Posts文章
Modelling模型建構31 May 2026 · 20 min read2026年5月31日 · 閱讀約 34 分鐘

Demand Forecasting with Statistical Models: How Far Can Demand History Alone Take Us?僅憑歷史需求,我們能預測到多準?

A practical and theoretical guide to forecasting iPhone demand with Holt–Winters and SARIMA—from backtesting and model selection to point forecasts.一份結合理論與實作的 iPhone 需求預測指南,使用 Holt–Winters 與 SARIMA——涵蓋回測、模型選擇到點預測。

Demand Forecasting with Statistical Models: How Far Can Demand History Alone Take Us?

This is the statistical deep dive behind Forecasting iPhone 17 Pro Demand: From Statistics to Deep Learning. The broader article compares three generations of forecasting models. Here, we slow down and ask a narrower question:

How much of tomorrow's demand can we forecast from demand history alone?

The answer establishes a baseline that every more complex model must beat.

This article is structured as follows:

  1. The decision behind the forecast
  2. One series, several behaviours
  3. Forward-walking backtesting
  4. Traditional statistical time-series forecasting
  5. How do we choose parameters?
  6. Evaluation metrics and model selection
  7. From point forecast to a 95% prediction interval
  8. Recommendation for inventory decision

The decision behind the forecast

Every evening, the inventory team in a synthetic London Central Apple Store scenario must decide how many units of one configuration—iPhone 17 Pro 256GB Light—should be available the following day.

Forecast too low and the store risks stockouts, lost sales, and disappointed customers. Forecast too high and expensive devices occupy working capital and storage capacity. At one store, the difference may look modest. Across many stores and configurations, small daily errors accumulate into a material inventory decision.

The modelling target is therefore:

yt+1=units demanded tomorrowy_{t+1}=\text{units demanded tomorrow}

and the operational question is:

How many units should be positioned before tomorrow begins?

A demand forecast does not automatically tell us how many phones to stock. That decision also depends on the cost of having too few phones compared with the cost of having too many. If stockouts are more expensive, the planner should choose a higher point in the forecast distribution. If excess inventory is more expensive, the planner should choose a lower point. The newsvendor model expresses this choice as:

q=F1(CuCu+Co)q^*=F^{-1}\left(\frac{C_u}{C_u+C_o}\right)

Here, CuC_u is the cost of understocking, CoC_o is the cost of overstocking, F1F^{-1} selects the corresponding quantile from the forecast demand distribution, and qq^* is the recommended inventory quantity. Because these costs are not available in this experiment, we cannot calculate an optimal inventory quantile. We therefore report the point forecast and 95% prediction interval as forecasting outputs, leaving the service-level decision to the business.

One series, several behaviours

The synthetic dataset contains 730 simulated daily observations from 19 September 2025 to 18 September 2027. Mean demand is 39.5 units per day. The model receives only the date and historical unit demand for this store-SKU combination.

Daily demand and seven-day rolling mean for the focal iPhone configuration

Daily observations are shown in grey; the seven-day rolling mean exposes the slower movement in demand.

The chart contains several distinct forms of temporal structure:

  • Lifecycle: demand begins high after launch and declines toward a more mature level.
  • Weekly seasonality: the day of the week changes the expected demand.
  • Calendar effects: Christmas creates sharp local peaks, while closure days can produce genuine zero demand.
  • Level changes: the local baseline rises and falls rather than remaining constant across two years.
  • Irregular shocks: promotions and other commercial events produce spikes that are not explained by trend or weekday alone.

This is a univariate forecasting problem: the history of yty_t is the entire information set. Price, promotions, marketing, holidays, weather, and competitor activity are deliberately withheld. Their effects appear only after they reach the series as unexplained demand shocks.

That constraint is useful. Before giving a machine-learning model more features, we first want to know what the demand series can explain by itself.

Forward-walking backtesting

A random train-test split would leak future market conditions into the past. Instead, the observations are divided chronologically:

WindowObservationsDatesPurpose
Training61819 Sep 2025–29 May 2027Fit candidate models
Validation5630 May–24 Jul 2027Select one specification per family
Test5625 Jul–18 Sep 2027Estimate final performance once

Chronological training, validation, and test windows

The evaluation then reproduces the nightly workflow:

  1. Fit the model using every observation available at the end of day tt.
  2. Forecast demand for day t+1t+1.
  3. Reveal the actual demand for t+1t+1.
  4. Add that observation to the available history.
  5. Move forward one day and repeat.

This is variously called walk-forward validation, rolling-origin evaluation, or time-series backtesting. The forecast horizon remains one day, while the forecast origin advances through the validation and test windows.

At each step, the models use only observations available at that point in time. Candidate specifications are selected on the validation window and then locked before evaluation on the test window. This prevents the test data from influencing model design and keeps the reported performance realistic.

Traditional statistical time-series forecasting

Both Holt–Winters and ARIMA assume that the series' own history contains useful information about its future. They differ in what they believe that information looks like.

Holt–Winters: forecast the evolving components

Holt–Winters belongs to the exponential-smoothing family. It represents a time series through interpretable states:

demand=level+trend+seasonality+noise\text{demand}=\text{level}+\text{trend}+\text{seasonality}+\text{noise}

For an additive model with seasonal period mm, the state updates are

t=α(ytstm)+(1α)(t1+bt1)bt=β(tt1)+(1β)bt1st=γ(ytt)+(1γ)stm\begin{aligned} \ell_t &= \alpha(y_t-s_{t-m}) +(1-\alpha)(\ell_{t-1}+b_{t-1}) \\ b_t &= \beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1} \\ s_t &= \gamma(y_t-\ell_t)+(1-\gamma)s_{t-m} \end{aligned}

and the hh-step-ahead forecast is

y^t+h=t+hbt+st+hm\hat y_{t+h}=\ell_t+h b_t+s_{t+h-m}

Each state has a business interpretation:

  • Level t\ell_t: the current baseline after removing seasonal effects.
  • Trend btb_t: the estimated daily change in that baseline.
  • Seasonal state sts_t: the recurring effect for a position in the cycle; with m=7m=7, the model maintains a weekday pattern.

Suppose it is Thursday evening and the model is forecasting demand for Saturday, two days ahead. It currently estimates:

  • baseline demand: 35 units;
  • trend: −0.2 units per day;
  • Saturday seasonal effect: +8 units.

The forecast is:

y^t+2=35+2(0.2)+8=42.6\hat y_{t+2}=35+2(-0.2)+8=42.6

The model therefore forecasts approximately 43 units.

When Saturday's actual demand becomes available, Holt–Winters updates all three estimates. The level parameter α\alpha determines how strongly the baseline reacts, β\beta controls how quickly the trend changes, and γ\gamma determines how much of the difference is treated as a change in the Saturday effect.

The smoothing parameters α\alpha, β\beta, and γ\gamma lie between zero and one. A high value reacts strongly to new observations; a low value preserves more of the previous state. In other words, recent observations matter most, but older observations fade gradually rather than disappearing at a fixed cutoff.

Holt–Winters works best when observations are equally spaced, the seasonal period is known and stable, level and trend evolve gradually, and unusual events do not dominate the series. Additive seasonality assumes a weekday effect of roughly constant magnitude. Multiplicative seasonality is excluded because the series contains genuine zero-demand closure days, while the implementation used here requires strictly positive observations.

We validate three weekly additive candidates:

  • level plus seasonality;
  • level, additive trend, and seasonality;
  • level, damped trend, and seasonality.

