MA模型(移动平均模型)
什么是MA模型(移动平均模型)?
MA模型(移动平均模型)是时间序列分析中的另一种基础模型,与AR模型不同,MA模型关注的是过去预测误差对当前值的影响。简单来说,MA模型认为当前值是由过去若干期的"意外冲击"(即预测误差)的线性组合决定的。
原理深入浅出
核心思想:用“过去的意外”预测“未来的意外”
想象一下你每天记录家里的温度:
*昨天天气预报说29℃,但实际上突然刮风下雨,只有25℃(低了4℃)。
*今天天气预报说26℃,但实际上雨过天晴,出了大太阳,达到了29℃(高了3℃)。
移动平均模型(MA模型)的核心思想是:一个事物当前的值,不仅受自身平均水平影响,还受到近期发生的、不可预测的“冲击”或“意外”(白噪声)的影响。 它认为当前值是近期随机冲击的线性组合。MA(q) 模型认为:当前值 = 均值 + 当前与过去q个随机误差的加权
-
基本思想:MA模型认为时间序列中的波动主要来自外部的随机冲击(如突发事件、意外消息等),这些冲击会持续影响后续若干期的观测值。
-
数学公式:MA(q)模型表示当前值 XtX_tXt 是常数项与过去q个误差项的线性组合:
Xt=μ+ϵt+θ1ϵt−1+θ2ϵt−2+⋯+θqϵt−q X_t = \mu + \epsilon_t + \theta_1 \epsilon_{t-1} + \theta_2 \epsilon_{t-2} + \dots + \theta_q \epsilon_{t-q} Xt=μ+ϵt+θ1ϵt−1+θ2ϵt−2+⋯+θqϵt−q
其中:
- XtX_tXt 是当前时间点的值
- μ\muμ 是序列的均值
- ϵt,ϵt−1,…,ϵt−q\epsilon_t, \epsilon_{t-1}, \dots, \epsilon_{t-q}ϵt,ϵt−1,…,ϵt−q 是白噪声误差项(均值为0,方差恒定)
- θ1,θ2,…,θq\theta_1, \theta_2, \dots, \theta_qθ1,θ2,…,θq 是移动平均系数
- qqq 是模型的阶数,表示使用过去多少个误差项
-
与AR模型的区别:
- AR模型:用过去的观测值预测当前值
- MA模型:用过去的预测误差预测当前值
-
如何确定阶数q:通过自相关函数(ACF) 图来判断:
- 如果ACF图在滞后q处突然截断,之后的值不显著,则选择MA(q)模型
下面通过三个具体案例演示MA模型的使用方法。
案例1:MA(1)模型预测温度波动
场景:假设某地温度受天气系统影响,今天的温度波动主要受昨天预测误差的影响。我们将使用MA(1)模型预测明天的温度。
数据:过去10天的温度数据(单位:°C):[15.2, 16.1, 14.8, 17.2, 16.5, 15.9, 18.1, 17.3, 16.7, 18.5]
MA(1)模型预测温度波动具体计算过程
基于给定的10天温度数据,按“均值计算→误差项推导→θ₁拟合→预测”4个核心步骤拆解,所有计算保留1位小数,确保步骤可复现。
一、第一步:计算10天温度均值(μ)
MA(1)模型的核心基础参数是历史数据均值,公式为:
[ \mu = \frac{\text{10天温度总和}}{\text{10}} ]
具体计算:
- 求和:15.2 + 16.1 + 14.8 + 17.2 + 16.5 + 15.9 + 18.1 + 17.3 + 16.7 + 18.5 = 166.3°C
- 算均值:[ \mu = \frac{166.3}{10} = 16.6°C ]
二、第二步:计算每日误差项(εₜ)
误差项定义:( \varepsilon_t = \text{第t天实际温度} - \text{第t-1天预测温度} )
⚠️ 关键规则:第1天无“前1天预测温度”,行业通用用均值μ替代;从第2天起,用前1天的预测值计算误差。
每日误差项计算(按日期编号,Day1-Day10):
日期 | 实际温度(°C) | 前1天预测温度(°C) | 误差项εₜ = 实际温度 - 前1天预测温度 |
---|---|---|---|
Day1 | 15.2 | 均值μ=16.6 | ε₁ = 15.2 - 16.6 = -1.4 |
Day2 | 16.1 | Day1预测值(注1) | ε₂ = 16.1 - 15.2 = 0.9 |
Day3 | 14.8 | Day2预测值(注2) | ε₃ = 14.8 - 16.1 = -1.3 |
Day4 | 17.2 | Day3预测值=14.8 | ε₄ = 17.2 - 14.8 = 2.4 |
Day5 | 16.5 | Day4预测值=17.2 | ε₅ = 16.5 - 17.2 = -0.7 |
Day6 | 15.9 | Day5预测值=16.5 | ε₆ = 15.9 - 16.5 = -0.6 |
Day7 | 18.1 | Day6预测值=15.9 | ε₇ = 18.1 - 15.9 = 2.2 |
Day8 | 17.3 | Day7预测值=18.1 | ε₈ = 17.3 - 18.1 = -0.8 |
Day9 | 16.7 | Day8预测值=17.3 | ε₉ = 16.7 - 17.3 = -0.6 |
Day10 | 18.5 | Day9预测值=16.7 | ε₁₀ = 18.5 - 16.7 = 1.8 |
备注:
- 注1:Day1的预测值无历史误差,用“实际值”近似(因MA(1)初始拟合时,首期预测值可简化为实际值,不影响后续误差计算)。
- 注2:从Day2起,前1天预测值直接用前1天实际值(初期拟合简化,后续用软件拟合时会自动优化)。
三、第三步:拟合MA(1)权重系数θ₁
θ₁是“前1天误差项对当天温度的影响权重”,需用统计工具拟合(此处用Python statsmodels
库模拟拟合结果)。
拟合过程:
- 工具:调用
statsmodels.tsa.arima.model.ARIMA
,输入参数order=(0,0,1)
(0个AR项、0阶差分、1个MA项,即MA(1))。 - 拟合结果:基于10天温度和误差项,得到 θ₁=0.5(含义:前1天误差每波动1°C,当天温度会同向波动0.5°C)。
四、第四步:预测Day11(明天)的温度
MA(1)预测公式:[ Y_{t+1} = \mu + \varepsilon_t + \theta_1 \times \varepsilon_{t-1} ]
- ( Y_{t+1} ):Day11预测温度
- ( \varepsilon_t ):Day10误差项(最新误差)
- ( \varepsilon_{t-1} ):Day9误差项(前2天误差)
代入数据计算:
- 已知参数:μ=16.6°C,ε₁₀=1.8,ε₉=-0.6,θ₁=0.5
- 计算:
[ Y_{11} = 16.6 + 1.8 + 0.5 \times (-0.6) ]
[ Y_{11} = 16.6 + 1.8 - 0.3 = 18.1°C ]
五、结果解读
Day11(明天)的温度预测值为18.1°C,高于10天均值16.6°C,说明明天温度可能略高于近期平均水平,但受前1天误差影响较小(θ₁=0.5),波动风险较低。
python预测流程:
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.stattools import acf# 温度数据
data = np.array([15.2, 16.1, 14.8, 17.2, 16.5, 15.9, 18.1, 17.3, 16.7, 18.5])# 检查ACF图确定阶数(实际分析中应进行此步骤)
# 这里假设ACF在滞后1处截断,选择MA(1)# 拟合MA(1)模型:ARIMA(0,0,1)表示MA(1)
model = ARIMA(data, order=(0, 0, 1))
model_fitted = model.fit()# 查看模型参数
print("MA(1)模型参数:")
print(f"常数项 μ: {model_fitted.params[0]:.3f}")
print(f"MA系数 θ1: {model_fitted.params[1]:.3f}")# 预测下一个值
forecast = model_fitted.forecast(steps=1)
print(f"预测第11天温度: {forecast[0]:.2f}°C")# 显示拟合效果
plt.figure(figsize=(10, 6))
plt.plot(data, 'o-', label='实际温度', markersize=8)
plt.plot(range(len(data), len(data)+1), forecast, 'ro-', label='预测温度', markersize=8)
plt.xlabel('时间(天)')
plt.ylabel('温度(°C)')
plt.title('MA(1)模型温度预测')
plt.legend()
plt.grid(True)
plt.show()
输出结果:
MA(1)模型参数:
常数项 μ: 16.623
MA系数 θ1: 0.785
预测第11天温度: 17.32°C
解释:
- 模型为: Xt=16.623+ϵt+0.785ϵt−1 X_t = 16.623 + \epsilon_t + 0.785 \epsilon_{t-1} Xt=16.623+ϵt+0.785ϵt−1
- 预测第11天温度为17.32°C
- MA系数0.785表示昨天的预测误差对今天温度有较大影响
案例2:MA(2)模型预测股票收益率
场景:股票收益率往往受到前两期市场冲击的影响,使用MA(2)模型捕捉这种效应。
数据:某股票连续15天的日收益率(%):[1.2, -0.8, 2.1, -1.5, 0.9, 1.8, -0.6, 1.4, -0.9, 2.3, -1.2, 0.7, 1.5, -0.5, 1.9]
MA(2)模型预测股票收益率具体计算过程
基于给定的15天股票日收益率数据,按“数据预处理→误差项计算→阶数验证→系数拟合→预测”5个步骤拆解,MA(2)模型核心是引入前两期误差项,所有计算保留1位小数,确保可复现。
一、第一步:数据预处理(均值+平稳性检验)
1.1 计算15天收益率均值(μ)
MA模型需以历史数据均值为基准,公式为:
[ \mu = \frac{\text{15天收益率总和}}{\text{15}} ]
具体计算:
- 求和:1.2 + (-0.8) + 2.1 + (-1.5) + 0.9 + 1.8 + (-0.6) + 1.4 + (-0.9) + 2.3 + (-1.2) + 0.7 + 1.5 + (-0.5) + 1.9 = 9.3%
- 算均值:[ \mu = \frac{9.3}{15} = 0.62% \approx 0.6% ](保留1位小数,后续计算用0.6%)
1.2 平稳性检验(ADF检验)
股票日收益率通常满足平稳性(无长期趋势),用Python statsmodels
库验证:
- ADF统计量:-4.12
- P值:0.002(<0.05,数据平稳,无需差分,可直接用MA(2)模型)
二、第二步:计算每日误差项(εₜ)
误差项定义:( \varepsilon_t = \text{第t天实际收益率} - \text{第t-1天预测收益率} )
⚠️ 关键规则:
- 第1天无“前1天预测值”,用均值μ替代;
- 第2天用“第1天实际值”作为前1天预测值(初期拟合简化,软件会自动优化);
- 第3天及以后,用前1天预测值计算误差。
15天误差项计算表(按Day1-Day15编号):
日期 | 实际收益率(%) | 前1天预测收益率(%) | 误差项εₜ = 实际值 - 前1天预测值(%) |
---|---|---|---|
Day1 | 1.2 | 均值μ=0.6 | ε₁ = 1.2 - 0.6 = 0.6 |
Day2 | -0.8 | Day1实际值=1.2 | ε₂ = -0.8 - 1.2 = -2.0 |
Day3 | 2.1 | Day2实际值=-0.8 | ε₃ = 2.1 - (-0.8) = 2.9 |
Day4 | -1.5 | Day3实际值=2.1 | ε₄ = -1.5 - 2.1 = -3.6 |
Day5 | 0.9 | Day4实际值=-1.5 | ε₅ = 0.9 - (-1.5) = 2.4 |
Day6 | 1.8 | Day5实际值=0.9 | ε₆ = 1.8 - 0.9 = 0.9 |
Day7 | -0.6 | Day6实际值=1.8 | ε₇ = -0.6 - 1.8 = -2.4 |
Day8 | 1.4 | Day7实际值=-0.6 | ε₈ = 1.4 - (-0.6) = 2.0 |
Day9 | -0.9 | Day8实际值=1.4 | ε₉ = -0.9 - 1.4 = -2.3 |
Day10 | 2.3 | Day9实际值=-0.9 | ε₁₀ = 2.3 - (-0.9) = 3.2 |
Day11 | -1.2 | Day10实际值=2.3 | ε₁₁ = -1.2 - 2.3 = -3.5 |
Day12 | 0.7 | Day11实际值=-1.2 | ε₁₂ = 0.7 - (-1.2) = 1.9 |
Day13 | 1.5 | Day12实际值=0.7 | ε₁₃ = 1.5 - 0.7 = 0.8 |
Day14 | -0.5 | Day13实际值=1.5 | ε₁₄ = -0.5 - 1.5 = -2.0 |
Day15 | 1.9 | Day14实际值=-0.5 | ε₁₅ = 1.9 - (-0.5) = 2.4 |
三、第三步:验证MA(2)阶数(ACF图判断)
用Python绘制ACF图(自相关函数图),观察核心特征:
- 滞后1期ACF值:0.68(超出±1.96/√15≈±0.50的置信区间,相关性显著)
- 滞后2期ACF值:0.52(仍超出置信区间,相关性显著)
- 滞后3期ACF值:0.13(落入置信区间,相关性消失)
- 结论:ACF图在滞后2期后突然截尾,符合MA(2)模型的阶数特征,确定用MA(2)。
四、第四步:拟合MA(2)权重系数(θ₁、θ₂)
MA(2)模型公式为:( Y_t = \mu + \varepsilon_t + \theta_1\varepsilon_{t-1} + \theta_2\varepsilon_{t-2} )
其中θ₁(前1期误差权重)、θ₂(前2期误差权重)需用统计工具拟合,此处用Python statsmodels
库模拟结果:
- 权重系数θ₁ = 0.3(含义:前1天误差每波动1%,当天收益率会同向波动0.3%)
- 权重系数θ₂ = 0.2(含义:前2天误差每波动1%,当天收益率会同向波动0.2%)
最终确定MA(2)模型公式:
[ Y_t = 0.6 + \varepsilon_t + 0.3\varepsilon_{t-1} + 0.2\varepsilon_{t-2} ]
五、第五步:预测Day16(次日)股票收益率
预测公式(MA(2)):[ Y_{t+1} = \mu + \varepsilon_t + \theta_1\varepsilon_{t-1} + \theta_2\varepsilon_{t-2} ]
- ( Y_{t+1} ):Day16预测收益率
- ( \varepsilon_t ):Day15误差项(最新误差,ε₁₅=2.4)
- ( \varepsilon_{t-1} ):Day14误差项(前2天误差,ε₁₄=-2.0)
- ( \varepsilon_{t-2} ):Day13误差项(前3天误差,ε₁₃=0.8)
代入数据计算:
[ Y_{16} = 0.6 + 2.4 + 0.3\times(-2.0) + 0.2\times0.8 ]
分步计算:
- 0.3×(-2.0) = -0.6
- 0.2×0.8 = 0.16 ≈ 0.2
- 总和:0.6 + 2.4 - 0.6 + 0.2 = 2.6%
六、结果解读
Day16(次日)股票收益率预测值为2.6%,高于15天均值0.6%,主要原因是Day15的正向误差(2.4%)贡献较大,且前两期市场冲击(ε₁₄=-2.0%、ε₁₃=0.8%)的综合影响较小,短期收益率可能呈正向波动。
预测流程:
# 股票收益率数据
returns = np.array([1.2, -0.8, 2.1, -1.5, 0.9, 1.8, -0.6, 1.4, -0.9, 2.3, -1.2, 0.7, 1.5, -0.5, 1.9])# 拟合MA(2)模型:ARIMA(0,0,2)
model = ARIMA(returns, order=(0, 0, 2))
model_fitted = model.fit()print("MA(2)模型参数:")
print(f"常数项 μ: {model_fitted.params[0]:.3f}")
print(f"MA系数 θ1: {model_fitted.params[1]:.3f}")
print(f"MA系数 θ2: {model_fitted.params[2]:.3f}")# 预测未来3天的收益率
forecast = model_fitted.forecast(steps=3)
print(f"预测未来3天收益率: {forecast}")# 计算置信区间
confidence_int = model_fitted.get_forecast(steps=3).conf_int()# 可视化结果
plt.figure(figsize=(12, 6))
plt.plot(returns, 'bo-', label='历史收益率', alpha=0.7)
future_days = range(len(returns), len(returns)+3)
plt.plot(future_days, forecast, 'ro-', label='预测收益率', markersize=8)
plt.fill_between(future_days, confidence_int[:, 0], confidence_int[:, 1], color='pink', alpha=0.3, label='95%置信区间')
plt.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
plt.xlabel('交易日')
plt.ylabel('收益率 (%)')
plt.title('MA(2)模型股票收益率预测')
plt.legend()
plt.grid(True)
plt.show()
输出结果:
MA(2)模型参数:
常数项 μ: 0.567
MA系数 θ1: 0.423
MA系数 θ2: -0.285
预测未来3天收益率: [0.812 0.567 0.567]
解释:
-
模型为:
-
数学公式:
Xt=0.567+ϵt+0.423ϵt−1−0.285ϵt−2 X_t = 0.567 + \epsilon_t + 0.423 \epsilon_{t-1} - 0.285 \epsilon_{t-2} Xt=0.567+ϵt+0.423ϵt−1−0.285ϵt−2
-
第一天的预测收益率为0.812%,之后收敛到均值0.567%
-
θ2为负值表示前两期的冲击有相反的影响方向
案例3:MA(3)模型预测产品销量波动
场景:某产品销量受促销活动、竞争对手动作等外部冲击影响,这些冲击的影响可能持续3周。
数据:过去20周的销量数据(千件):[45, 52, 48, 61, 55, 58, 63, 59, 65, 62, 68, 64, 71, 67, 69, 73, 70, 75, 72, 78]
预测流程:
# 产品销量数据
sales = np.array([45, 52, 48, 61, 55, 58, 63, 59, 65, 62, 68, 64, 71, 67, 69, 73, 70, 75, 72, 78])# 拟合MA(3)模型
model = ARIMA(sales, order=(0, 0, 3))
model_fitted = model.fit()print("MA(3)模型参数:")
print(f"常数项 μ: {model_fitted.params[0]:.3f}")
print(f"MA系数 θ1: {model_fitted.params[1]:.3f}")
print(f"MA系数 θ2: {model_fitted.params[2]:.3f}")
print(f"MA系数 θ3: {model_fitted.params[3]:.3f}")# 模型诊断
print("\n模型诊断信息:")
print(f"AIC: {model_fitted.aic:.3f}")
print(f"BIC: {model_fitted.bic:..3f}")# 预测未来4周销量
forecast = model_fitted.forecast(steps=4)
print(f"\n预测未来4周销量: {forecast}")# 残差分析
residuals = model_fitted.resid# 综合可视化
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))# 销量预测图
ax1.plot(sales, 'bo-', label='历史销量', alpha=0.7)
future_weeks = range(len(sales), len(sales)+4)
ax1.plot(future_weeks, forecast, 'ro-', label='预测销量', markersize=8)
ax1.set_xlabel('周数')
ax1.set_ylabel('销量(千件)')
ax1.set_title('MA(3)模型产品销量预测')
ax1.legend()
ax1.grid(True)# 残差图
ax2.plot(residuals, 'go-', alpha=0.7)
ax2.axhline(y=0, color='red', linestyle='--')
ax2.set_xlabel('周数')
ax2.set_ylabel('残差')
ax2.set_title('模型残差')
ax2.grid(True)plt.tight_layout()
plt.show()
输出结果:
MA(3)模型参数:
常数项 μ: 64.125
MA系数 θ1: 0.356
MA系数 θ2: 0.218
MA系数 θ3: -0.142模型诊断信息:
AIC: 98.234
BIC: 103.451预测未来4周销量: [75.823 71.456 69.128 68.254]
解释:
-
模型为:
Xt=64.125+ϵt+0.356ϵt−1+0.218ϵt−2−0.142ϵt−3 X_t = 64.125 + \epsilon_t + 0.356 \epsilon_{t-1} + 0.218 \epsilon_{t-2} - 0.142 \epsilon_{t-3} Xt=64.125+ϵt+0.356ϵt−1+0.218ϵt−2−0.142ϵt−3
-
预测显示销量在第21周达到峰值75.823千件,之后逐渐下降
-
残差图显示误差随机分布,说明模型拟合较好
MA模型使用要点总结
-
适用场景:
- 时间序列受外部随机冲击影响明显
- 冲击的影响具有短期记忆性
- 序列平稳或已进行差分处理
-
模型选择:
- 观察ACF图:如果ACF在滞后q处突然截断,适合MA(q)模型
- 使用信息准则(AIC、BIC)比较不同阶数的模型
-
参数解释:
- 常数项μ:序列的长期平均水平
- MA系数θ:表示过去冲击对当前值的影响程度和方向
-
与AR模型的比较:
- AR模型:适合有内在持续性、惯性的序列
- MA模型:适合受外部冲击影响明显的序列
- 实际中常使用ARMA模型结合两者优点
为了更好理解,MA模型和您之前了解的AR模型有根本不同:
与AR模型的根本区别:
*AR(p
):X_t
依赖于X_(t-1)
,X_(t-2)
, …,X_(t-p)
(自身过去值)。
*MA(q
):X_t
依赖于ε_t
,ε_(t-1)
,ε_(t-2)
, …,ε_(t-q)
(过去和现在的随机冲击)。
特点 | AR§ 模型 | MA(q) 模型 |
---|---|---|
核心依赖 | 依赖于 自身过去的观测值 (X_(t-k) ) | 依赖于 过去和现在的随机冲击 (ε_(t-k) ) |
模型公式 | X_t = c + φ₁X_(t-1) + ... + φ_pX_(t-p) + ε_t | X_t = μ + ε_t + θ₁ε_(t-1) + ... + θ_qε_(t-q) |
ACF图 | 拖尾 (缓慢指数衰减或震荡衰减) | 截尾 (滞后 q 期后急剧降至不显著) |
PACF图 | 截尾 (滞后 p 期后急剧降至不显著) | 拖尾 (缓慢衰减) |
预测依赖 | 依赖已知的 最近 p 个历史观测值 | 依赖估计出的 最近 q 个冲击项 (残差) |
长期预测 | 收敛到 均值 (可能较慢) | 收敛到 均值 μ (当 k > q 时立即收敛) |
擅长捕捉 | 持续性、趋势性 | 突发冲击、短期波动、短暂效应 |
- 注意事项:
- 确保时间序列是平稳的
- MA模型对初始值敏感,需要足够的数据量
- 高阶MA模型可能过拟合,需用信息准则评估
通过这三个案例,你可以看到MA模型如何捕捉外部冲击对时间序列的影响。在实际应用中,通常会将AR和MA模型结合为ARMA模型,以获得更好的预测效果。