Skip to content

Commit

Permalink
Merge pull request #775 from JoaquinAmatRodrigo/0.13.x
Browse files Browse the repository at this point in the history
0.13.x
  • Loading branch information
JoaquinAmatRodrigo authored Jul 31, 2024
2 parents d2c2794 + aaefa43 commit 6aeb5ce
Show file tree
Hide file tree
Showing 39 changed files with 1,543 additions and 614 deletions.
11 changes: 9 additions & 2 deletions dev/00_template.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{
"data": {
"text/plain": [
"'/home/ubuntu/varios/skforecast'"
"'c:\\\\Users\\\\jaesc2\\\\GitHub\\\\skforecast'"
]
},
"execution_count": 1,
Expand All @@ -24,6 +24,13 @@
"sys.path.insert(1, str(Path.cwd().parent))\n",
"str(Path.cwd().parent)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand All @@ -42,7 +49,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
"version": "3.11.5"
},
"orig_nbformat": 4,
"vscode": {
Expand Down
900 changes: 900 additions & 0 deletions dev/Example_Multiseries.ipynb

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3189,7 +3189,7 @@
" <b style=\"color: #ff9100;\"> <span style=\"color: #ff9100;\">&#9888;</span> Warning</b>\n",
"</p>\n",
"\n",
"Since the unknown series are encoded as NaN when the forecaster uses the <code>'ordinal_category'</code> or <code>'ordinal'</code> encoding, only forecasters that can handle missing values can be used, otherwise an error will be raised.\n",
"Since the unknown series are encoded as NaN when the forecaster uses the <code>'ordinal_category'</code> or <code>'ordinal'</code> encoding, only regressors that can handle missing values can be used, otherwise an error will be raised.\n",
"\n",
"</div>"
]
Expand Down Expand Up @@ -4558,7 +4558,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.12.4"
},
"toc": {
"base_numbering": 1,
Expand Down
118 changes: 59 additions & 59 deletions skforecast/ForecasterAutoreg/ForecasterAutoreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,13 @@ def __init__(
self,
regressor: object,
lags: Union[int, np.ndarray, list],
transformer_y: Optional[object]=None,
transformer_exog: Optional[object]=None,
weight_func: Optional[Callable]=None,
differentiation: Optional[int]=None,
fit_kwargs: Optional[dict]=None,
binner_kwargs: Optional[dict]=None,
forecaster_id: Optional[Union[str, int]]=None
transformer_y: Optional[object] = None,
transformer_exog: Optional[object] = None,
weight_func: Optional[Callable] = None,
differentiation: Optional[int] = None,
fit_kwargs: Optional[dict] = None,
binner_kwargs: Optional[dict] = None,
forecaster_id: Optional[Union[str, int]] = None
) -> None:

self.regressor = regressor
Expand Down Expand Up @@ -297,7 +297,7 @@ def __repr__(

if isinstance(self.regressor, Pipeline):
name_pipe_steps = tuple(name + "__" for name in self.regressor.named_steps.keys())
params = {key : value for key, value in self.regressor.get_params().items() \
params = {key: value for key, value in self.regressor.get_params().items()
if key.startswith(name_pipe_steps)}
else:
params = self.regressor.get_params(deep=True)
Expand Down Expand Up @@ -379,7 +379,7 @@ def _create_lags(
def create_train_X_y(
self,
y: pd.Series,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None
exog: Optional[Union[pd.Series, pd.DataFrame]] = None
) -> Tuple[pd.DataFrame, pd.Series]:
"""
Create training matrices from univariate time series and exogenous
Expand Down Expand Up @@ -453,7 +453,7 @@ def create_train_X_y(
X_train = pd.DataFrame(
data = X_train,
columns = X_train_col_names,
index = y_index[self.max_lag: ]
index = y_index[self.max_lag:]
)

if exog is not None:
Expand All @@ -470,21 +470,21 @@ def create_train_X_y(
# TODO: DataFrame or Series?
y_train = pd.Series(
data = y_train,
index = y_index[self.max_lag: ],
index = y_index[self.max_lag:],
name = 'y'
)

if self.differentiation is not None:
X_train = X_train.iloc[self.differentiation: ]
y_train = y_train.iloc[self.differentiation: ]
X_train = X_train.iloc[self.differentiation:]
y_train = y_train.iloc[self.differentiation:]

return X_train, y_train


def create_sample_weights(
self,
X_train: pd.DataFrame,
)-> np.ndarray:
) -> np.ndarray:
"""
Crate weights for each observation according to the forecaster's attribute
`weight_func`.
Expand Down Expand Up @@ -527,9 +527,9 @@ def create_sample_weights(
def fit(
self,
y: pd.Series,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None,
store_last_window: bool=True,
store_in_sample_residuals: bool=True
exog: Optional[Union[pd.Series, pd.DataFrame]] = None,
store_last_window: bool = True,
store_in_sample_residuals: bool = True
) -> None:
"""
Training Forecaster.
Expand Down Expand Up @@ -624,7 +624,7 @@ def _binning_in_sample_residuals(
self,
y_true: pd.Series,
y_pred: pd.Series,
random_state: int=95123
random_state: int = 95123
) -> None:
"""
Binning residuals according to the predicted value each residual is
Expand Down Expand Up @@ -693,8 +693,8 @@ def _binning_in_sample_residuals(
def _create_predict_inputs(
self,
steps: int,
last_window: Optional[Union[pd.Series, pd.DataFrame]]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None
last_window: Optional[Union[pd.Series, pd.DataFrame]] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None
) -> Tuple[np.ndarray, np.ndarray, pd.Index]:
"""
Create inputs needed for the first iteration of the prediction process.
Expand Down Expand Up @@ -784,7 +784,7 @@ def _recursive_predict(
self,
steps: int,
last_window: np.ndarray,
exog: Optional[np.ndarray]=None
exog: Optional[np.ndarray] = None
) -> np.ndarray:
"""
Predict n steps ahead. It is an iterative process in which, each prediction,
Expand Down Expand Up @@ -833,8 +833,8 @@ def _recursive_predict(
def create_predict_X(
self,
steps: int,
last_window: Optional[Union[pd.Series, pd.DataFrame]]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None
last_window: Optional[Union[pd.Series, pd.DataFrame]] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None
) -> pd.DataFrame:
"""
Create the predictors needed to predict `steps` ahead. As it is a recursive
Expand Down Expand Up @@ -890,8 +890,8 @@ def create_predict_X(
def predict(
self,
steps: int,
last_window: Optional[Union[pd.Series, pd.DataFrame]]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None
last_window: Optional[Union[pd.Series, pd.DataFrame]] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None
) -> pd.Series:
"""
Predict n steps ahead. It is an recursive process in which, each prediction,
Expand Down Expand Up @@ -952,12 +952,12 @@ def predict(
def predict_bootstrapping(
self,
steps: int,
last_window: Optional[pd.Series]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None,
n_boot: int=250,
random_state: int=123,
in_sample_residuals: bool=True,
binned_residuals: bool=False,
last_window: Optional[pd.Series] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None,
n_boot: int = 250,
random_state: int = 123,
in_sample_residuals: bool = True,
binned_residuals: bool = False,
) -> pd.DataFrame:
"""
Generate multiple forecasting predictions using a bootstrapping process.
Expand Down Expand Up @@ -1110,13 +1110,13 @@ def predict_bootstrapping(
def predict_interval(
self,
steps: int,
last_window: Optional[pd.Series]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None,
interval: list=[5, 95],
n_boot: int=250,
random_state: int=123,
in_sample_residuals: bool=True,
binned_residuals: bool=False
last_window: Optional[pd.Series] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None,
interval: list = [5, 95],
n_boot: int = 250,
random_state: int = 123,
in_sample_residuals: bool = True,
binned_residuals: bool = False
) -> pd.DataFrame:
"""
Iterative process in which each prediction is used as a predictor
Expand Down Expand Up @@ -1194,7 +1194,7 @@ def predict_interval(
binned_residuals = binned_residuals
)

interval = np.array(interval)/100
interval = np.array(interval) / 100
predictions_interval = boot_predictions.quantile(q=interval, axis=1).transpose()
predictions_interval.columns = ['lower_bound', 'upper_bound']
predictions = pd.concat((predictions, predictions_interval), axis=1)
Expand All @@ -1205,13 +1205,13 @@ def predict_interval(
def predict_quantiles(
self,
steps: int,
last_window: Optional[pd.Series]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None,
quantiles: list=[0.05, 0.5, 0.95],
n_boot: int=250,
random_state: int=123,
in_sample_residuals: bool=True,
binned_residuals: bool=False
last_window: Optional[pd.Series] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None,
quantiles: list = [0.05, 0.5, 0.95],
n_boot: int = 250,
random_state: int = 123,
in_sample_residuals: bool = True,
binned_residuals: bool = False
) -> pd.DataFrame:
"""
Calculate the specified quantiles for each step. After generating
Expand Down Expand Up @@ -1289,12 +1289,12 @@ def predict_dist(
self,
steps: int,
distribution: object,
last_window: Optional[pd.Series]=None,
exog: Optional[Union[pd.Series, pd.DataFrame]]=None,
n_boot: int=250,
random_state: int=123,
in_sample_residuals: bool=True,
binned_residuals: bool=False
last_window: Optional[pd.Series] = None,
exog: Optional[Union[pd.Series, pd.DataFrame]] = None,
n_boot: int = 250,
random_state: int = 123,
in_sample_residuals: bool = True,
binned_residuals: bool = False
) -> pd.DataFrame:
"""
Fit a given probability distribution for each step. After generating
Expand Down Expand Up @@ -1352,7 +1352,7 @@ def predict_dist(
)

param_names = [p for p in inspect.signature(distribution._pdf).parameters
if not p=='x'] + ["loc","scale"]
if not p == 'x'] + ["loc", "scale"]
param_values = np.apply_along_axis(
lambda x: distribution.fit(x),
axis = 1,
Expand Down Expand Up @@ -1446,11 +1446,11 @@ def set_lags(
def set_out_sample_residuals(
self,
residuals: Union[pd.Series, np.ndarray],
y_pred: Optional[Union[pd.Series, np.ndarray]]=None,
append: bool=True,
transform: bool=True,
random_state: int=123
)-> None:
y_pred: Optional[Union[pd.Series, np.ndarray]] = None,
append: bool = True,
transform: bool = True,
random_state: int = 123
) -> None:
"""
Set new values to the attribute `out_sample_residuals`. Out of sample
residuals are meant to be calculated using observations that did not
Expand Down Expand Up @@ -1642,7 +1642,7 @@ def set_out_sample_residuals(

def get_feature_importances(
self,
sort_importance: bool=True
sort_importance: bool = True
) -> pd.DataFrame:
"""
Return feature importances of the regressor stored in the forecaster.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def test_binning_in_sample_residuals_stores_maximum_200_residuals_per_bin():

y = pd.Series(
data = np.random.normal(loc=10, scale=1, size=1000),
index = pd.date_range(start='01-01-2000', periods=1000, freq='H')
index = pd.date_range(start='01-01-2000', periods=1000, freq='h')

)
forecaster = ForecasterAutoreg(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# ==============================================================================
import re
import pytest
from pytest import approx
import numpy as np
import pandas as pd
from skforecast.ForecasterAutoreg import ForecasterAutoreg
Expand Down
Loading

0 comments on commit 6aeb5ce

Please sign in to comment.