技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
time-series【数据与研究】Decomposes and forecasts time-indexed data with STL, ARIMA/SARIMA, and Prophet, validated by time-ordered backtests against a seasonal-naive baseline. Use when someone asks "forecast next quarter's demand", "is this series seasonal", "why is my ARIMA forecast flat", "how do I backtest a forecast", or has any metric indexed by time that needs predicti…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Time series work fails in two characteristic ways: validating on a random split (which leaks the future into training and produces accuracy numbers that evaporate in production), and shipping a model that never had to beat the dumbest possible baseline. The discipline below exists to prevent both - every forecast is backtested in time order and compared against seasonal-naive before anyone sees it.
Order matters: exploration decides the seasonal period, the period decides the decomposition and model structure, and validation only means something after the model choices are frozen.
series.asfreq("D")); missing timestamps must become explicit NaNs, then be imputed or modeled, never silently skipped.from statsmodels.tsa.seasonal import STL
result = STL(series, period=12).fit()
result.plot()
Read the components: if the seasonal panel's amplitude dwarfs the residual panel, seasonality is real; if the residual still shows structure, the period is wrong or a second cycle exists.
from statsmodels.tsa.stattools import adfuller
stat, pvalue, *_ = adfuller(series.dropna())
p < 0.05 rejects the unit root - treat the series as stationary. Otherwise difference.
Difference once for trend, seasonally difference for seasonality:
diff = series.diff().dropna()
seasonal_diff = series.diff(12).dropna()
Almost never difference more than twice total (d + D ≤ 2); over-differencing injects noise and shows up as a strongly negative lag-1 ACF. Read ACF/PACF on the differenced series to choose orders: PACF cutting off after lag p suggests AR(p); ACF cutting off after lag q suggests MA(q).
SARIMA:
from statsmodels.tsa.statespace.sarimax import SARIMAX
model = SARIMAX(series, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12))
fit = model.fit(disp=False)
forecast = fit.get_forecast(steps=12)
ci = forecast.conf_int()
pmdarima.auto_arima can search orders by AIC, but treat its winner as a candidate, not an answer - verify residuals (Step 6) before trusting it.
Prophet, for business series with strong multiple seasonality and holiday effects:
from prophet import Prophet
m = Prophet(yearly_seasonality=True, weekly_seasonality=True)
m.add_country_holidays(country_name="US")
m.fit(df) # columns: ds, y
fc = m.predict(m.make_future_dataframe(periods=90))
Apply a log transform first when seasonal amplitude scales with the level (multiplicative seasonality), for either model family.
Backtest with rolling or expanding windows that respect time:
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
Report MAPE, MAE, and RMSE on held-out future windows only - in-sample fit is not evidence. Always fit the seasonal-naive baseline (predict the value from one season ago) through the same backtest. The acceptance threshold: the model's error must beat seasonal-naive (MASE < 1, or lower MAPE on the same folds). A sophisticated model that loses to naive ships the naive.
Residuals from a correct model are white noise:
Always show the confidence interval, and say plainly that uncertainty grows with horizon. Report the backtest error at the actual decision horizon (the 6-month-ahead MAPE for a 6-month decision), not the flattering 1-step-ahead number.
Monthly revenue, 36 points, clear December spike, variance growing with level. Decision trail: period = 12 (monthly with annual cycle, 3 full cycles available - enough). Log transform (multiplicative seasonality). ADF on log series p = 0.41 → difference; on differenced series p = 0.01 → proceed with d = 1, D = 1. ACF/PACF suggest (1,1,1)(0,1,1,12). Backtest on 5 expanding folds at horizon 6: SARIMA MAPE 7.2% vs seasonal-naive 11.8% - model earns its keep, ship with intervals from the log-scale fit back-transformed.
Produce a forecast package containing: the decomposition plot with a one-line reading, the stationarity and transform decisions with test p-values, the chosen model and orders with the rejected candidates named, backtest error (MAPE/MAE/RMSE) at the decision horizon side-by-side with seasonal-naive, residual diagnostics (Ljung-Box p-value, residual ACF), and the forecast with confidence intervals.
Ship only when: the seasonal period is verified by decomposition, not assumed; all accuracy numbers come from time-ordered held-out windows at the decision horizon; the model beats seasonal-naive; Ljung-Box shows no residual autocorrelation; intervals accompany every point forecast; and every data gap, transform, and intervention is documented.