时间序列分析基石:白噪声与随机游走原理及实战应用
2026/7/30 6:46:42 网站建设 项目流程

1. 从“醉汉走路”到金融预测:为什么必须理解白噪声与随机游走

如果你刚开始接触时间序列分析,可能会觉得“白噪声”和“随机游走”是两个听起来很学术、甚至有点枯燥的概念。但我想告诉你,这两个概念是理解几乎所有时间序列模型(无论是经典的ARIMA,还是热门的LSTM、Transformer)的基石。它们就像盖房子前要打的地基,地基没搞清楚,后面盖的楼再漂亮也可能摇摇欲坠。

我见过不少朋友,一上来就急着用Python的statsmodels库跑ARIMA,或者用TensorFlow搭建LSTM网络做预测。模型跑起来了,结果也出来了,但一看预测曲线和实际值,要么完全对不上,要么就是模型“预测”的明天价格几乎等于今天的价格,然后他们困惑地问:“为什么我的模型好像没学到东西?” 很多时候,问题的根源就在于没有先判断你的数据到底是不是一个“随机游走”。如果你的数据本身就是随机游走,那么用很多复杂模型去预测未来具体的价格点位,本身就是一件近乎不可能完成的任务,模型的“最佳策略”就是猜“明天和今天差不多”。

所以,今天我们不急着上模型,而是彻底搞懂这两个核心概念:白噪声随机游走。我会用最直白的方式,结合金融股价、气象温度、商店销售这些你搜索里关心的例子,把它们讲透。你会明白,为什么有的序列可以预测,有的序列预测起来极其困难,以及我们该如何应对。

2. 白噪声:时间序列中的“纯粹随机”

让我们先从一个最基础、最“干净”的随机结构开始。

2.1 白噪声的严格定义与核心特征

你可以把白噪声想象成一台完全公平的随机数生成器。在每一个时间点t,它产生一个数值。这个数值的大小,完全由“运气”决定,并且满足以下三个严格的数学条件:

  1. 均值为零:长期来看,这些随机数围绕0上下波动,正负抵消,平均值为0。公式表示为 E(ε_t) = 0。
  2. 方差恒定:波动的剧烈程度是稳定的。无论今天是周一还是周五,波动的幅度(方差σ²)都一样。公式表示为 Var(ε_t) = σ²。
  3. 序列不相关:这是白噪声最核心的特征。今天的随机数,和昨天、前天、明天、后天的随机数,没有任何关系。你知道今天ε_t=1.5,这对你猜测明天ε_{t+1}是多少毫无帮助。用自相关系数来表示,就是对于任何非零的时间间隔k,自相关系数 ρ(k) = 0。

在Python中,我们可以用numpy轻松生成一段标准正态分布的白噪声序列,并观察它的样子。

import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 设置样式 plt.style.use('seaborn-v0_8-darkgrid') np.random.seed(42) # 确保结果可复现 # 生成1000个点的标准正态白噪声 n_points = 1000 white_noise = np.random.randn(n_points) # 绘制时序图 fig, axes = plt.subplots(2, 2, figsize=(12, 8)) axes[0, 0].plot(white_noise, lw=0.8) axes[0, 0].set_title('白噪声序列时序图') axes[0, 0].set_xlabel('时间') axes[0, 0].set_ylabel('值') axes[0, 0].axhline(y=0, color='r', linestyle='--', alpha=0.5) # 绘制分布直方图 axes[0, 1].hist(white_noise, bins=30, edgecolor='black', alpha=0.7, density=True) sns.kdeplot(white_noise, ax=axes[0, 1], color='red', lw=2) axes[0, 1].set_title('白噪声分布(近似正态)') axes[0, 1].set_xlabel('值') axes[0, 1].set_ylabel('密度') # 绘制自相关图 (ACF) from statsmodels.graphics.tsaplots import plot_acf plot_acf(white_noise, lags=40, ax=axes[1, 0], title='白噪声自相关图(ACF)') axes[1, 0].set_ylim(-0.2, 0.2) # 强调相关系数在0附近 # 绘制滞后1阶散点图 (今天 vs 昨天) axes[1, 1].scatter(white_noise[:-1], white_noise[1:], alpha=0.5, s=10) axes[1, 1].set_xlabel('t时刻的值') axes[1, 1].set_ylabel('t+1时刻的值') axes[1, 1].set_title('滞后1阶散点图(无相关性)') # 计算并显示相关系数 corr = np.corrcoef(white_noise[:-1], white_noise[1:])[0, 1] axes[1, 1].text(0.05, 0.95, f'相关系数: {corr:.3f}', transform=axes[1, 1].transAxes, verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5)) plt.tight_layout() plt.show()

运行这段代码,你会看到四张图,完美诠释了白噪声的特性:时序图看起来就是围绕0轴上下乱跳,毫无规律;分布图接近标准的钟形曲线(正态分布);自相关图除了在0阶(自己和自己相关,必然是1)有一个尖峰,其他所有滞后阶数的相关系数都几乎为0,并且落在置信区间(图中蓝色区域)内,这证明没有显著的自相关;滞后散点图则是一团均匀的“云”,相关系数接近0。

2. 2 白噪声的现实意义与检验

在时间序列建模中,白噪声扮演着“终极残差”的角色。当我们用一个模型(比如ARIMA)去拟合数据后,会对模型的残差(预测值与真实值的差)进行检验。一个理想的模型,其残差序列应该是一个白噪声。这意味着模型已经提取了数据中所有可能被预测的信息,剩下的部分是完全随机的、不可预测的“噪音”。如果残差不是白噪声(比如还有自相关性),那就说明模型还有改进空间,有些规律没被捕捉到。

如何检验一个序列是不是白噪声?最常用的工具就是上面代码中出现的自相关图Ljung-Box检验。自相关图可以直观地看,而Ljung-Box检验则给出一个统计量(Q统计量)和p值。通常,如果p值大于0.05,我们倾向于认为序列是白噪声。

from statsmodels.stats.diagnostic import acorr_ljungbox # 对上面生成的白噪声进行Ljung-Box检验 lb_test = acorr_ljungbox(white_noise, lags=[10, 20, 30], return_df=True) print(lb_test)

如果输出中lb_pvalue都远大于0.05,则接受原假设(序列是白噪声)。

注意:在实际操作中,尤其是金融高频数据里,你可能会遇到“异方差”现象,即波动率会聚集(大的波动后面跟着大的波动,小的波动后面跟着小的波动)。这种序列的残差可能通过白噪声检验(均值意义上无自相关),但其平方项(代表波动)却有很强的自相关性。这时就需要更复杂的模型(如GARCH族)来刻画波动率了。这是从白噪声检验延伸出去的一个重要知识点。

3. 随机游走:当白噪声开始“累积”

理解了白噪声,随机游走就非常好理解了。随机游走就是白噪声的累积和

3.1 随机游走的数学模型与生成

随机游走的标准定义是:Y_t = Y_{t-1} + ε_t,其中ε_t是一个白噪声。 换句话说,今天的位置等于昨天的位置,加上一个随机的“步长”(白噪声)。如果初始位置Y_0 = 0,那么Y_t = ε_1 + ε_2 + ... + ε_t

这个模型为什么著名?因为它描述了一个“失忆”的醉汉的行走路径。醉汉每一步走的方向和大小都是随机的(白噪声),他下一步去哪,只取决于他现在站在哪,而完全忘了自己是怎么走到这里的。这也是“马尔可夫性”的体现。

我们用Python来生成一个随机游走序列,并和白噪声对比。

# 使用之前生成的白噪声来构造随机游走 random_walk = np.cumsum(white_noise) fig, axes = plt.subplots(2, 2, figsize=(12, 8)) # 时序图对比 axes[0, 0].plot(white_noise, lw=0.8, alpha=0.7, label='白噪声') axes[0, 0].set_title('白噪声序列') axes[0, 0].legend() axes[0, 1].plot(random_walk, lw=1.5, color='orange', label='随机游走') axes[0, 1].set_title('随机游走序列 (由上方白噪声累积而成)') axes[0, 1].legend() # 自相关图(ACF)对比 plot_acf(white_noise, lags=40, ax=axes[1, 0], title='白噪声ACF') axes[1, 0].set_ylim(-0.2, 1.1) plot_acf(random_walk, lags=40, ax=axes[1, 1], title='随机游走ACF') axes[1, 1].set_ylim(-0.2, 1.1) plt.tight_layout() plt.show()

对比非常鲜明:

  1. 时序图:白噪声围绕0轴剧烈但无趋势地波动。随机游走则呈现出明显的“趋势”和“长期记忆”,它会缓慢地漂移到很远的地方,并且没有明显的均值回归倾向。这就是“累积”效应带来的质变。
  2. 自相关图:白噪声的ACF迅速降到0。而随机游走的ACF衰减得非常缓慢,在很长的时间滞后上仍然保持着很高的正相关性。这意味着随机游走的当前值,与很久以前的历史值,仍然有很强的统计关联。这是判断一个序列是否具有“单位根”(即随机游走特征)的直观方法。

3.2 随机游走的深刻性质与预测困境

随机游走有几个让预测者“头疼”但又必须接受的性质:

  1. 无条件均值不确定,条件均值简单:对于一个随机游走,我们无法说它的长期平均水平是多少(无条件均值不存在或依赖于初始值)。但是,在已知今天所有信息的情况下,对明天的最佳点预测就是今天的值。即 E(Y_{t+1} | 所有历史信息) = Y_t。因为明天的期望步长 E(ε_{t+1}) = 0。这就是很多朴素预测模型(如“明天和今天一样”)的理论基础。

  2. 方差随时间线性增长:Var(Y_t) = t * σ²。时间越久远,位置的不确定性就越大。这意味着做长期预测的置信区间会非常宽,预测几乎没有意义。

  3. “不可预测性”:这里的不可预测性,指的是无法预测其未来具体的点位。因为未来的变化完全由不可预测的白噪声驱动。任何试图预测 Y_{t+1} 具体值的模型,其理论上的最优表现就是一直猜 Y_t。

那么,对随机游走序列我们就束手无策了吗?并不是。我们的预测目标需要转变:

  • 从预测绝对值变为预测差分:既然 Y_t - Y_{t-1} = ε_t 是白噪声,那我们就不预测Y本身,而是预测它的变化量(收益率、温差、销售增量)。对于很多金融时间序列,价格序列可能接近随机游走,但收益率序列(价格的对数差分)则可能表现出可建模的模式(如波动率聚集)。
  • 从点预测变为区间预测或分布预测:虽然不知道明天具体是多少点,但我们可以基于历史波动率σ,估算明天价格落在 [Y_t - 1.96σ, Y_t + 1.96σ] 这个区间内的概率约为95%。这对于风险管理至关重要。
  • 识别并处理:在构建ARIMA等模型前,必须用单位根检验(如ADF检验)来判断序列是否具有随机游走特征。如果是,就需要进行差分处理,将其转化为平稳序列后再建模。
from statsmodels.tsa.stattools import adfuller # 对随机游走序列进行ADF检验 result_rw = adfuller(random_walk, autolag='AIC') print(f'随机游走序列ADF检验:') print(f' ADF统计量: {result_rw[0]:.6f}') print(f' p-value: {result_rw[1]:.6f}') # p-value通常 > 0.05,无法拒绝原假设(原假设:存在单位根,即非平稳) # 对随机游走的一阶差分(即白噪声)进行ADF检验 diff_rw = np.diff(random_walk) result_diff = adfuller(diff_rw, autolag='AIC') print(f'\n随机游走一阶差分序列ADF检验:') print(f' ADF统计量: {result_diff[0]:.6f}') print(f' p-value: {result_diff[1]:.6f}') # p-value通常 < 0.05,拒绝原假设,序列平稳

4. 实战辨析:你的数据更像白噪声还是随机游走?

现在我们把理论应用到你的搜索词所涉及的实际场景中。

4.1 案例一:金融时间序列预测(股价)

这是随机游走理论最经典的战场。尤金·法玛的“有效市场假说”弱形式就认为,股价已经反映了所有历史信息,因此其走势近似于随机游走,不可预测。

  • 股价序列本身:通常对数价格序列ln(P_t)非常接近随机游走。它的ACF衰减缓慢,ADF检验p值很大。直接预测明天股价的具体点数极其困难。
  • 对数收益率序列r_t = ln(P_t) - ln(P_{t-1})。这个序列通常近似于白噪声(均值附近随机波动),但关键区别在于,它往往不是严格的白噪声。它的平方序列(代表波动)常有显著的自相关性(波动聚集效应)。这就是为什么预测股价方向难,但预测市场波动率(用GARCH模型)相对可行。你搜索的LSTMTransformer用于股价预测,如果直接预测价格,效果往往不佳;但用于预测收益率或波动率,并结合其他市场微观结构特征,可能挖掘出一些短期微弱的预测能力。

实操心得:拿到一只股票的历史价格,第一步不是急着丢进LSTM,而是画图、看ACF、做ADF检验。如果确认是随机游走,就要调整预期:模型的目标应该是预测收益率方向(分类问题)或波动率,而不是具体价格。特征工程上,创建滞后特征(如过去5天的收益率)是必须的,但这对于随机游走本身来说,这些滞后特征与未来收益率的线性关系可能很弱,需要引入非线性模型(如LSTM)或注意力机制(Transformer)来捕捉复杂关系。

4.2 案例二:气象时间序列预测(如SPSS ARIMA模型)

气象数据,如每日气温、降水量,与金融数据有本质不同。

  • 气温序列:有强烈的季节性(一年四季)和周期性。今天的温度与昨天、去年同期的温度高度相关。它的ACF图会呈现出明显的周期性尖峰(滞后365天左右相关系数很高)。这种序列不是随机游走,它有稳定的长期均值和季节模式。ARIMA模型需要引入季节性差分季节性ARIMA项(即SARIMA模型)来处理。SPSS等工具可以方便地完成季节性分解和SARIMA建模。
  • 白噪声成分:在剔除了趋势、季节周期之后,剩下的残差序列应该接近白噪声。如果残差不是白噪声,说明还有未捕捉到的规律(比如某种周期未考虑)。

实操心得:对于气象、电力负荷等强季节性数据,季节性差分是关键一步。Y_t - Y_{t-365}可以消除年度季节性。同时,创建滞后特征时,不仅要考虑lag1, lag2(短期依赖),更要考虑lag365, lag7(年度和每周周期)。这也是你搜索“为商店销售创建滞后特征”的核心逻辑之一——商店销售同样受星期、月份、节假日影响。

4.3 案例三:异常检测与“醉汉游走”模拟

  • 时间序列异常检测:其核心思想是“建模正常,识别偏离”。我们通常用一个模型(如ARIMA、指数平滑)来预测时间序列在t时刻的“正常值”区间。如果实际值落在预测区间之外,则可能是异常点。这里,对残差序列的假设就是它应为白噪声。如果残差中出现一个巨大的“尖峰”(远超白噪声的预期方差),那这个点就很可疑。你搜索的ISCE(干涉雷达处理软件)做时间序列分析,监测地表形变,其原理之一就是检测形变序列中偏离长期趋势(可能是线性或周期性)的异常信号。
  • 醉汉随机游走模型:这是一个完美的教学和模拟工具。在Matlab或Python中,你可以轻松模拟二维甚至三维的随机游走,来演示扩散过程、布朗运动等物理现象。它直观地展示了“每一步都随机,但整体形成路径”的过程。

5. 高级模型面对随机游走:LSTM与Transformer的挑战

你搜索了“LSTM时间序列预测Python”和“Transformer时间序列预测每次结果都不一样”,这引出了深度学习模型处理时间序列,特别是随机游走类数据时的核心挑战。

5.1 为什么预测结果每次都不一样?

这主要有两个原因,都与随机游走的本质和模型特性有关:

  1. 数据本身的随机性:如果目标序列(如股价)本质上是近似随机游走的,那么其未来值本身就包含一个不可预测的白噪声成分ε_{t+1}。任何模型,无论多么复杂,都无法预测这个纯粹的随机冲击。因此,每次你拿一段包含不同随机冲击的真实数据做测试,模型预测的结果与真实值的差异就会不同,导致评价指标(如RMSE)有波动。
  2. 模型初始化的随机性:LSTM和Transformer模型的训练依赖于随机权重初始化和随机梯度下降。不同的随机种子会导致模型收敛到不同的局部最优解。对于预测任务,如果数据中可学习的、确定性的模式很强(比如有规律的周期信号),那么不同的初始化最终学到的模型会趋于一致,预测结果稳定。但如果数据中随机成分占主导(如随机游走),模型能学到的确定性规律很少,那么不同的初始化就会导致模型学到不同的、但效果都差不多的“伪规律”(比如过度依赖某个无关的滞后特征),从而产生差异较大的预测结果。这实际上是模型在“过拟合”数据中的噪声。

