Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions neuralforecast/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,26 +480,58 @@ def cross_validation(
fcsts_df = fcsts_df.merge(df, how="left", on=["unique_id", "ds"])
return fcsts_df

def predict_insample(self, step_size: int = 1):
def predict_insample(
self,
df: Optional[pd.DataFrame] = None,
static_df: Optional[pd.DataFrame] = None,
step_size: int = 1,
test_size: Optional[int] = None,
sort_df: bool = True,
verbose: bool = False,
):
"""Predict insample with core.NeuralForecast.

`core.NeuralForecast`'s `predict_insample` uses stored fitted `models`
to predict historic values of a time series from the stored dataframe.

Parameters
----------
df : pandas.DataFrame, optional (default=None)
DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.
If None, a previously stored dataset is required.
static_df : pandas.DataFrame, optional (default=None)
DataFrame with columns [`unique_id`] and static exogenous.
step_size : int (default=1)
Step size between each window.
sort_df : bool (default=True)
Sort `df` before fitting.
verbose : bool (default=False)
Print processing steps.

Returns
-------
fcsts_df : pandas.DataFrame
DataFrame with insample predictions for all fitted `models`.
"""

if (df is None) and not (hasattr(self, 'dataset')):
raise Exception('You must pass a DataFrame or have one stored.')

if not self._fitted:
raise Exception(
"The models must be fitted first with `fit` or `cross_validation`."
)
# Process new dataset but does not store it.
if df is not None:
dataset, uids, last_dates, ds = self._prepare_fit(df=df,
static_df=static_df, sort_df=sort_df)
else:
dataset = self.dataset
uids = self.uids
last_dates = self.last_dates
ds = self.ds
if verbose:
print('Using stored dataset.')

for model in self.models:
if model.SAMPLING_TYPE == "recurrent":
Expand All @@ -525,19 +557,19 @@ def predict_insample(self, step_size: int = 1):
test_size = self.models_fitted[0].get_test_size()
if test_size > 0:
trimmed_dataset = TimeSeriesDataset.trim_dataset(
dataset=self.dataset, right_trim=test_size, left_trim=0
dataset=dataset, right_trim=test_size, left_trim=0
)
last_dates_train = self.last_dates.shift(-test_size, freq=self.freq)
last_dates_train = last_dates.shift(-test_size, freq=self.freq)
else:
trimmed_dataset = self.dataset
last_dates_train = self.last_dates
trimmed_dataset = dataset
last_dates_train = last_dates

# Generate dates
len_series = np.diff(
trimmed_dataset.indptr
) # Computes the length of each time series based on indptr
fcsts_df = _insample_dates(
uids=self.uids,
uids=uids,
last_dates=last_dates_train,
freq=self.freq,
h=self.h,
Expand Down Expand Up @@ -567,7 +599,7 @@ def predict_insample(self, step_size: int = 1):

# Add original input df's y to forecasts DataFrame
Y_df = pd.DataFrame.from_records(
self.dataset.temporal[:, [0]].numpy(), columns=["y"], index=self.ds
dataset.temporal[:, [0]].numpy(), columns=["y"], index=ds
)
Y_df = Y_df.reset_index(drop=False)
fcsts_df = fcsts_df.merge(Y_df, how="left", on=["unique_id", "ds"])
Expand Down