The component specification is selected on the validation window; within each specification, the smoothing coefficients are estimated numerically from the training history rather than chosen by hand.

Holt–Winters candidateValidation MAEValidation WAPEBias
Additive trend + weekly9.3428.51%−2.07%
Level + weekly9.3628.57%−1.16%
Damped trend + weekly9.4028.67%−1.18%

The candidates are close, but additive trend has the lowest validation WAPE and is locked as the family winner.

A damped trend replaces the indefinitely extrapolated hbth b_t term with a trend whose incremental effect decays over the horizon. This often prevents implausible long-range extrapolation, although it is less consequential for a one-day forecast.

ARIMA: model changes, persistence, and surprises

Holt–Winters describes demand through level, trend, and seasonality. ARIMA approaches the same problem differently. It asks:

After making the series sufficiently stable, how does current demand depend on previous values and previous forecasting errors?

The process can be understood as:

Original demand
      ↓ differencing
Approximately stationary series
      ↓ AR and MA modelling
Forecast temporal dependence
      ↓ reverse differencing
Forecast demand in its original units

ARIMA stands for AutoRegressive Integrated Moving Average. Its notation is ARIMA(p,d,q)\mathrm{ARIMA}(p,d,q), where each parameter represents a different source of information.

Integrated (I): model the change instead of the level

ARIMA generally works best when the series it models is approximately stationary. Its mean, variance, and dependence structure should not change substantially over time.

If demand has a changing level or trend, we can take the first difference:

wt=ytyt1w_t=y_t-y_{t-1}

Instead of modelling demand directly, ARIMA then models the daily change. Suppose demand increases from 40 units on Monday to 44 units on Tuesday:

wt=4440=4w_t=44-40=4

The transformed observation is an increase of four units. If one ordinary difference is applied, then d=1d=1. If the original series is already sufficiently stationary, then d=0d=0.

Differencing does not mean that the final forecast is expressed only as a change. After forecasting wt+1w_{t+1}, ARIMA adds the predicted change back to the latest observed demand. For example:

Latest demand:             44 units
Forecasted daily change:   +3 units
Forecasted demand:         47 units

This reversal returns the prediction to the business quantity we care about: units demanded.

Autoregression (AR): use previous values

The autoregressive component assumes that recent values of the stationary or differenced series may contain information about the next value.

An AR(1) relationship is:

wt=c+ϕ1wt1+εtw_t=c+\phi_1w_{t-1}+\varepsilon_t

Here, wt1w_{t-1} is the previous transformed value, ϕ1\phi_1 measures how strongly it carries forward, cc is a constant, and εt\varepsilon_t is a new, unpredictable shock.

Suppose yesterday's demand increased by five units and the model estimates ϕ1=0.6\phi_1=0.6. The autoregressive contribution to today's expected change is:

0.6×5=30.6\times5=3

The model is saying that part of yesterday's movement is likely to continue today. The order pp controls how many previous values are included: p=1p=1 uses one previous value, while p=2p=2 uses the previous two.

Moving average (MA): use previous forecast errors

The moving-average component uses recent forecast errors:

wt=c+εt+θ1εt1w_t=c+\varepsilon_t+\theta_1\varepsilon_{t-1}

The previous error is:

εt1=actualt1forecastt1\varepsilon_{t-1} =\text{actual}_{t-1}-\text{forecast}_{t-1}

Suppose yesterday's forecast was 40 units but actual demand was 45:

εt1=4540=5\varepsilon_{t-1}=45-40=5

The model underestimated demand by five units. If recent surprises tend to carry information into the following day, the MA component uses part of this error to adjust the next forecast.

The order qq determines how many previous errors are used. Despite its name, this is not an ordinary moving average of previous demand; it is a weighted combination of previous forecasting errors.

Combining the components

An ARIMA(1,1,1)(1,1,1) model first calculates the daily difference wt=ytyt1w_t=y_t-y_{t-1}. It then models that difference using one previous value and one previous forecast error:

wt=c+ϕ1wt1+θ1εt1+εtw_t=c+\phi_1w_{t-1}+\theta_1\varepsilon_{t-1}+\varepsilon_t

Finally, it reverses the difference to produce a forecast in units demanded. In plain language, the model asks:

Given the most recent change in demand and how wrong the previous forecast was, what change should we expect next?

The general ARIMA equation summarises the same idea for any orders pp and qq:

wt=c+i=1pϕiwti+εt+j=1qθjεtjw_t =c +\sum_{i=1}^{p}\phi_i w_{t-i} +\varepsilon_t +\sum_{j=1}^{q}\theta_j\varepsilon_{t-j}

Here, wt=Δdytw_t=\Delta^d y_t is the series after applying dd differences. The first sum combines the previous pp transformed values, while the second sum combines the previous qq forecast errors. This article follows the plus-sign convention used by statsmodels; some textbooks define the MA coefficients with the opposite sign.

SARIMA: extend the same idea to weekly demand

ARIMA models short-term relationships between recent values and forecast errors. SARIMA extends it to recurring seasonal patterns:

SARIMA(p,d,q)(P,D,Q)m\mathrm{SARIMA}(p,d,q)(P,D,Q)_m

The lowercase parameters describe ordinary ARIMA behaviour. The uppercase parameters describe seasonal behaviour:

  • PP: seasonal autoregressive order;
  • DD: seasonal differencing order;
  • QQ: seasonal moving-average order;
  • mm: number of observations in one seasonal cycle.

For daily demand with a weekly pattern, m=7m=7.

Seasonal differencing

A weekly seasonal difference compares demand with the same weekday one week earlier:

wt=ytyt7w_t=y_t-y_{t-7}

Suppose demand is 48 units this Monday and was 42 units the previous Monday:

wt=4842=6w_t=48-42=6

Seasonal naive assumes this difference will be zero:

y^t=yt7\hat y_t=y_{t-7}

SARIMA instead predicts the weekly change and adds it to last week's demand:

y^t=yt7+(ytyt7)^\hat y_t=y_{t-7}+\widehat{(y_t-y_{t-7})}

In simple terms:

Seasonal naive repeats last week. SARIMA starts from last week and adjusts for recent changes and forecast errors.

The selected specification

For a Monday forecast, the model begins with demand from the previous Monday. It estimates how demand has changed relative to last week, adjusts for recent forecasting errors, and adds the predicted change back to last Monday's demand.

The validation process described next selects:

SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_7
  • p=1p=1: use one previous value of the transformed series;
  • d=0d=0: no ordinary daily differencing;
  • q=1q=1: use one recent forecast error.
  • P=0P=0: no seasonal autoregressive term;
  • D=1D=1: apply weekly seasonal differencing;
  • Q=1Q=1: use a forecast error from seven days earlier;
  • m=7m=7: use a seven-day seasonal cycle.

How do we choose parameters?

STL, ADF, ACF, PACF, AIC, and BIC help us identify reasonable statistical model specifications. They answer different questions and narrow the candidate set, but they do not select the final model automatically. Chronological validation performance and residual diagnostics make that decision.

STL — Seasonal-Trend decomposition using LOESS

STL explores whether the time series contains trend, seasonality, changing seasonal strength, or unusual events. LOESS means Locally Estimated Scatterplot Smoothing. Seasonal-Trend decomposition using LOESS writes the training series as

yt=Tt+St+Rty_t=T_t+S_t+R_t

where TtT_t is a smooth trend, StS_t is the repeating seasonal component, and RtR_t is the remainder.

STL decomposition of the training window

STL is a diagnostic, not a forecasting model. In this plot it provides four useful clues:

  1. The trend changes substantially after launch and around holiday periods, so a fixed historical mean is inadequate.
  2. A repeating seven-day component supports m=7m=7 for both Holt–Winters and SARIMA.
  3. Seasonal amplitude varies, making multiplicative seasonality worth considering in theory, but zero-demand days make it invalid here.
  4. Large remainders coincide with events that trend and weekday effects cannot explain. A history-only model will continue to miss some of them.

Standard STL, Holt–Winters, and SARIMA each handle one seasonal period cleanly. If both weekly and annual seasonalities needed explicit representation, we would need an extension such as MSTL, TBATS, or dynamic harmonic regression.

ADF — Augmented Dickey–Fuller test

ADF helps assess whether ordinary differencing may be necessary. It tests whether a series contains a unit root, a common form of non-stationarity.

A weakly stationary series has an approximately constant mean, constant variance, and an autocovariance that depends on lag rather than calendar time. ARIMA needs this behaviour in the series it actually models.

The Augmented Dickey–Fuller test uses:

  • H0H_0: the series has a unit root and is non-stationary;
  • H1H_1: the series does not have a unit root under the test specification.

A common rule is:

p-value<0.05reject H0p\text{-value}<0.05 \quad\Rightarrow\quad \text{reject }H_0

The results are:

TransformationADF statisticp-value
Raw demand−3.43280.0099
First difference−8.8361<0.0001\lt 0.0001
Seasonal difference at lag 7−6.1794<0.0001\lt 0.0001

Because the raw-demand p-value is below 0.05, we reject the unit-root null. That supports including candidates with d=0d=0: ordinary first differencing is not automatically required.

It does not prove that the raw series has no trend, seasonality, changing variance, or structural breaks. ADF addresses a specific unit-root question. Weekly differencing is still reasonable because the weekly pattern and correlation plots show a strong lag-seven relationship. We therefore test seasonal orders with both D=0D=0 and D=1D=1.

ACF (Autocorrelation Function) and PACF (Partial Autocorrelation Function)

ACF identifies persistent temporal relationships, seasonal cycles, and possible moving-average structure.

The autocorrelation function measures the correlation between the series and its previous values:

ρk=Corr(yt,ytk)\rho_k=\mathrm{Corr}(y_t,y_{t-k})

at each lag kk. The partial autocorrelation at lag kk measures the incremental relationship after controlling for shorter lags.

For example:

  • lag 1 compares today with yesterday;
  • lag 7 compares today with the same weekday last week;
  • lag 14 compares today with the same weekday two weeks ago.

Typical interpretations include:

  • slow decay across many lags: differencing may be needed;
  • spikes at 7, 14, and 21: weekly seasonality;
  • a sharp cutoff after lag qq: possible MA order qq.

The PACF measures the direct relationship between yty_t and ytky_{t-k} after controlling for the shorter lags. For example, PACF at lag 7 asks:

Does demand from seven days ago add information after accounting for lags 1 through 6?

Typical interpretations include:

  • a strong lag-1 PACF: consider p=1p=1;
  • strong lags 1 and 2: consider p=2p=2;
  • a seasonal spike at lag 7: consider a seasonal AR term P=1P=1.

ACF of raw demand and PACF after weekly differencing

The raw ACF is strongly positive at short lags and shows recurring strength at weekly multiples. The PACF after lag-seven differencing retains a clear lag-one relationship and a smaller set of notable seasonal-multiple spikes. Together, these patterns motivate:

  • a weekly period m=7m=7;
  • non-seasonal AR orders p=1p=1 and p=2p=2 as compact alternatives;
  • a non-seasonal MA term q=1q=1;
  • testing either a seasonal AR term P=1P=1 or a seasonally differenced MA structure with D=1D=1, Q=1Q=1.

ACF and PACF heuristics are cleanest for pure AR or pure MA processes. Real series with mixed AR, MA, seasonal terms, shocks, and finite samples rarely produce textbook cutoffs. They suggest a candidate set; they do not read the final orders directly from the chart.

AIC (Akaike Information Criterion) and BIC (Bayesian Information Criterion)

AIC and BIC compare fitted candidate specifications while penalising unnecessary complexity.

AIC compares statistical models by balancing likelihood fit with model complexity:

AIC=2logL+2kAIC=-2\log L+2k

where LL is the likelihood and kk is the number of estimated parameters.

BIC uses a stronger complexity penalty:

BIC=2logL+klognBIC=-2\log L+k\log n

where nn is the number of observations.

AIC places relatively more emphasis on predictive fit, whereas BIC's stronger penalty generally favours simpler models. Both are in-sample specification diagnostics; neither directly measures operational forecast error.

The tools play complementary roles:

ToolMain questionMost relevant decision
STLWhat trend and seasonality are visible?Seasonal period and model structure
ADFIs there evidence of a unit root?Ordinary differencing dd
ACFWhich lag correlations remain?Seasonality, qq, and possible QQ
PACFWhich lags have direct effects?pp and possible PP
AIC/BICDoes improved fit justify extra complexity?Compare fitted candidates
BacktestingWhich candidate forecasts unseen data best?Final model selection

The resulting candidate set is deliberately small:

CandidateValidation WAPEAICBIC
SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_727.59%5460.485482.92
SARIMA(1,1,1)(1,0,0)7\mathrm{SARIMA}(1,1,1)(1,0,0)_728.39%5605.045627.54
SARIMA(2,0,1)(1,0,0)7\mathrm{SARIMA}(2,0,1)(1,0,0)_729.35%5595.345622.33
SARIMA(1,0,1)(1,0,0)7\mathrm{SARIMA}(1,0,1)(1,0,0)_730.10%5612.005634.50

Lower is preferred among models fitted to the same target, observations, transformation, and comparable likelihood. They are valuable specification diagnostics, but they do not directly measure one-day-ahead operational error. Because differencing can also change the effective likelihood comparison, the chronological validation WAPE remains the primary selection criterion.

Evaluation metrics and model selection

No single metric describes every kind of forecast failure.

MAE: the typical miss in business units

MAE=1nt=1nyty^t\mathrm{MAE}=\frac{1}{n}\sum_{t=1}^{n}|y_t-\hat y_t|

MAE answers the most tangible question: by how many phones is the forecast wrong on an average day? Every unit of error receives equal weight.

RMSE: emphasise large misses

RMSE=1nt=1n(yty^t)2\mathrm{RMSE}=\sqrt{\frac{1}{n}\sum_{t=1}^{n}(y_t-\hat y_t)^2}

Squaring errors makes RMSE more sensitive to occasional large misses. This is useful when any large forecast miss is disproportionately costly. RMSE penalises overforecasting and underforecasting symmetrically; bias is still needed to describe direction. Comparing RMSE with MAE also reveals whether errors are fairly consistent or dominated by spikes.

WAPE: error relative to total demand

WAPE=tyty^ttyt×100\mathrm{WAPE}= \frac{\sum_t|y_t-\hat y_t|}{\sum_t|y_t|}\times100

WAPE is the primary selection metric because it is scale-normalised, aggregates naturally across the evaluation window, and remains defined when individual days have zero demand. MAPE would divide by each actual value and therefore break on closure days.

A WAPE of 25% means total absolute error equals roughly 25% of total observed demand. It does not mean the model is “75% accurate.” Whether 25% is useful depends on the cost and tolerance of the inventory process and on performance relative to credible baselines.

Bias: the direction of total error

Bias=t(y^tyt)tyt×100\mathrm{Bias}=\frac{\sum_t(\hat y_t-y_t)}{\sum_t y_t}\times100

Negative bias means systematic underforecasting; positive bias means overforecasting. Bias cannot stand alone because positive and negative errors can cancel. A nearly unbiased model may still be highly inaccurate.

Validation selects the family winners

On the validation window, additive-trend Holt–Winters wins its family with 28.51% WAPE. The selected SARIMA specification wins its family with 27.59%. Those choices are then locked before the test window is opened.

Three simple baselines provide context. Historical mean predicts the expanding average of all demand observed so far, naive repeats yesterday's demand, and seasonal naive repeats demand from seven days earlier.

The final test results are:

ModelMAERMSEWAPEBias
Holt–Winters: additive trend + weekly8.8711.0424.43%−0.12%
SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_78.9711.1624.71%−4.45%
Historical mean10.5113.3328.95%9.15%
Naive12.6216.2734.76%0.54%
Seasonal naive13.0516.3535.94%2.02%

Final test WAPE for all statistical models and baselines

Holt–Winters lowers WAPE by about 32% relative to seasonal naive and misses by about 8.9 units on an average day. Its aggregate bias is almost zero. SARIMA is only 0.28 WAPE points behind, so the result does not justify a general claim that Holt–Winters is the superior family. It wins this particular test window.

Actual demand and one-day-ahead walk-forward forecasts

The forecast paths also show why the statistical models win: they adapt more smoothly than seasonal naive while retaining the weekly movement. None of them anticipates every sharp commercial shock.

Residual diagnostics add an important qualification. The Ljung–Box test asks whether a group of residual autocorrelations is jointly different from zero. At lags 7, 14, and 21, Holt–Winters has p-values near 0.005, evidence that temporal structure remains in its residuals. SARIMA's p-values range from 0.31 to 0.89, providing no strong evidence of remaining autocorrelation at those lags.

SARIMA is statistically cleaner; Holt–Winters is marginally more accurate on the test window. These findings are compatible. Ljung–Box asks whether residual dependence remains. WAPE asks how large the point errors were. Operational accuracy and statistical adequacy are related, but they are not the same criterion.

From point forecast to a 95% prediction interval

After evaluation, both selected models are refitted using all 730 observations. Their one-day-ahead forecasts for the next simulated date, 19 September 2027, are:

ModelPoint forecastLower 95%Upper 95%
Seasonal naive41.0
Holt–Winters40.010.169.8
SARIMA39.710.968.6

The point forecasts are nearly identical. The test result makes Holt–Winters' 40 units the statistical recommendation, but the interval is just as important as the centre.

SARIMA's state-space likelihood produces a forecast distribution and a model-based interval. Conceptually,

y^t+h±z0.975SE(y^t+h)\hat y_{t+h}\pm z_{0.975}\,\mathrm{SE}(\hat y_{t+h})

with z0.9751.96z_{0.975}\approx1.96, subject to the model's residual assumptions. The Holt–Winters implementation used in the notebook does not expose an analytic interval, so its interval is an explicit Gaussian residual approximation:

y^t+h±1.96σ^ε\hat y_{t+h}\pm1.96\,\hat\sigma_\varepsilon

Lower bounds are clipped at zero because negative unit demand is not operationally meaningful.

Walk-forward forecasts with 95% prediction intervals

Across the 56 test days, the approximate Holt–Winters interval covers 100% of actuals with a mean width of 59.2 units. SARIMA covers 98.2% with a mean width of 57.7 units. Both coverage rates exceed the nominal 95%, suggesting that the intervals may be conservative. With only 56 observations—and an approximate Holt–Winters interval—this remains a diagnostic rather than proof of calibration.

The bands are also wide relative to mean daily demand of 39.5 units. That is an honest result. A history-only model can estimate the recurring centre of demand, but it cannot know tomorrow's promotion, competitor launch, weather, or other external shock.

These intervals quantify uncertainty; they do not prescribe an inventory target. The final step is to combine the forecast with the current inventory position, replenishment lead time, and the business cost of shortages and surplus stock.

Recommendation for inventory decision

For the next simulated day, use Holt–Winters' 40-unit forecast as the expected-demand baseline—not as the order quantity. Holt–Winters becomes the initial production model, while SARIMA continues running in parallel as a challenger.

The replenishment decision should account for the inventory already available, deliveries confirmed to arrive in time, and any safety buffer required by the chosen service level:

Replenishment quantity=max(0,forecast demand+safety bufferstock on handconfirmed inbound)\text{Replenishment quantity} = \max\left( 0,\, \text{forecast demand} +\text{safety buffer} -\text{stock on hand} -\text{confirmed inbound} \right)

If expected demand is 40 units, the store has 27 units available, five more will arrive before the next selling day, and no safety buffer has yet been added, then:

40275=840-27-5=8

The immediate replenishment requirement is eight units. This calculation assumes that replenishment can arrive before tomorrow's demand occurs. If the lead time is longer, the inventory target must cover forecast demand across the full lead-time period.

The upper end of the 95% prediction interval—approximately 70 units—should not automatically become the stock target. It describes forecast uncertainty, not the service level the business should choose. The safety buffer should instead reflect the cost of a stockout relative to the cost of carrying surplus stock.

Known promotions, launches, closures, and price changes should be recorded as explicit business adjustments because neither statistical model sees these events in advance. In production, compare Holt–Winters and SARIMA using rolling WAPE and bias alongside stockouts and excess inventory. Promote SARIMA only if it delivers a sustained improvement across these operational measures.

這篇文章是 預測 iPhone 17 Pro 需求:從統計方法到深度學習 背後的統計深度解析。那篇文章比較了三個世代的預測模型;在這裡,我們放慢腳步,聚焦在一個更精準的問題上:

僅憑歷史需求,我們能預測出明天需求的多少?

這個答案建立了一個基準——任何更複雜的模型都必須超越它。

本文架構如下:

  1. 預測背後的決策
  2. 一條序列,多種行為
  3. 前向滾動回測
  4. 傳統統計時間序列預測
  5. 我們如何選擇參數?
  6. 評估指標與模型選擇
  7. 從點預測到 95% 預測區間
  8. 庫存決策建議

1. 預測背後的決策

在一個虛構的倫敦市中心 Apple Store 情境中,庫存團隊每天晚上都必須決定:某一項配置——iPhone 17 Pro 256GB 淺色——隔天應該備多少台。

預測太低,門市就有缺貨、流失銷售與顧客失望的風險。預測太高,昂貴的裝置就會佔用營運資金與倉儲空間。在單一門市,這個差異或許看起來不大;但放到許多門市與眾多配置加總起來,每天微小的誤差,就會累積成一項實質的庫存決策。

因此,建模的目標是:

yt+1=明天需求台數y_{t+1}=\text{明天需求台數}

而營運面的問題則是:

在明天開始之前,應該備多少台?

需求預測本身,並不會自動告訴我們該備多少台手機。這項決策還取決於「缺貨的成本」相對於「囤貨過多的成本」哪個更高。如果缺貨的代價比較高,規劃者就應該選擇預測分布中較高的分位點;如果庫存過剩的代價比較高,就應該選擇較低的分位點。 報童模型(newsvendor model)將這個選擇表達為:

q=F1(CuCu+Co)q^*=F^{-1}\left(\frac{C_u}{C_u+C_o}\right)

其中,CuC_u 是缺貨成本,CoC_o 是超額庫存成本,F1F^{-1} 則從預測需求分布中選出對應的分位數,qq^* 就是建議的庫存數量。由於本次實驗並沒有這些成本資料,我們無法計算出最適庫存分位點。因此,我們只回報點預測與 95% 預測區間作為預測輸出,將服務水準的決策留給業務端來判斷。

2. 一條序列,多種行為

這個合成資料集包含 730 筆模擬的每日觀測值,時間範圍從 2025 年 9 月 19 日到 2027 年 9 月 18 日。平均每日需求為 39.5 台。模型只接收這個門市-商品組合的日期與歷史需求台數。

目標 iPhone 配置的每日需求與七天移動平均

灰色為每日觀測值;七天移動平均線則呈現需求較緩慢的變動趨勢。

這張圖包含幾種不同型態的時間結構:

  • 生命週期: 需求在上市後偏高,隨後逐漸下降到較成熟的水準。
  • 每週季節性: 星期幾會改變預期需求。
  • 日曆效應: 聖誕節會造成明顯的局部高峰,而公休日則可能產生真正的零需求。
  • 水準變化: 兩年間,局部基準線會上升與下降,而非維持恆定。
  • 不規則衝擊: 促銷與其他商業活動,會產生無法單靠趨勢或星期幾解釋的尖峰。

這是一個單變量預測問題:yty_t 的歷史紀錄就是全部的資訊集合。價格、促銷、行銷、假期、天氣與競爭對手動態,都被刻意排除在外。它們的影響,只會以「無法解釋的需求衝擊」的形式,反映在序列之中。

這個限制其實很有用。在給機器學習模型更多特徵之前,我們想先知道:光靠需求序列本身,能解釋到什麼程度。

3. 前向滾動回測

隨機切分訓練/測試集,會讓未來的市場狀況洩漏到過去。因此,這裡改以時間順序切分觀測值:

區間觀測值數量日期用途
訓練集6182025/09/19–2027/05/29配適候選模型
驗證集562027/05/30–2027/07/24為每個模型家族選出一種規格
測試集562027/07/25–2027/09/18僅估計一次最終表現

依時間順序劃分的訓練、驗證與測試區間

接著,這個評估流程重現了每晚實際的作業方式:

  1. 使用截至第 tt 天結束時,所有可取得的觀測值來配適模型。
  2. 預測第 t+1t+1 天的需求。
  3. 揭曉第 t+1t+1 天的實際需求。
  4. 把這筆觀測值加進可用的歷史資料中。
  5. 往前推進一天,重複上述步驟。

這個做法有幾種常見的稱呼:前向滾動驗證(walk-forward validation)滾動起點評估(rolling-origin evaluation),或時間序列回測(time-series backtesting)。預測期間始終維持一天,但預測起點會隨著驗證集與測試集不斷往前推進。

在每一步,模型只使用當下時間點已經可取得的觀測值。候選規格會先在驗證區間中選定,並在進入測試區間評估之前鎖定下來。這樣可以避免測試資料影響模型設計,讓回報出來的表現更貼近真實情況。

4. 傳統統計時間序列預測

Holt-Winters 與 ARIMA 都假設,序列自身的歷史紀錄包含了關於未來的有用資訊。兩者的差異,在於它們認為這些資訊該長成什麼樣子。

Holt-Winters:預測不斷演變的成分

Holt-Winters 屬於指數平滑家族。它用一組可解釋的狀態來表示時間序列:

需求=水準+趨勢+季節性+雜訊\text{需求}=\text{水準}+\text{趨勢}+\text{季節性}+\text{雜訊}

對於季節週期為 mm 的加法模型,狀態更新方式為:

t=α(ytstm)+(1α)(t1+bt1)bt=β(tt1)+(1β)bt1st=γ(ytt)+(1γ)stm\begin{aligned} \ell_t &= \alpha(y_t-s_{t-m}) +(1-\alpha)(\ell_{t-1}+b_{t-1}) \\ b_t &= \beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1} \\ s_t &= \gamma(y_t-\ell_t)+(1-\gamma)s_{t-m} \end{aligned}

而往前 hh 步的預測則為:

y^t+h=t+hbt+st+hm\hat y_{t+h}=\ell_t+h b_t+s_{t+h-m}

每個狀態,都有對應的商業意涵:

  • 水準 t\ell_t 去除季節效應後,目前的基準值。
  • 趨勢 btb_t 這個基準值每日估計的變化量。
  • 季節狀態 sts_t 週期中某個位置的重複性效應;當 m=7m=7 時,模型維持的是星期幾的模式。

假設現在是星期四晚上,模型要預測兩天後、星期六的需求。目前的估計值為:

  • 基準需求:35 台;
  • 趨勢:每天 −0.2 台;
  • 星期六的季節效應:+8 台。

預測值為:

y^t+2=35+2(0.2)+8=42.6\hat y_{t+2}=35+2(-0.2)+8=42.6

因此,模型預測大約為 43 台。

當星期六的實際需求揭曉後,Holt-Winters 會更新這三個估計值。水準參數 α\alpha 決定基準值反應的強度,β\beta 控制趨勢變化的速度,而 γ\gamma 則決定這個差異中,有多少比例會被當作星期六效應本身的改變。

平滑參數 α\alphaβ\betaγ\gamma 都介於 0 到 1 之間。數值愈高,對新觀測值的反應愈強烈;數值愈低,就愈能保留先前的狀態。換句話說,近期的觀測值最重要,但較舊的觀測值是逐漸淡出,而不是在某個固定的截斷點就直接消失。

當觀測值等間距、季節週期已知且穩定、水準與趨勢緩慢演變,且異常事件不會主導整個序列時,Holt-Winters 的表現最好。加法季節性假設星期幾效應的大小大致固定;這裡排除乘法季節性,是因為序列中包含真正的零需求公休日,而這裡使用的實作方式,要求觀測值必須嚴格為正。

我們驗證三種每週加法候選模型:

  • 水準加季節性;
  • 水準、加法趨勢與季節性;
  • 水準、阻尼趨勢與季節性。

成分規格是在驗證區間中選定的;在每一種規格內,平滑係數則是從訓練歷史資料以數值方式估計出來,而非人工選定。

Holt–Winters 候選模型驗證集 MAE驗證集 WAPE偏差
加法趨勢 + 每週季節性9.3428.51%−2.07%
水準 + 每週季節性9.3628.57%−1.16%
阻尼趨勢 + 每週季節性9.4028.67%−1.18%

這幾個候選模型的表現相當接近,但加法趨勢的驗證集 WAPE 最低,因此被鎖定為這個模型家族中的勝出者。

阻尼趨勢,會把無限外推的 hbth b_t 項,換成一個增量效應會隨預測期間衰減的趨勢。這通常能避免不合理的長期外推,不過對於僅一天的預測而言,影響相對較小。

ARIMA:對變化、持續性與意外事件建模

Holt-Winters 透過水準、趨勢與季節性來描述需求。ARIMA 則用不同的方式處理同一個問題,它問的是:

在把序列變得足夠穩定之後,目前的需求,如何取決於過去的數值與過去的預測誤差?

這個流程可以理解為:

原始需求
      ↓ 差分
近似平穩序列
      ↓ AR 與 MA 建模
預測時間相依性
      ↓ 還原差分
還原為原始單位的需求預測

ARIMA 是 自迴歸整合移動平均模型(AutoRegressive Integrated Moving Average) 的縮寫。其表示法為 ARIMA(p,d,q)\mathrm{ARIMA}(p,d,q),每個參數各自代表不同來源的資訊。

