本講學習重點
時間序列 = 按時間順序排列的資料點,相鄰資料點之間存在時間依賴性(autocorrelation),不能直接用普通回歸處理
時間序列分解:趨勢(長期方向)+ 季節性(固定週期波動)+ 殘差(隨機波動),加法模型 vs 乘法模型
平穩性(Stationarity):均值和方差不隨時間改變,是 ARIMA 的前提;差分(Differencing)可讓非平穩序列變平穩
ARIMA(p,d,q):p=自回歸階數(用過去幾個值預測),d=差分次數,q=移動平均階數(過去預測誤差的影響)
Prophet:加法模型,自動處理趨勢轉折點、多重季節性和假期效應,適合業務場景,不需要平穩性假設
時間序列交叉驗證:必須保持時間順序(Walk-Forward Validation),不能隨機打亂分訓練/測試集
評估指標:MAE(平均絕對誤差)、MAPE(平均絕對百分比誤差)、RMSE(均方根誤差)、SMAPE(對稱 MAPE)
🎙️ Podcast(中文)
一句話搞懂
時間序列分析是專門處理「按時間順序排列的資料」的方法——它的核心假設是「今天的數值和昨天、上周、去年同期的數值是有關聯的」,因此必須用特殊的方法來分析和預測;從氣象預報、股價分析、電商的銷售預測,到工廠設備的故障預警,任何「隨時間變化且我們想預測未來走勢」的問題,都屬於時間序列的範疇,而 ARIMA 和 Prophet 是其中最廣泛使用的預測框架。
白話解說
時間序列:資料裡藏著時間的記憶
普通的資料分析(如用年齡預測收入)假設樣本之間是獨立的——張三的收入和李四的收入互不影響。但時間序列資料根本上是不同的:今天的氣溫受到昨天氣溫的影響;本月的銷售量受到上個月、去年同期銷售量的影響。這種「過去影響現在」的特性稱為自相關(Autocorrelation),是時間序列分析的核心。
如果你把時間序列資料用散點圖畫出,通常可以直觀地看到幾個組成成分:
趨勢(Trend):資料的長期方向,可以是上升(如全球電商市場規模逐年增長)、下降(如實體書店銷售量逐年減少),或先漲後跌的非線性趨勢。趨勢反映了驅動該指標長期變化的根本因素。
季節性(Seasonality):在固定週期內重複出現的波動模式。例如:零售業的日季節性(午飯時間和下班後的流量高峰)、週季節性(周末的消費行為和工作日不同)、年季節性(雙 11、聖誕節、農曆新年的銷售高峰)。季節性是可預測的、有規律的波動。
週期性(Cyclicality):與季節性不同,週期性的波動週期不固定,通常與宏觀經濟週期(繁榮、衰退)相關,可能長達幾年甚至幾十年。
殘差(Residual/Noise):去除趨勢和季節性後剩下的隨機波動,代表無法被解釋的隨機因素。
時間序列分解(Decomposition)是把這些成分分離出來的技術,有兩種主要形式:
- 加法模型:時間序列 = 趨勢 + 季節性 + 殘差。適用於季節性波動的幅度不隨趨勢水準改變的情況(如每年銷售高峰固定增加 1000 件)。
- 乘法模型:時間序列 = 趨勢 × 季節性 × 殘差。適用於季節性波動的幅度隨趨勢水準等比例放大的情況(如銷售量越大,雙 11 的絕對增量也越大)。電商、旅遊等業務常符合乘法模型。
平穩性:ARIMA 的前提條件
ARIMA 等經典統計模型要求時間序列具備平穩性(Stationarity)——粗略地說,就是序列的統計特性(均值、方差)不隨時間改變,不存在系統性的趨勢或季節性。
大多數真實世界的時間序列是非平穩的(想想股票價格,整體是往上走的,均值不是固定的)。把非平穩序列轉換為平穩序列最常用的方法是差分(Differencing):
一階差分:計算相鄰兩個時間點的差值,ΔYₜ = Yₜ - Yₜ₋₁。如果原始序列有線性趨勢(價格持續上漲),一階差分後得到的「漲跌幅」序列通常是平穩的。如果一階差分後仍不平穩,可以做二階差分(對差分後的序列再做一次差分)。
判斷序列是否平穩的正式方法是統計檢定,常用的有:
- ADF 檢定(Augmented Dickey-Fuller Test):如果 p 值 < 0.05,可以拒絕「有單位根(非平穩)」的零假設,認為序列是平穩的。
- KPSS 檢定:零假設是「序列是平穩的」,和 ADF 相反,兩者搭配使用可以更確定地判斷。
ARIMA:統計學的經典預測框架
ARIMA(AutoRegressive Integrated Moving Average,自回歸整合移動平均)是時間序列預測中最著名的經典方法,由三個部分組成:
AR(AutoRegressive,自回歸):用過去 p 個時間點的值來預測當前值。直觀上,「今天的氣溫是昨天、前天氣溫的加權組合」就是一個 AR(2) 模型(使用過去 2 個時間點)。
I(Integrated,整合):指對序列做 d 次差分,讓序列變平穩。d=1 代表一階差分,d=0 代表原始序列已經是平穩的。
MA(Moving Average,移動平均):用過去 q 個時間點的預測誤差(而非觀測值本身)來修正預測。直觀上,如果模型昨天、前天都高估了,MA 部分會自動修正「今天也不要預測太高」。
ARIMA(p, d, q) 的參數選擇通常借助以下工具:
- ACF(自相關函數圖):觀察各時間滯後(Lag)的自相關係數,幫助確定 MA 的 q 參數。
- PACF(偏自相關函數圖):控制中間滯後項影響後的自相關係數,幫助確定 AR 的 p 參數。
- auto_arima(
pmdarima套件):自動搜索最優的 (p, d, q) 組合(根據 AIC/BIC 資訊準則)。
ARIMA 的變體 SARIMA(Seasonal ARIMA) 在 ARIMA 的基礎上增加了季節性成分參數 (P, D, Q, m),其中 m 是季節週期長度(如月度資料的季節週期是 m=12)。
Prophet:為業務人員設計的預測工具
雖然 ARIMA 在統計上嚴謹,但對於非統計背景的業務人員來說,選擇合適的 p、d、q 參數、診斷模型等步驟門檻很高。Facebook(現 Meta)的資料科學家於 2017 年開發並開源了 Prophet,專門針對業務場景中的時間序列預測。
Prophet 的核心設計哲學是「把業務知識直接融入模型」:
自動趨勢轉折點偵測(Changepoint Detection):Prophet 會自動找到趨勢發生突變的時間點(如某次重大產品更新、政策改變導致用戶增長曲線出現拐點),而不是假設趨勢永遠是線性的。
多重季節性(Multiple Seasonalities):可以同時處理日、週、月、年等多個週期的季節性,不需要像 SARIMA 一樣只能指定單一季節週期。
假期效應(Holiday Effects):允許直接指定業務相關的假期和特殊事件(雙 11、春節等),模型會自動估計這些事件對時間序列的影響,這對電商、旅遊等業務非常實用。
自動處理缺失值和異常值:Prophet 對資料中的缺失值和異常值有較強的魯棒性,不需要像 ARIMA 那樣對資料進行嚴格的前處理。
from prophet import Prophet
import pandas as pd
# Prophet 要求資料格式:ds(日期)和 y(目標值)
df = pd.DataFrame({'ds': dates, 'y': sales_values})
# 加入自定義假期
holidays = pd.DataFrame({
'holiday': ['double_11', 'double_11'],
'ds': ['2024-11-11', '2023-11-11'],
'lower_window': -2, # 節日前 2 天有效果
'upper_window': 2, # 節日後 2 天有效果
})
model = Prophet(holidays=holidays, yearly_seasonality=True, weekly_seasonality=True)
model.fit(df)
# 未來 90 天的預測
future = model.make_future_dataframe(periods=90)
forecast = model.predict(future)
model.plot(forecast)
時間序列評估:Walk-Forward Validation
時間序列的模型評估不能隨機分訓練集和測試集(因為隨機打亂會把未來的資料放進訓練集,導致資料洩漏)。正確的方法是 Walk-Forward Validation(前向滾動驗證):
- 用時間上最早的 N 個觀測值訓練模型,預測第 N+1 個觀測值。
- 加入第 N+1 個觀測值的真實值,重新訓練,預測第 N+2 個。
- 重複滾動,直到測試完所有保留的測試期資料。
常用的評估指標:
- MAE(Mean Absolute Error,平均絕對誤差):容易解讀,對大誤差不特別敏感。
- MAPE(Mean Absolute Percentage Error,平均絕對百分比誤差):以百分比表示,便於跨不同量級的序列比較;但當真實值接近 0 時會爆炸(除以 0 的問題)。
- RMSE(Root Mean Square Error,均方根誤差):對大誤差更敏感,當你特別不希望出現大誤差時(如供應鏈庫存預測)適合使用。
應用場景
| 場景 | 預測目標 | 適用方法 | 特殊考量 |
|---|---|---|---|
| 零售銷售預測 | 每日/每週銷售量 | Prophet(處理多重季節性和假期) | 促銷活動需要作為外生變數加入模型 |
| 電力負載預測 | 未來 24 小時的用電量 | SARIMA、LSTM | 日週期和年週期都很強,天氣是重要外生變數 |
| 股價/匯率分析 | 明天的價格走勢 | ARIMA 分析結構,但預測精度有限 | 金融時間序列接近隨機遊走,可預測性本就有限 |
| 伺服器流量預測 | 未來 1 小時的請求量 | SARIMA(週期性明顯)、Prophet | 用於自動擴縮容(Auto-scaling)決策 |
| 設備故障預警 | 未來 N 天內是否發生故障 | 時間序列異常偵測 + 分類模型 | 需要對感測器讀數的異常模式特別敏感 |
| 疫情預測 | 未來病例趨勢 | SEIR 傳染病模型、Prophet | 干預措施(封城)是重要的趨勢轉折點 |
| 財務預測 | 下季度的收入/支出 | 指數平滑、Prophet | 業務判斷(計畫中的新產品上線)應作為外部知識輸入 |
常見誤區
誤區 1:「預測的資料越多、模型越複雜,預測就越準確」
這是時間序列預測中最普遍的誤解,實際情況恰恰相反。對於時間序列預測,增加訓練資料的效益是遞減的,而更複雜的模型往往在長期預測上表現更差。
原因一:時間序列的預測不確定性隨預測期增長而急劇擴大。預測「明天的氣溫」和預測「一個月後的氣溫」的難度是完全不同量級的,因為每往前預測一步,誤差就會累積。即使是世界最先進的氣象模型,超過 10 天的預測也幾乎沒有實際參考價值。理解你的預測問題在「哪個時間跨度內是可預測的」比追求模型複雜度更重要。
原因二:使用太久遠的歷史資料可能反而降低準確性,因為 3-5 年前的模式和現在的業務環境可能已經完全不同(例如,疫情前的旅遊消費模式不能直接用來預測疫情後的趨勢)。實務中,許多業務預測問題使用最近 1-2 年的資料反而比使用 5 年資料得到更好的近期預測效果。
原因三:LSTM 等深度學習方法在看似「更強大」的宣傳下,在許多標準時間序列基準測試中(如 M4 Competition、M5 Competition)的表現並不比 ARIMA、指數平滑等傳統統計方法更好,甚至更差。M4 和 M5 競賽的結論都指出,傳統統計方法配合合理的特徵工程(加入外部資訊),仍然是大多數業務預測場景的可靠選擇。
誤區 2:「時間序列可以直接用普通的 K-Fold 交叉驗證評估」
這是一個會讓你的模型評估完全失去意義的操作失誤。在普通的機器學習中,K-Fold 交叉驗證隨機把資料分成 K 個等份,輪流把其中一份作為測試集,其餘作為訓練集。這個方法的前提是樣本之間相互獨立。
但在時間序列中,樣本之間是時間相依的——2024 年 12 月的資料「知道」2024 年 11 月發生了什麼,因為兩者相鄰在時間上。如果你隨機打亂資料後做 K-Fold,訓練集中可能包含 2024 年 12 月的數據,而測試集是 2024 年 10 月的數據——這等於「用未來的資料預測過去」,是典型的資料洩漏,評估結果會顯示出不切實際的高準確率,部署到真實環境後效果遠不如評估結果。
正確做法是Walk-Forward Validation(也稱為時間序列 Cross-Validation):把最早的資料作為初始訓練集,每次往後滾動一個時間窗口,始終確保測試集的時間點在訓練集之後。這樣才能真正模擬「用過去的資料預測未來」的場景,得到有意義的泛化性能評估。
另一種簡化的做法是時間分割(Time-Based Split):把資料按時間切割為前 80% 作為訓練集、後 20% 作為測試集,一次性評估。雖然不如 Walk-Forward Validation 全面,但至少避免了資料洩漏。
誤區 3:「Prophet 是萬能的,任何時間序列預測直接用 Prophet 就好」
Prophet 是一個優秀的工具,特別適合非技術背景的業務分析師使用,但它並非萬能,有幾類場景下的表現反而不佳:
高頻短週期序列:Prophet 設計上最適合每日或更低頻率(每週、每月)的資料,並且通常需要至少幾個月到幾年的歷史資料才能有效地估計季節性。如果你要預測每分鐘或每小時的機器感測器讀數,SARIMA 或基於深度學習的方法(如 N-BEATS、Temporal Fusion Transformer)可能更合適。
多變數時間序列:Prophet 本質上是單變量的(只考慮一個時間序列的歷史值),雖然支援加入外生變數(Regressor),但外生變數的未來值也需要事先知道,這在許多場景下是不現實的。如果你的預測問題有多個相互關聯的時間序列(如多個商品的銷售量互相影響),VAR(向量自回歸)或 LightGBM/XGBoost 配合時間特徵可能更合適。
突然性結構斷裂(Structural Break):如果時間序列在某個時間點因為外部衝擊(如新冠疫情、重大政策改變)而完全改變了行為模式,Prophet 的趨勢轉折點機制雖然能偵測到漸進性的趨勢改變,但對「今天和昨天完全不同」的突然性斷裂的適應能力有限。這類情況需要人工介入:明確地告訴模型「以這個日期為界,前後是兩個不同的世界」,或者直接只使用斷裂後的資料訓練。
小練習
練習 1:識別時間序列的組成成分
以下是四個不同業務場景的描述,請為每個場景識別出最主要的時間序列成分(趨勢、季節性、週期性、隨機性),並解釋你的判斷理由:
- 一家台灣的傳統百貨公司在過去 10 年的月銷售額資料,整體呈現緩慢下滑,每年 12 月和農曆新年前後銷售明顯高於其他月份。
- 過去 2 年的台股加權指數日收盤價,夾雜著各種震盪,但大方向隨著全球景氣緩慢上升。
- 一個 SaaS 軟體平台過去 18 個月的每日活躍用戶(DAU),因為是企業用戶,周末的 DAU 明顯低於工作日,但整體 DAU 因產品持續成長而上升。
- 一家精品咖啡館的每日來客數,整體水準穩定,但有時因附近辦大型展覽而突然暴增。
練習 2:設計電商銷售預測方案
一家台灣電商平台希望預測「未來 30 天每天的訂單量」,用來優化倉儲備貨和物流排班。已知:
- 歷史資料:過去 3 年的每日訂單量
- 每年有雙 11(11/11)、雙 12(12/12)、母親節(5 月第二個周日)等重要促銷活動,活動日的訂單量是平日的 3-10 倍
- 周末的訂單量平均比工作日高 25%
- 近半年平台整體訂單量有上升趨勢,每月大約增長 2%
請設計一個使用 Prophet 的預測方案:(1)說明你會加入哪些設定讓 Prophet 更準確;(2)如何評估這個模型的預測準確性;(3)模型建好後,倉儲團隊應如何使用預測結果做決策?