5.2 LSTM/Transformer该如何应对?

  1. 目标转换:不要预测原始序列Y_t,而是预测其差分、收益率或去趋势/去季节化后的序列Y'_t。后者的平稳性和可预测性更强。
  2. 特征工程:除了滞后特征,引入更多外部特征。对于股价,可以加入成交量、移动平均线、RSI等技术指标,其他市场的宏观数据等。为模型提供更多可能包含因果关系的信号,而不是仅仅依赖历史价格本身。
  3. 不确定性量化:使用可以输出预测分布的模型(如贝叶斯神经网络、DeepAR、分位数回归),或者用蒙特卡洛Dropout在预测时进行多次采样,得到一个预测区间,而不仅仅是一个点估计。这比追求一个不稳定的点预测值更有价值。
  4. 模型集成:训练多个不同初始化的模型,对它们的预测结果进行平均(Bagging)。这可以有效降低由于随机初始化带来的方差,使最终预测更稳定。
  5. 调整预期:理解对于高度随机的序列,模型的预测能力存在理论上限。评估模型时,不仅要看RMSE、MAE,更要看它是否比一个简单的基准模型(如朴素预测Ŷ_{t+1} = Y_t,或历史均值)有统计上显著的提升。如果费尽心思搭建的复杂模型只比朴素预测好一点点,那它的实用价值就需要谨慎评估。

一个简单的LSTM预测随机游走的对比实验思路:

import numpy as np import tensorflow as tf from tensorflow import keras from sklearn.metrics import mean_squared_error # 生成模拟随机游走数据 def generate_random_walk(n): return np.cumsum(np.random.randn(n)) # 创建监督学习数据集 (用过去10步预测下一步) def create_dataset(data, look_back=10): X, Y = [], [] for i in range(len(data)-look_back): X.append(data[i:(i+look_back)]) Y.append(data[i + look_back]) return np.array(X), np.array(Y) # 生成数据 np.random.seed(42) data = generate_random_walk(1000) look_back = 10 X, y = create_dataset(data, look_back) X = X.reshape((X.shape[0], X.shape[1], 1)) # 调整为LSTM输入格式 [样本数, 时间步长, 特征数] # 划分训练集和测试集 split = 800 X_train, X_test = X[:split], X[split:] y_train, y_test = y[:split], y[split:] # 定义一个简单的LSTM模型 def build_model(seed): tf.random.set_seed(seed) model = keras.Sequential([ keras.layers.LSTM(50, activation='relu', input_shape=(look_back, 1)), keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='mse') return model # 用不同的随机种子训练多个模型 predictions = [] for seed in [42, 123, 456]: model = build_model(seed) model.fit(X_train, y_train, epochs=20, batch_size=32, verbose=0) pred = model.predict(X_test, verbose=0).flatten() predictions.append(pred) # 计算该模型的RMSE rmse = np.sqrt(mean_squared_error(y_test, pred)) print(f"随机种子 {seed} 的模型在测试集上的RMSE: {rmse:.4f}") # 计算朴素预测(用前一个值)的RMSE naive_pred = X_test[:, -1, 0] # 取每个样本序列的最后一个值作为预测 naive_rmse = np.sqrt(mean_squared_error(y_test, naive_pred)) print(f"\n朴素预测 (Ŷ_t+1 = Y_t) 的RMSE: {naive_rmse:.4f}") # 计算模型集成(平均)的RMSE ensemble_pred = np.mean(predictions, axis=0) ensemble_rmse = np.sqrt(mean_squared_error(y_test, ensemble_pred)) print(f"模型集成(平均)的RMSE: {ensemble_rmse:.4f}")

运行这个实验,你可能会发现:

  1. 不同随机种子训练出的LSTM模型,其RMSE有差异。
  2. LSTM模型的RMSE可能并不比简单的朴素预测(Ŷ_{t+1} = Y_t)好多少,甚至更差。这正印证了随机游走预测的困境。
  3. 模型集成后的预测可能会更稳定一些。

理解白噪声和随机游走,不是为了让我们对预测感到悲观,而是为了让我们更清醒、更科学地对待时间序列数据。它能帮助我们在建模前进行正确的数据预处理(如差分),设定合理的目标(预测变化量而非绝对值),选择恰当的模型,并最终对模型的预测结果有一个理性的预期。这是从时间序列分析新手走向熟练从业者的关键一步。下次当你看到股价曲线时,你会看到一串随机游走;当你看到模型的残差图时,你会本能地去检查它是否像白噪声。这种直觉,就是深入理解这两个概念带来的最大价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询