整合(I):對變化量建模,而非對水準本身建模

當 ARIMA 所建模的序列近似平穩時,通常表現最好。其平均數、變異數與相依結構,不應該隨時間出現顯著變化。

如果需求的水準或趨勢會改變,我們可以取一階差分:

wt=ytyt1w_t=y_t-y_{t-1}

此時 ARIMA 建模的不是需求本身,而是每日的變化量。假設需求從星期一的 40 台,增加到星期二的 44 台:

wt=4440=4w_t=44-40=4

轉換後的觀測值就是增加了 4 台。如果套用一次一般差分,則 d=1d=1;如果原始序列本身已經夠平穩,則 d=0d=0

差分並不代表最終的預測結果只會以「變化量」呈現。在預測出 wt+1w_{t+1} 之後,ARIMA 會把預測出的變化量,加回最近一次觀測到的需求值上。舉例來說:

最近一次需求:             44 台
預測的每日變化量:         +3 台
預測需求:                 47 台

這個還原的動作,讓預測值回到我們真正關心的商業量值:需求台數。

自迴歸(AR):使用過去的數值

自迴歸成分假設,平穩序列或差分後序列的近期數值,可能包含關於下一個數值的資訊。

一個 AR(1) 關係式為:

wt=c+ϕ1wt1+εtw_t=c+\phi_1w_{t-1}+\varepsilon_t

其中,wt1w_{t-1} 是前一期的轉換後數值,ϕ1\phi_1 衡量它延續下去的強度,cc 是常數項,而 εt\varepsilon_t 則是全新、無法預測的衝擊。

假設昨天的需求增加了 5 台,而模型估計 ϕ1=0.6\phi_1=0.6。那麼自迴歸成分對今天預期變化量的貢獻為:

0.6×5=30.6\times5=3

這代表模型認為,昨天變動的一部分,很可能會延續到今天。階數 pp 控制納入多少個過去的數值:p=1p=1 使用前一期的數值,p=2p=2 則使用前兩期的數值。

移動平均(MA):使用過去的預測誤差

移動平均成分使用的是近期的預測誤差:

wt=c+εt+θ1εt1w_t=c+\varepsilon_t+\theta_1\varepsilon_{t-1}

前一期的誤差為:

εt1=實際值t1預測值t1\varepsilon_{t-1} =\text{實際值}_{t-1}-\text{預測值}_{t-1}

假設昨天的預測是 40 台,但實際需求是 45 台:

εt1=4540=5\varepsilon_{t-1}=45-40=5

模型低估了 5 台的需求。如果近期的意外落差,往往會把資訊帶到隔天,MA 成分就會利用這個誤差的一部分,來調整下一次的預測。

階數 qq 決定使用多少個過去的誤差。儘管名稱如此,這並不是對過去需求做一般的移動平均,而是對過去預測誤差做加權組合。

結合各個成分

一個 ARIMA(1,1,1)(1,1,1) 模型,會先計算每日差分 wt=ytyt1w_t=y_t-y_{t-1},接著使用前一期的數值與前一期的預測誤差,對這個差分建模:

wt=c+ϕ1wt1+θ1εt1+εtw_t=c+\phi_1w_{t-1}+\theta_1\varepsilon_{t-1}+\varepsilon_t

最後,它會還原差分,產生以需求台數表示的預測值。用白話來說,這個模型問的是:

根據需求最近一次的變化,以及前一次預測錯了多少,我們應該預期接下來會有什麼樣的變化?

以下的一般 ARIMA 方程式,把同樣的概念延伸到任意階數 ppqq

wt=c+i=1pϕiwti+εt+j=1qθjεtjw_t =c +\sum_{i=1}^{p}\phi_i w_{t-i} +\varepsilon_t +\sum_{j=1}^{q}\theta_j\varepsilon_{t-j}

其中,wt=Δdytw_t=\Delta^d y_t 是套用 dd 次差分之後的序列。第一個加總項,結合了前 pp 期的轉換後數值;第二個加總項,則結合了前 qq 期的預測誤差。本文採用 statsmodels 使用的正號慣例;部分教科書會以相反的正負號定義 MA 係數。

SARIMA:把同樣的概念延伸到每週需求

ARIMA 對近期數值與預測誤差之間的短期關係建模。SARIMA 則將這個概念延伸到重複出現的季節模式:

SARIMA(p,d,q)(P,D,Q)m\mathrm{SARIMA}(p,d,q)(P,D,Q)_m

小寫參數描述一般的 ARIMA 行為;大寫參數則描述季節性行為:

  • PP:季節性自迴歸階數;
  • DD:季節性差分階數;
  • QQ:季節性移動平均階數;
  • mm:一個季節週期中的觀測值數量。

對於具有每週模式的每日需求而言,m=7m=7

季節性差分

每週的季節性差分,會將需求與一週前同一個星期幾的需求相比:

wt=ytyt7w_t=y_t-y_{t-7}

假設這個星期一的需求是 48 台,而上個星期一是 42 台:

wt=4842=6w_t=48-42=6

季節性單純法(seasonal naive)假設這個差值會是零:

y^t=yt7\hat y_t=y_{t-7}

SARIMA 則會預測每週的變化量,並把它加到上週的需求上:

y^t=yt7+(ytyt7)^\hat y_t=y_{t-7}+\widehat{(y_t-y_{t-7})}

簡單來說:

季節性單純法只是重複上週的數值。SARIMA 則是從上週的數值出發,再根據近期的變化與預測誤差進行調整。

選定的模型規格

以星期一的預測為例,模型會從上個星期一的需求出發,估計需求相對於上週的變化,並根據近期的預測誤差進行調整,最後把預測出的變化量,加回上個星期一的需求上。

接下來描述的驗證流程,選出的是:

SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_7
  • p=1p=1:使用轉換後序列前一期的數值;
  • d=0d=0:不做一般的每日差分;
  • q=1q=1:使用一個近期的預測誤差;
  • P=0P=0:不含季節性自迴歸項;
  • D=1D=1:套用每週的季節性差分;
  • Q=1Q=1:使用七天前的預測誤差;
  • m=7m=7:使用七天的季節週期。

5. 我們如何選擇參數?

STL、ADF、ACF、PACF、AIC 與 BIC,能幫助我們找出合理的統計模型規格。它們各自回答不同的問題,並縮小候選集合的範圍,但並不會自動選出最終的模型——真正做出這個決定的,是依時間順序的驗證表現,以及殘差診斷。

STL——使用 LOESS 的季節趨勢分解

STL 用來探索時間序列中是否存在趨勢、季節性、季節強度的變化,或異常事件。LOESS 指的是局部估計散佈圖平滑法(Locally Estimated Scatterplot Smoothing)。使用 LOESS 的季節趨勢分解,會把訓練序列寫成

yt=Tt+St+Rty_t=T_t+S_t+R_t

其中,TtT_t 是平滑的趨勢,StS_t 是重複出現的季節成分,RtR_t 則是餘量。

訓練區間的 STL 分解結果

STL 是一種診斷工具,而不是預測模型。在這張圖中,它提供了四項有用的線索:

  1. 趨勢在上市之後與假期前後出現顯著變化,代表固定的歷史平均並不夠用。
  2. 重複出現的七天成分,支持 Holt-Winters 與 SARIMA 都採用 m=7m=7
  3. 季節振幅會變動,理論上值得考慮乘法季節性,但由於存在零需求的日子,這裡並不適用。
  4. 較大的餘量,往往與趨勢和星期幾效應都無法解釋的事件同時出現。純粹只靠歷史資料的模型,仍然會持續漏掉其中一部分。

