-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Normalize M Competition Basemodels (Point Forecast) #53
Labels
Comments
I have added a todo list to keep track of the implementations. |
Code for:
from scipy.optimize import minimize_scalar
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.metrics import mean_squared_error
metric_dict = {
"mse": mean_squared_error,
"rmse": lambda y_true, y_pred, sample_weight=None: mean_squared_error(
y_true, y_pred, sample_weight=sample_weight, squared=False
),
}
class Naive(BaseEstimator, RegressorMixin):
def __init__(self, horizon=1):
self.horizon = horizon
def fit(self, X=None, y=None):
return self
def predict(self, X=None, y=None):
return y.shift(self.horizon)
def score(self, X, y, metric=None, sample_weight=None):
preds = self.predict(X, y)
if metric is None:
metric = mean_squared_error
if isinstance(metric, str):
metric = metric_dict[metric]
else:
assert callable(
metric
), "metric must be a callable with the signature metric(y_true, y_pred, sample_weight=None)"
y = y[preds.notna()]
preds = preds[preds.notna()]
return metric(y, preds, sample_weight=sample_weight)
class ExponentialSmoothing(BaseEstimator, RegressorMixin):
def __init__(self, alpha=None):
self.alpha = alpha
def fit(self, X=None, y=None, horizon=1):
if self.alpha:
return self
# Optimize alpha to minimize the RMSE
self.alpha = minimize_scalar(
lambda alpha: self.score(X, y, alpha=alpha, horizon=horizon),
bounds=(0, 1),
method="bounded",
).x
return self
def predict(self, X=None, y=None, alpha=None, horizon=1):
# Implement the exponential smoothing
alpha = alpha or self.alpha
if not alpha:
alpha = 0.2
return y.shift(horizon).ewm(alpha=alpha, adjust=False).mean()
def score(
self, X=None, y=None, metric=None, sample_weight=None, alpha=None, horizon=1
):
preds = self.predict(X, y, alpha, horizon)
if metric is None:
metric =lambda y_true, y_pred, sample_weight=None: mean_squared_error(
y_true, y_pred, sample_weight=sample_weight, squared=False
)
if isinstance(metric, str):
metric = metric_dict[metric]
else:
assert callable(
metric
), "metric must be a callable with the signature metric(y_true, y_pred, sample_weight=None)"
y = y[preds.notna()]
preds = preds[preds.notna()]
return metric(y, preds, sample_weight=sample_weight)
class SeasonalNaive(BaseEstimator, RegressorMixin):
def __init__(self, period=7):
self.period = period
def fit(self, X=None, y=None):
return self
def predict(self, X=None, y=None):
# Implement the seasonal naive using the period
return y.shift(self.period)
def score(self, X, y, metric=None, sample_weight=None):
preds = self.predict(X, y)
if metric is None:
metric = mean_squared_error
if isinstance(metric, str):
metric = metric_dict[metric]
else:
assert callable(
metric
), "metric must be a callable with the signature metric(y_true, y_pred, sample_weight=None)"
y = y[preds.notna()]
preds = preds[preds.notna()]
return metric(y, preds, sample_weight=sample_weight)
class MovingAverage(BaseEstimator, RegressorMixin):
def __init__(self, window_size=5):
self.window_size = window_size
def fit(self, X=None, y=None):
return self
def predict(self, X=None, y=None, horizon=1):
# Implement the moving average using the window size and the horizon
# Hint: use the pandas rolling function
return y.shift(horizon).rolling(self.window_size).mean()
def score(self, X, y, metric=None, sample_weight=None, horizon=1):
preds = self.predict(X, y, horizon)
if metric is None:
metric = mean_squared_error
if isinstance(metric, str):
metric = metric_dict[metric]
assert callable(
metric
), "metric must be a callable with the signature metric(y_true, y_pred, sample_weight=None)"
y = y[preds.notna()]
preds = preds[preds.notna()]
return metric(y, preds, sample_weight=sample_weight) |
Could we have this in a branch and a PR? |
Where should they be placed within the repo? @ggsdc |
Place it wherever you want, during the PR review we can move it. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following list are basemodels used by M-Competition and I think It is a good idea to normalize how they are implemented to be able to automate the generation of this model.
Base Models
Regular series
Intermitent series
where$z_t$ and $p_t$ are predicted using SES. In this case both SES models use $a=0.1$ . First observation of the components is used as initialization for the SES model
Both series
Example of implementation
Here is a snippet of code to be able to normalize with the Sklearn API (fit, predict,...)
TODO list of implementations
The text was updated successfully, but these errors were encountered: