skforecast/skforecast-ai/feature-engineering

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Creates features for time series forecasting: calendar features with skforecast's `CalendarFeatures` (cyclical, onehot, or spline encoding) — either delegated to the forecaster via the `calendar_features` parameter or built manually as exog — holiday distance features with `calculate_distance_from_holiday`, rolling statistics with `RollingFeatures`, differencing, and categorical exogenous variables. Use when the user wants to improve model accuracy through feature engineering or asks about exogenous variable creation.

Install

npx vskill@latest install skforecast/skforecast-ai/feature-engineering

SKILL.md

The same SKILL.md was published earlier as skforecast/skforecast/feature-engineering.

Feature Engineering

When to Use

Use this skill when the user wants to create features to improve forecasting accuracy: calendar/datetime features, cyclical / onehot / spline encoding, holiday distance features, rolling statistics, differencing, or data scaling.

Related skills
  • Prerequisite: autocorrelation-and-lag-selection (use ACF/PACF to choose a candidate set of lags before adding rolling and calendar features)
  • Next: feature-selection (prune redundant features with select_features after engineering)
  • Next: hyperparameter-optimization (jointly tune the engineered configuration and the estimator hyperparameters)

Stop Conditions

Scan before writing code. Each row lists a rule, the symptom when it is broken, and the recovery. Full pitfall catalog: the troubleshooting-common-errors skill.

RuleSymptomRecovery
Do not mix the delegated (calendar_features=) and manual (CalendarFeatures as exog) paths for the same featuresValueError on duplicate feature namesChoose one path per feature set
Manual calendar / holiday exog must cover the full forecast horizonpredict() exog error or truncated forecastGenerate exog for all future dates before predicting
Cyclical calendar features need sin/cos (or spline) encodingHour 23 treated as far from hour 0, degrading the modelUse encoding='cyclical' (or spline) for periodic features
window_features are computed on the differenced series when differentiation is setroll_mean_7 is a mean of changes, not of raw valuesAccount for differencing when interpreting or scaling window features

Overview

ToolModulePurpose
calendar_features paramskforecast ML forecastersDelegated calendar features: pass a CalendarFeatures instance and the forecaster generates them at train and predict — no manual exog.
CalendarFeaturesskforecast.preprocessingSklearn-compatible transformer: extract calendar features from a DatetimeIndex and (optionally) encode them. Pass to calendar_features, use as transformer_exog, or in a Pipeline.
create_calendar_featuresskforecast.preprocessingFunction form of the same logic, for one-shot use without a transformer.
calculate_distance_from_holidayskforecast.preprocessingPeriods to next / since last holiday
RollingFeaturesskforecast.preprocessingRolling window statistics (mean, std, min, max, etc.)
differentiation paramskforecast forecastersMake non-stationary series stationary

Calendar Features

There are two ways to add calendar features (month, day of week, hour, …). Both use the CalendarFeatures class; they differ in who builds the features.

WorkflowHowWhen to use
DelegatedPass a CalendarFeatures instance to the forecaster's calendar_features parameter. The forecaster generates the features at train and predict — no manual exog.The 4 supported forecasters: ForecasterRecursive, ForecasterRecursiveMultiSeries, ForecasterDirect, ForecasterDirectMultiVariate.
ManualBuild features with CalendarFeatures.fit_transform / create_calendar_features and pass them as exog (or wire CalendarFeatures as transformer_exog on forecasters that have it).Forecasters without calendar_features support (ForecasterRecursiveClassifier, ForecasterRnn, ForecasterStats, and ForecasterFoundation with an exog-capable model, which has no transformer_exog), or when the features live inside a Pipeline / ColumnTransformer.
Full constructor, all features/encodings, per-forecaster support, and gotchas:

Supported features: 'year', 'month', 'week', 'day_of_week', 'day_of_month', 'day_of_year', 'weekend', 'hour', 'minute', 'second', 'quarter'. Encodings: 'cyclical' (default, sin/cos pair), 'onehot', 'spline', None. 'year' and 'weekend' are never encoded.

Delegated — calendar_features parameter (preferred when supported)

The forecaster builds the calendar features from the datetime index during both training and prediction. You do not build or pass a calendar exog, and you do not need to cover the forecast horizon manually.

python
from lightgbm import LGBMRegressor
from skforecast.preprocessing import CalendarFeatures
from skforecast.recursive import ForecasterRecursive
calendar = CalendarFeatures(
features=['month', 'day_of_week', 'hour'],
encoding='cyclical', # 'cyclical' | 'onehot' | 'spline' | None
keep_original_columns=False,
)
forecaster = ForecasterRecursive(
estimator=LGBMRegressor(),
lags=24,
calendar_features=calendar, # requires a pandas DatetimeIndex
)
forecaster.fit(y=y_train) # calendar features built automatically
predictions = forecaster.predict(steps=24) # calendar features built automatically

Requires a DatetimeIndex (otherwise TypeError). Calendar features are added as predictors alongside lags, window features, and any exog.

Manual — build calendar features as exog

For forecasters without the calendar_features parameter, or for use in a Pipeline:

python
import pandas as pd
from skforecast.preprocessing import CalendarFeatures
data = data.asfreq('h') # DatetimeIndex with frequency set
calendar_transformer = CalendarFeatures(
features=['month', 'week', 'day_of_week', 'hour'],
encoding='cyclical',
keep_original_columns=False,
)
exog_calendar = calendar_transformer.fit_transform(data)
# Columns: month_sin, month_cos, week_sin, week_cos, ...
# The exog passed to predict() must cover the entire forecast horizon.

The function form create_calendar_features(X=data, ...) does the same in one shot without a transformer. See the reference for max_values, spline_kwargs, and features_to_encode options.

Holiday Distance Features

calculate_distance_from_holiday computes the number of periods to the next and since the last holiday. The time unit is inferred from the index frequency (days, hours, minutes, …) when date_column=None, and is always days when a date column is used.

python
from skforecast.preprocessing import calculate_distance_from_holiday
# Index-based (preferred): unit follows the index frequency
holiday_dist = calculate_distance_from_holiday(
X=data[['is_holiday']], # boolean / 0-1 column
holiday_column='is_holiday',
fill_na=0, # value for rows before first / after last holiday
)
# Columns: time_to_holiday, time_since_holiday
# Series form: values used directly as the holiday indicator
holiday_dist = calculate_distance_from_holiday(
X=data['is_holiday'],
fill_na=0,
)

Combine with calendar features into a single exog:

python
exog = pd.concat([exog_calendar, holiday_dist], axis=1)

Rolling Features (Window Statistics)

python
from skforecast.preprocessing import RollingFeatures
from skforecast.recursive import ForecasterRecursive
from lightgbm import LGBMRegressor
# Single window size for all stats
rolling = RollingFeatures(
stats=['mean', 'std', 'min', 'max'],
window_sizes=7, # int applies same window to all stats
)
# Different window sizes per statistic
rolling = RollingFeatures(
stats=['mean', 'std', 'min', 'max'],
window_sizes=[7, 7, 14, 14], # Must match length of stats
)
# Multiple RollingFeatures objects
rolling_short = RollingFeatures(stats=['mean', 'std'], window_sizes=7)
rolling_long = RollingFeatures(stats=['mean', 'std'], window_sizes=30)
forecaster = ForecasterRecursive(
estimator=LGBMRegressor(),
lags=24,
window_features=[rolling_short, rolling_long], # List of RollingFeatures
)
Available Rolling Statistics

Standard: 'mean', 'std', 'min', 'max', 'sum', 'median', 'ratio_min_max', 'coef_variation'

Exponential weighted: 'ewm' — requires kwargs_stats:

python
rolling = RollingFeatures(
stats=['ewm'],
window_sizes=7,
kwargs_stats={'ewm': {'alpha': 0.3}},
)
The window_features parameter

The forecaster's window_features argument accepts any object (or list of objects) that implements the contract:

python
def transform_batch(y: pd.Series) -> pd.DataFrame:
# Returns one row per training sample, indexed to align with y[max_window_size:]
...

RollingFeatures is the built-in implementation; user-defined classes that follow the same contract are accepted. See references/rolling-stats-reference.md for the full protocol and a custom-class example.

Effective `window_size`. The forecaster sets window_size = max(max_lag, max_size_window_features) (+ differentiation). A RollingFeatures(window_sizes=30) combined with lags=7 raises window_size to 30 — last_window must hold ≥ 30 values and the first 30 rows of training data are dropped. This is a frequent source of "not enough data to train" errors when the rolling window is much larger than the lags.

Lags-free configuration. lags=None, window_features=... is valid (and useful for purely smoothed-history models). At least one of lags / window_features must be non-None — passing both as None raises ValueError.

Multiple `RollingFeatures` instances. When passing a list, each instance is processed independently and their feature names are concatenated. Names must be unique across instances; collisions silently overwrite columns. Use the features_names= argument of RollingFeatures to disambiguate when reusing the same stat/window_size combination.

Runtime mutation. After construction, use forecaster.set_window_features(new_window_features) to swap the configuration (analogous to set_lags). This recomputes window_size, max_size_window_features, window_features_names, and the differentiator's window. Useful inside manual hyperparameter loops.

Interaction with `differentiation`. Window features are computed on the differenced series, not the original one. With differentiation=1, roll_mean_7 is the mean of seven consecutive changes, not seven raw values. Take this into account when interpreting feature importances.

Multi-series. In ForecasterRecursiveMultiSeries, the same RollingFeatures instance is applied independently to each series — configuration is global but the computed values are per-series (no leakage between series).

Classifier variant. For ForecasterRecursiveClassifier, use RollingFeaturesClassification (also in skforecast.preprocessing) instead of RollingFeatures.

Choosing window features

When window features help:

  • Noisy series — a smoothed signal (mean, ewm) reduces variance the lags cannot.
  • Capturing a longer scale than the lags without exploding column count: with hourly data and lags=24, a roll_mean_168 represents the weekly level with one feature instead of adding 144 more lags.
  • Heteroscedastic or regime-changing series (energy, finance, traffic) — roll_std, coef_variation.
  • When extreme behaviour drives decisions (peak demand, drawdowns) — roll_min, roll_max.

When they don't help:

  • Short series — each large window discards training rows (window_size grows).
  • Highly periodic, low-noise series — lags + calendar features are usually enough.
  • Redundant ranges — a roll_mean_24 alongside lags=range(1, 25) adds little for a gradient boosting model that can already construct the average from splits.

Which statistic for which signal:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
50
Repository forks
6
7-day trend score
20

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/skforecast/skforecast-ai/feature-engineering/badge)](https://verified-skill.com/skills/skforecast/skforecast-ai/feature-engineering)

Something wrong with this skill or its page? Tell us.