標準的 STL、Holt-Winters 與 SARIMA,都只能乾淨地處理一個季節週期。如果需要同時明確表示每週與年度兩種季節性,就需要 MSTL、TBATS,或動態調和迴歸(dynamic harmonic regression)等延伸方法。

ADF——增強戴基-富勒檢定

ADF 能幫助我們評估是否需要進行一般差分。它檢定的是序列中是否存在單位根——這是一種常見的非平穩型態。

一個弱平穩序列,具有大致固定的平均數、固定的變異數,而自我共變異數只取決於落後期數,而不取決於實際的日曆時間。ARIMA 實際建模的序列,需要具備這樣的性質。

增強戴基-富勒檢定使用:

  • H0H_0(虛無假設):序列存在單位根,屬於非平穩序列;
  • H1H_1(對立假設):在此檢定設定下,序列不存在單位根。

常見的判斷規則是:

p<0.05拒絕 H0p\text{值}<0.05 \quad\Rightarrow\quad \text{拒絕 }H_0

結果如下:

轉換方式ADF 統計量p 值
原始需求−3.43280.0099
一階差分−8.8361<0.0001\lt 0.0001
落後 7 期的季節性差分−6.1794<0.0001\lt 0.0001

由於原始需求的 p 值低於 0.05,我們拒絕單位根的虛無假設。這支持納入 d=0d=0 的候選模型:並不是一定需要做一般的一階差分。

但這並不能證明原始序列沒有趨勢、季節性、變異數變化,或結構性斷點。ADF 處理的,是一個特定的單位根問題。每週差分仍然是合理的選擇,因為每週模式與相關圖都顯示出強烈的落後 7 期關係。因此,我們會同時測試 D=0D=0D=1D=1 的季節性階數。

ACF(自相關函數)與 PACF(偏自相關函數)

ACF 用來找出持續性的時間關係、季節週期,以及可能的移動平均結構。

自相關函數衡量的是,序列與其過去數值之間的相關性:

ρk=Corr(yt,ytk)\rho_k=\mathrm{Corr}(y_t,y_{t-k})

在每一個落後期 kk 上計算。而落後期 kk 的偏自相關,衡量的則是在控制較短落後期之後,額外增加的關係強度。

舉例來說:

  • 落後 1 期,比較的是今天與昨天;
  • 落後 7 期,比較的是今天與上週同一個星期幾;
  • 落後 14 期,比較的是今天與兩週前同一個星期幾。

常見的解讀方式包括:

  • 在許多落後期上緩慢衰減:可能需要進行差分;
  • 在落後 7、14、21 期出現尖峰:代表每週季節性;
  • 在落後期 qq 之後出現明顯截斷:可能對應 MA 階數 qq

PACF 衡量的是,在控制較短落後期之後,yty_tytky_{t-k} 之間的直接關係。舉例來說,落後 7 期的 PACF 問的是:

在考量過落後 1 到 6 期之後,七天前的需求,是否還能提供額外的資訊?

常見的解讀方式包括:

  • 落後 1 期的 PACF 明顯偏高:可以考慮 p=1p=1
  • 落後 1、2 期都偏高:可以考慮 p=2p=2
  • 在落後 7 期出現季節性尖峰:可以考慮加入季節性 AR 項 P=1P=1

原始需求的 ACF,以及經過每週差分後的 PACF

原始的 ACF 在短落後期呈現強烈的正相關,並在每週倍數的落後期上重複出現較強的數值。經過落後 7 期差分後的 PACF,仍保留明顯的落後 1 期關係,以及一小組值得注意的季節倍數尖峰。綜合這些型態,可以得出以下方向:

  • 每週週期 m=7m=7
  • 非季節性 AR 階數 p=1p=1p=2p=2,作為精簡的替代選項;
  • 非季節性 MA 項 q=1q=1
  • 測試季節性 AR 項 P=1P=1,或是 D=1D=1Q=1Q=1 的季節性差分 MA 結構,兩者皆可嘗試。

ACF 與 PACF 的判讀原則,在純 AR 或純 MA 過程中最為乾淨俐落。而現實中混合了 AR、MA、季節項、隨機衝擊與有限樣本的序列,很少會出現教科書等級的清楚截斷。這些圖表能提示候選集合,但無法直接從圖上讀出最終的階數。

AIC(赤池資訊準則)與 BIC(貝氏資訊準則)

AIC 與 BIC 用來比較已配適的候選規格,同時對不必要的複雜度加以懲罰。

AIC 透過權衡概似配適度與模型複雜度,來比較統計模型:

AIC=2logL+2kAIC=-2\log L+2k

其中,LL 是概似值,kk 是估計出的參數數量。

BIC 則使用更強的複雜度懲罰:

BIC=2logL+klognBIC=-2\log L+k\log n

其中,nn 是觀測值的數量。

AIC 相對更重視預測配適度,而 BIC 較強的懲罰,則通常會偏好較簡單的模型。兩者都是樣本內的規格診斷工具,都不能直接衡量實際營運上的預測誤差。

這些工具彼此扮演互補的角色:

工具主要問題最相關的決策
STL可以看到什麼樣的趨勢與季節性?季節週期與模型結構
ADF是否有單位根的證據?一般差分 dd
ACF哪些落後期的相關性仍然存在?季節性、qq,以及可能的 QQ
PACF哪些落後期具有直接效應?pp,以及可能的 PP
AIC/BIC配適度的改善,是否值得增加的複雜度?比較已配適的候選模型
回測哪個候選模型對未見過的資料預測得最好?最終模型選擇

最終得到的候選集合刻意保持精簡:

候選模型驗證集 WAPEAICBIC
SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_727.59%5460.485482.92
SARIMA(1,1,1)(1,0,0)7\mathrm{SARIMA}(1,1,1)(1,0,0)_728.39%5605.045627.54
SARIMA(2,0,1)(1,0,0)7\mathrm{SARIMA}(2,0,1)(1,0,0)_729.35%5595.345622.33
SARIMA(1,0,1)(1,0,0)7\mathrm{SARIMA}(1,0,1)(1,0,0)_730.10%5612.005634.50

在目標變數、觀測值、轉換方式相同,且概似值具有可比性的模型之間,數值愈低愈好。這些指標是很有價值的規格診斷工具,但並不能直接衡量隔天預測的實際誤差。由於差分也可能改變概似值比較的有效性,依時間順序的驗證集 WAPE,仍然是主要的選擇標準。

6. 評估指標與模型選擇

沒有單一指標,能夠描述所有類型的預測失誤。

MAE:以商業單位表示的典型誤差

MAE=1nt=1nyty^t\mathrm{MAE}=\frac{1}{n}\sum_{t=1}^{n}|y_t-\hat y_t|

MAE 回答的是最直觀的問題:平均而言,每天的預測誤差是幾台手機?每一台的誤差,權重都相同。

RMSE:放大較大的誤差

RMSE=1nt=1n(yty^t)2\mathrm{RMSE}=\sqrt{\frac{1}{n}\sum_{t=1}^{n}(y_t-\hat y_t)^2}

將誤差平方,讓 RMSE 對偶發的大誤差更敏感。當任何一次大幅失準的預測,代價都不成比例地高時,這項指標就特別有用。RMSE 對高估與低估的懲罰是對稱的;要描述誤差的方向,仍然需要偏差指標。比較 RMSE 與 MAE,也能看出誤差是相當一致,還是主要由少數尖峰所主導。

