Feature engineering¶
The spatio-temporal series is a panel: one time series per place. Feature
classes in predspot.feature_engineering
turn each of those series into lagged predictors.
Feature classes¶
Every class takes lags (how many previous periods become columns) and an
optional tfreq (inferred from the series when omitted):
| Class | Transformation before lagging | Columns |
|---|---|---|
AR |
none (raw values) | ar_1 … ar_k |
Diff |
first difference | diff_1 … diff_k |
Seasonality |
seasonal component of an STL decomposition with period lags |
seasonal_1 … seasonal_k |
Trend |
trend component of the same STL decomposition | trend_1 … trend_k |
ar_1 at period t is the value at t-1, ar_2 the value at t-2, and so
on. For Seasonality and Trend, lags doubles as the STL period: use 12
for monthly data with a yearly cycle, 7 for daily data with a weekly cycle,
52 for weekly data, and make sure the series is at least twice as long.
from predspot.feature_engineering import AR, Seasonality
X = AR(lags=3).fit_transform(stseries)
X.head()
Note the index: features at t only use values before t, and the
matrix always includes one extra period after the last observed one — the
row a fitted model uses to forecast.
Combining features¶
PandasFeatureUnion runs several
feature transformers and concatenates their columns, aligning on the
(t, places) index and dropping rows that any transformer could not fill
(warm-up periods):
from predspot import PandasFeatureUnion
from predspot.feature_engineering import Seasonality, Trend, Diff
fextraction = PandasFeatureUnion([
("seasonal", Seasonality(lags=12)),
("trend", Trend(lags=12)),
("diff", Diff(lags=12)),
])
X = fextraction.fit_transform(stseries)
Scaling and selection inside the estimator¶
Because features are a DataFrame, plain scikit-learn transformers would drop
the index. FeatureScaling
and FeatureSelection wrap any
scaler / selector so that DataFrames come out the other side, and
Model does the same for the regressor:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import QuantileTransformer
from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestRegressor
from predspot.feature_engineering import FeatureScaling
from predspot.ml_modelling import FeatureSelection, Model
estimator = Pipeline([
("scaling", FeatureScaling(QuantileTransformer(n_quantiles=10))),
("selection", FeatureSelection(RFE(RandomForestRegressor(n_estimators=20)))),
("model", Model(RandomForestRegressor(n_estimators=100))),
])
Writing your own feature¶
Subclass TimeSeriesFeatures,
set label and implement apply_ts_decomposition(ts), which receives the
series of one place and returns the series to lag: