前言
按照时间排下来的序列,如果比较长的话(数据体量大),
一下子看不出什么规律,此时我们就需要用到本篇章的建模方法了。
当然预测模型可以按照以下学习路径
机器学习(多层感知机、卷积) => 时间序列(LSTM、RNN等)
1 时间序列的基本概念
基本概念
顾名思义就是有时间性的序列
典型特征
数据有一个时间列作为索引
(这个时间表示的是一个先后关系)
典型应用
时间序列的建模
参数学习:通过模型参数分析这个序列的特征,
从而基于“领域知识”分析序列特点,挖掘出一些有意思的点子
预测:“预测周期”&“预测精度”是一对冲突概念,
如果想要精准预测那么预测周期不能够太长。
- 对天气预报而言,我可以基于历史天气预报未来24小时内的天气情况,并且用序列建模方法可以预测得比较精准;
- 对股票而言,我可以基于其一个月内的股价预测其接下来一周的股价变化。
时间序列的描述
时间序列 Y
鼠标右键 -> 在新标签页中打开图像
2 移动平均法与指数平滑法
移动平均法
鼠标右键 -> 在新标签页中打开图像
if 预测目标的基本趋势在某一个水平上下浮动,
趋势线是一条水平线而非斜线跟非曲线时
- 使用一次移动平均方法
if 预测目标类似于一个线性模型
(也就是趋势线是一条一次函数)
- 使用二次移动平均方法
if 预测目标的基本趋势呈周期加线性
- 使用趋势移动平均方法
N 的取值:
意味着我们计算了一个窗口长度为 N 的移动平均。
具体来说,对于每个数据点,移动平均值是该点之前(包括该点)最近的 N 个数据点的平均值。
时间序列中如果应用移动平均,
预测序列的数据量会少一个窗口长度
指数平滑法
鼠标右键 -> 在新标签页中打开图像
针对没有趋势 T 和季节性 S 的序列
- 使用一次指数平滑法
针对有趋势 T 但没有季节性 S 的序列
- 使用二次指数平滑法
针对有趋势 T 也有季节性 S 的序列
- 使用三次指数平滑法
时间序列中如果应用指数平滑,
趋势线的长度和原始序列的长度是对齐的
3 ARIMA系列模型
鼠标右键 -> 在新标签页中打开图像
自回归(AR)模型
差分模型
移动平均(MA)模型
AIC准则(赤池信息准则)
贝叶斯信息准则
4 GARCH系列模型
鼠标右键 -> 在新标签页中打开图像
5 灰色系统模型
灰色预测模型
鼠标右键 -> 在新标签页中打开图像
级比检验
累加生成
构建数据矩阵 B 和数据向量 Y
参数估计
使用最小二乘法估计GM(1,1)微分方程的参数 a 和 b
(通过求解正规方程实现)
模型建立
建立灰色预测模型,计算拟合序列
精度检验
- 后验差比值(C):
计算残差方差与历史数据方差的比值,
用来衡量模型的预测能力。 - 小误差概率 (P):
计算误差小于标准误差的点的比例,
用于评估模型的可靠性。
预测生成
- if 模型精度满足条件
(后验差比值 C < 0.35 和小误差概率 P > 0.95),
则认为预测精度达到一级 - if 模型精度不满足条件
则认为灰色预测模型不适用
Python 案例代码
代码
import numpy as np
import math
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei','Songti SC','STFangsong'] # 用来正常显示中文
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.style.use("ggplot") #风格使用ggplot
history_data = [724.57,746.62,778.27,800.8,827.75,871.1,912.37,954.28,995.01,1037.2]
# 定义 GM(1,1) 预测函数
def GM11(history_data,forcast_steps):
n = len(history_data) # 确定历史数据体量
X0 = np.array(history_data) # 向量化(将历史数据转换成numpy数组)
# 级比检验,检查级比是否在合理范围内,确保数据适合使用GM(1,1)模型
lambda0=np.zeros(n-1)
for i in range(n-1):
if history_data[i]:
lambda0[i]=history_data[i+1]/history_data[i]
if lambda0[i]<np.exp(-2/(n+1)) or lambda0[i]>np.exp(2/n+2):
print("GM11模型失效")
return -1
# 累加生成,将原数据序列转换成累加序列
history_data_agg = [sum(history_data[0:i+1]) for i in range(n)]
X1 = np.array(history_data_agg)
# 构造 数据矩阵B和数据向量Y
B = np.zeros([n-1,2])
Y = np.zeros([n-1,1])
for i in range(0,n-1):
B[i][0] = -0.5*(X1[i] + X1[i+1]) # B矩阵的第1列:序列均值化
B[i][1] = 1 # B矩阵的第2列:全为1
Y[i][0] = X0[i+1] # Y向量由原数据序列的后n-1项构成
# 参数估计:求解最小二乘法得到GM(1,1)微分方程的参数a和b
A = np.linalg.inv(B.T.dot(B)).dot(B.T).dot(Y) # 计算参数向量A
a = A[0][0] # 得到参数a
b = A[1][0] # 得到参数b
# 建立灰色预测模型,计算拟合序列XX0
XX0 = np.zeros(n)
XX0[0] = X0[0]
for i in range(1,n):
XX0[i] = (X0[0] - b/a)*(1-math.exp(a))*math.exp(-a*(i)) # 计算拟合序列
# 后验差比值 (C)
e=sum(X0-XX0)/n
aver=sum(X0)/n #求历史数据平均值
s12=sum((X0-aver)**2)/n #求历史数据方差
s22=sum(((X0-XX0)-e)**2)/n #求残差方差
C = s22 / s12
# 小误差概率 (P)
cobt = 0
for i in range(0,n):
if abs((X0[i] - XX0[i]) - e) < 0.6754*math.sqrt(s12): # 判断误差是否小于标准误差
cobt = cobt+1 # 计数小误差数量
else:
cobt = cobt
P = cobt / n # 计算小误差概率
# 精度检验&预测生成
f = np.zeros(forcast_steps)
if (C < 0.35 and P > 0.95): # 如果模型精度满足条件
#预测精度为一级
print('往后各年预测值为:')
for i in range(0,forcast_steps):
f[i] = (X0[0] - b/a)*(1-math.exp(a))*math.exp(-a*(i+n)) # 计算未来预测值
print(f)
else:
print('灰色预测法不适用')
return f
# 执行预测,预测未来20年的数据
f=GM11(history_data,20)
# 绘制预测结果和历史数据
plt.plot(range(11,31),f) # 绘制预测数据
plt.plot(range(1,11),history_data) # 绘制历史数据
plt.show()
回显
往后各年预测值为:
[1079.38044724 1125.65457636 1173.91252409 1224.23933874 1276.72371473
1331.45814889 1388.53910348 1448.0671762 1510.14727748 1574.88881535
1642.40588828 1712.81748628 1786.24770054 1862.8259422 1942.68717036
2025.97212997 2112.82759985 2203.40665138 2297.86891827 2396.38087787]
Read more
- 数学建模导论 intro-mathmodel
(知识密度大、代码理论兼备)
https://datawhalechina.github.io/intro-mathmodel/#/ - Python科学计算 scientific-computing(数学建模导论的前置课程)
(知识密度小、代码实操强悍)
https://datawhalechina.github.io/scientific-computing/#/