WAPE:相對於總需求的誤差

WAPE=tyty^ttyt×100\mathrm{WAPE}= \frac{\sum_t|y_t-\hat y_t|}{\sum_t|y_t|}\times100

WAPE 是主要的選擇指標,因為它經過尺度標準化、能自然地在整個評估區間中加總,而且即使個別日期需求為零,也仍然有定義。MAPE 則是除以每一天各自的實際值,因此在公休日就會失效。

WAPE 為 25%,代表總絕對誤差,大約等於總觀測需求的 25%。這並不代表模型「準確率是 75%」。25% 是否算是可用的表現,取決於庫存流程的成本與容忍度,也取決於相對於可信基準模型的表現。

偏差:總誤差的方向

Bias=t(y^tyt)tyt×100\mathrm{Bias}=\frac{\sum_t(\hat y_t-y_t)}{\sum_t y_t}\times100

負偏差代表系統性低估;正偏差代表系統性高估。偏差不能單獨使用,因為正負誤差可能會互相抵銷——一個幾乎沒有偏差的模型,仍然可能非常不準確。

驗證集選出各模型家族的勝出者

在驗證區間中,加法趨勢的 Holt-Winters 以 28.51% 的 WAPE,在自己的模型家族中勝出;選定的 SARIMA 規格,則以 27.59% 在其家族中勝出。這些選擇會在打開測試區間之前先行鎖定。

三個簡單的基準模型提供了對照的脈絡。歷史平均法預測的是截至目前為止所有需求的擴張平均數;**單純法(naive)**重複昨天的需求;季節性單純法則重複七天前的需求。

最終的測試結果為:

模型MAERMSEWAPE偏差
Holt–Winters:加法趨勢 + 每週季節性8.8711.0424.43%−0.12%
SARIMA(1,0,1)(0,1,1)7\mathrm{SARIMA}(1,0,1)(0,1,1)_78.9711.1624.71%−4.45%
歷史平均法10.5113.3328.95%9.15%
單純法12.6216.2734.76%0.54%
季節性單純法13.0516.3535.94%2.02%

所有統計模型與基準模型在測試集上的最終 WAPE

相較於季節性單純法,Holt-Winters 把 WAPE 降低了約 32%,平均每天的誤差約為 8.9 台,整體偏差幾乎為零。SARIMA 的 WAPE 只落後 0.28 個百分點,因此這個結果並不足以支持「Holt-Winters 是整體上更優越的模型家族」這種普遍性的說法——它只是在這個特定的測試區間中勝出。

實際需求,與前向滾動的隔日預測

預測路徑也顯示出,為什麼這兩個統計模型會勝出:它們的調整方式比季節性單純法更平滑,同時仍保留每週的變動。但它們都無法預先掌握每一次劇烈的商業衝擊。

殘差診斷則加上了一項重要的但書。Ljung-Box 檢定問的是,一組殘差自相關是否整體顯著不為零。在落後 7、14、21 期,Holt-Winters 的 p 值接近 0.005,顯示其殘差中仍殘留著時間結構。SARIMA 在這些落後期的 p 值介於 0.31 到 0.89 之間,並沒有強烈證據顯示仍存在自相關。

SARIMA 在統計上更乾淨;Holt-Winters 在測試區間上則稍微更準確一些。這兩項發現並不矛盾:Ljung-Box 問的是殘差相依性是否仍然存在,WAPE 問的則是點預測誤差有多大。實務上的準確度,與統計上的適切性彼此相關,但並不是同一套標準。

7. 從點預測到 95% 預測區間

評估完成之後,兩個選定的模型都會使用全部 730 筆觀測值重新配適。它們對下一個模擬日期——2027 年 9 月 19 日——的隔日預測為:

模型點預測95% 下界95% 上界
季節性單純法41.0
Holt–Winters40.010.169.8
SARIMA39.710.968.6

兩者的點預測幾乎相同。根據測試結果,統計上建議採用 Holt-Winters 的 40 台這個數字,但預測區間本身,和中心點同樣重要。

SARIMA 的狀態空間概似函數,會產生一個預測分布,以及以模型為基礎的預測區間。概念上為:

y^t+h±z0.975SE(y^t+h)\hat y_{t+h}\pm z_{0.975}\,\mathrm{SE}(\hat y_{t+h})

其中 z0.9751.96z_{0.975}\approx1.96,並受限於模型對殘差的假設。筆記本中使用的 Holt-Winters 實作,並未提供解析形式的預測區間,因此這裡改用明確的高斯殘差近似:

y^t+h±1.96σ^ε\hat y_{t+h}\pm1.96\,\hat\sigma_\varepsilon

下界會被截斷在零,因為負的需求台數在營運上沒有意義。

附有 95% 預測區間的前向滾動預測

在 56 天的測試期間中,Holt-Winters 的近似區間涵蓋了 100% 的實際值,平均寬度為 59.2 台;SARIMA 則涵蓋了 98.2%,平均寬度為 57.7 台。兩者的涵蓋率,都超過名目上的 95%,顯示這些區間可能偏保守。由於樣本只有 56 筆——且 Holt-Winters 的區間本身就是近似值——這仍然只能算是一項診斷,而不是校準良好的證明。

相對於每日平均需求 39.5 台而言,這些區間的寬度也偏大。這是一個誠實的結果:純粹依賴歷史資料的模型,能夠估計需求重複出現的中心值,但無法知道明天會不會有促銷、競爭對手新品上市、天氣變化,或其他外部衝擊。

這些區間量化的是不確定性,並不能直接指定庫存目標。最後一步,是把預測結果,與目前的庫存部位、補貨前置時間,以及缺貨與庫存過剩的商業成本結合起來考量。

8. 庫存決策建議

對於下一個模擬日期,應該把 Holt-Winters 預測出的 40 台,當作預期需求的基準值——而不是直接當作訂購數量。Holt-Winters 會成為初始的正式模型,而 SARIMA 則會以挑戰模型的角色,持續並行運作。

補貨決策,應該將目前已有的庫存、已確認能及時送達的貨量,以及所選服務水準所需的任何安全緩衝,都納入考量:

補貨量=max(0,預測需求+安全緩衝現有庫存已確認到貨量)\text{補貨量} = \max\left( 0,\, \text{預測需求} +\text{安全緩衝} -\text{現有庫存} -\text{已確認到貨量} \right)

如果預期需求為 40 台,門市目前有 27 台庫存,另外還有 5 台會在下一個銷售日之前送達,且尚未加入任何安全緩衝,那麼:

40275=840-27-5=8

立即需要補貨的數量就是 8 台。這個計算假設補貨能在明天需求發生之前送達;如果前置時間更長,庫存目標就必須涵蓋整個前置時間期間的預測需求。

95% 預測區間的上界——大約 70 台——不應該自動被當作庫存目標。它描述的是預測的不確定性,而不是企業應該選擇的服務水準。安全緩衝,應該反映的是缺貨成本相對於持有過剩庫存成本的高低。

已知的促銷、新品上市、公休與價格變動,都應該記錄為明確的業務調整項目,因為這兩個統計模型都無法預先看到這些事件。在正式上線後,應該用滾動的 WAPE 與偏差,搭配缺貨與庫存過剩的實際情況,來比較 Holt-Winters 與 SARIMA。只有當 SARIMA 在這些營運指標上,展現出持續性的改善時,才應該將它升級為正式模型。