跳转至

12.1   时间序列基本概念

暑假里,小率在奶茶店帮忙整理销售记录。他发现同样是“销量”,按日期排起来以后,折线像有记忆:周末会高一点,天气热会高一点,连续几天促销后还会慢慢回落。

图 12.1.1 小率带着奶茶店销量记录来问时间序列

日期 最高气温 奶茶销量
7 月 1 日 31 118
7 月 2 日 32 126
7 月 3 日 33 137
... ... ...
7 月 7 日 35 172
均哥,我以前会把销量当成一列普通数字。现在按日期一画,怎么感觉它们互相牵着走?
这就是时间序列最特别的地方:顺序本身带信息。今天不是随机抽出来的一天,它站在昨天和明天中间。

12.1.1   时间顺序让数据有了记忆

时间序列 (Time Series) 是按时间顺序记录的一串观测值,通常写成:

\[ y_1, y_2, \ldots, y_t, \ldots, y_T \]

这里的下标 \(t\) 表示时间。普通横截面数据常问“这些人有什么差异”;时间序列常问“这个量怎样随时间变化,以及接下来会怎样”。

时间序列常见在哪里

每日销量、每小时客流、每月收入、每周体重、每天步数、气温、空气质量、网站访问量、股票价格,都可以按时间序列来分析。

12.1.2   一条折线通常混着三种东西

一条真实时间序列通常不是单一原因造成的。奶茶销量里至少混着三层信号:

  • 趋势 (Trend):长期向上、向下或基本水平。
  • 季节 (Seasonality):每周、每月、每年重复出现的周期波动。
  • 残差 (Residual):趋势和季节解释不了的临时扰动。

图 12.1.2 时间序列可以拆成趋势、季节和残差

最常见的加法分解写作:

\[ \text{原序列} = \text{趋势} + \text{季节} + \text{残差} \]

也就是:

\[ y_t = T_t + S_t + R_t \]

如果销量越高,季节波动幅度也越大,可以先对数据取对数,再用加法思路处理。

12.1.3   自相关:今天和前几天有多像

时间序列里的“记忆”,常用自相关 (Autocorrelation) 描述。滞后 \(k\) 阶自相关,就是把序列和自己向后错开 \(k\) 个时间单位后计算相关性。

\[ \rho_k = \operatorname{Corr}(y_t, y_{t-k}) \]

如果奶茶销量的 \(\rho_7\) 很高,说明“今天”和“上周同一天”很像,周周期可能很强。

小率的问题

如果昨天销量高,今天销量也容易高,这是不是说明天气一定是原因?

不一定。自相关只说明时间上的相似,不直接说明因果。天气、促销、节假日都可能一起影响销量。

12.1.4   用 Python 先做三件小事

拿到时间序列后,先不要急着建复杂模型。先画图、算滚动均值、看自相关。

from pathlib import Path
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import acf

rng = np.random.default_rng(12)
dates = pd.date_range("2026-01-01", periods=72, freq="W")
trend = np.linspace(80, 130, len(dates))
season = 12 * np.sin(2 * np.pi * np.arange(len(dates)) / 4)
noise = rng.normal(0, 5, len(dates))
sales = pd.Series(trend + season + noise, index=dates, name="奶茶销量")

rolling = pd.DataFrame({
    "销量": sales,
    "4 周滚动均值": sales.rolling(4).mean(),
    "4 周滚动标准差": sales.rolling(4).std(),
})

print(rolling.head(8).round(1))
print("前 8 阶自相关:", np.round(acf(sales, nlags=8), 2))

完整脚本见:

docs/assets/scripts/ch12_time_series/01_ts_basics/main.py

不要把时间打乱

时间序列建模时,训练集和测试集不能随机打散。预测未来时,模型只能看见过去,不能偷看未来。

小率的笔记本

时间序列 = 按时间顺序排列的数据。
第一眼先看折线图:有没有趋势、季节、异常点。
第二眼看自相关:今天和前几天、前几周是否相似。
做预测前,必须保留时间顺序。