时间序列预测之移动平均法预测模型
1. 时间序列预测法概述
时间序列,也称为时间数列、历史复数或动态数列。
它是将某种统计的指标数值按照时间先后顺序排列所形成的数列。根据时间序列所反映出来的发展过程、方向和趋势,进行类推和延伸,来预测下一时间或若干年以后达到的水平。
时间序列预测其实是一种回归预测方法,属于定量预测。主要有移动平均预测法、指数平滑预测法、趋势性指数平滑法。
1.1 时间序列的基本特征
时间序列一般包含两个要素:一是现象所属的时间,二是这些时间所对应的统计指标数值。因此在对某现象进行统计研究时,把所需研究现象在不同时间上发展变化的一系列同类统计指标数值,按照时间的先后顺序排列起来,就形成了时间序列。排列的时间可以是年份、季度、月份或其他任何时间形式。
1.2 时间序列的分类
-
时间序列按是否平稳可以分为平稳性时间序列和非平稳性时间序列。
平稳性时间序列是指其序列只存在随机波动,不存在明显的持续上升或下降的趋势,并且波动的幅度在不同的时间也没有明显的差异。反之,若时间序列存在明显的持续上升或下降趋势,或者波动幅度在不同的时间存在明显的差异,就是非平稳性时间序列。 -
时间序列按照其表现形式可以分为绝对数时间序列、相对数时间序列和平均数时间序列。
绝对数时间序列是把某种指标数值用绝对数表示,按照时间顺序排列而成的序列。它又可细分为时期序列和时点序列。- 时期序列是指总量指标反映社会经济现象在一段时间内的发展过程的总量的时间序列,其特点是各时间上的同一指标数值可以累计相加,相加之后的指标值表示更长一段时间现象发生的总量。
- 时点序列则是反映某一时刻上所处的状态或水平,其指标不可相加,相加的指标没有实际意义。
相对数时间序列是把相对指标在时间上按照先后顺序排列起来,用来反映社会经济现象之间相互关系的发展过程。
平均数时间序列是把平均指标在不同时间上的数值按时间先后顺序排列,用来反映社会经济现象总体一般水平的发展趋势。
1.3 时间序列的影响因素分析
时间序列反映了社会经济现象随时间的发展变化,而影响现象的变动因素是多方面的,既有长期作用的基本因素,也有短期或偶然起作用的偶然因素。根据它们的性质和作用不同,归纳起来将它们分为以下四类。
- 长期趋势
长期趋势是指经济现象由于受到某些决定性因素的作用,在一段较长时期内呈现持续向上增长或向下降低的态势,也称趋势,一般记为 T T T。 - 季节变动
季节变动是指受到自然条件、社会风俗习惯等原因的影响,某些社会经济现象表现出随着季节的更换呈现有规律的变动,记为 S S S。 - 循环变动
循环变动是指经济现象发生周期在一年以上,出现涨落起伏有规律的商业景气循环,也称周期运动,记为 C C C。 - 不规则变动
不规则变动是指社会经济现象除了受上述因素变动的影响之外,还受到临时、偶然因素或突发、不明因素影响而呈现的无规律性的变动,记为 I I I。
以上四类因素对现象变动的影响,可分为两种分析模型。一种是当各因素彼此相互独立时,时间序列观察值可以看成是四因素相加的结果:𝑌=𝑇+𝑆+𝐶+𝐼,即加法模式。
另一种是当因素间互相影响时,其时间序列模型为: 𝑌=𝑇×𝑆×𝐶×𝐼,即乘法模式。
时间序列分析可以反映现象在不同时间上的规模和水平,反映社会经济现象发展变化的过程和趋势。通过随时间序列的趋势进行分析,可以探索某些社会经济现象发展变化的规律性。根据时间序列的特点,构建数学模型,预测未来。因此,研究时间序列具有重要的作用。
2 移动平均数预测模型
时间序列预测法可用于短期预测、中期预测和长期预测。根据对资料分析方法的不同,又可分为:移动平均数法、趋势预测法、指数平滑法、季节性趋势预测法、市场寿命周期预测法等。
移动平均法(Moving Average Method)是根据时间序列,逐项推移,依次计算包含一定项数的时序平均数,以此进行预测的方法。
例如,原有材料单价
a
1
a_1
a1元、数量
b
1
b_1
b1,一次购入原材料实际单价
a
2
a_2
a2元、数量
b
2
b_2
b2,计算成本单价则为:
(
a
1
∗
b
1
+
a
2
∗
b
2
)
/
(
b
1
+
b
2
)
(a_1*b_1+a_2*b_2)/(b_1+b_2)
(a1∗b1+a2∗b2)/(b1+b2)。类似地,如果期间又要购入原材料,则成本单价是上次总额与现购的总额再求一次单价。
这可以看作是一个移动的过程,所以叫移动平均法。
移动平均法是用一组最近的实际数据值来预测未来一期或几期内公司产品的需求量、公司产能等的一种常用方法。移动平均法适用于近期预测,当产品需求既不快速增长也不快速下降,且不存在季节性因素时,移动平均法能有效地消除预测中的随机波动,是非常有用的。
2.1 一次移动平均法
一次移动平均法是在算术平均法的基础上加以改进,其基本思想是每次取一定数量周期的数据平均,按时间顺序逐次推进。每推进一个周期,舍去前一个周期的数据,增加一个新周期的数据,再进行平均。一次移动平均法一般只应用于一个时期后的预测(即预测第
t
+
1
t+1
t+1期)。一次移动平均法预测模型:
Y
t
+
1
=
M
t
(
1
)
Y_{t+1}=M_t^{(1)}
Yt+1=Mt(1)
其中
M
t
(
1
)
M_t^{(1)}
Mt(1)表示第t期一次移动平均值,
M
t
(
1
)
=
y
t
+
y
t
−
1
+
.
.
.
+
y
t
−
N
+
1
N
M_t^{(1)}=\frac{y_t+y_{t-1}+...+y_{t-N+1}}{N}
Mt(1)=Nyt+yt−1+...+yt−N+1,
N
N
N为计算移动平均值时所选定的数据个数。一般情况下,
N
N
N越大,均匀的程度越强,波动也越小;
N
N
N越小,对变化趋势反应越灵敏,均匀的程度越差。实际预测中可以利用试算法,即选择几个
N
N
N值进行计算,比较它们的预测误差,从中选择使误差较小的
N
N
N值。
2.2 二次移动平均法
当序列具有线性增长的发展趋势时,用一次移动平均预测会出现滞后偏差,表现为对于线性增长的时间序列预测值偏低。这时,可进行二次移动平均计算,二次移动平均就是将一次移动平均再进行一次移动平均来建立线性趋势模型。二次移动平均法的线性趋势预测模型为:
y
t
+
τ
=
a
t
+
b
^
t
τ
y_{t+\tau}=a_t+\hat{b}_t\tau
yt+τ=at+b^tτ
其中截距为
a
^
t
=
2
M
t
(
1
)
−
M
t
(
2
)
\hat{a}_t=2M_t^{(1)} -M_t^{(2)}
a^t=2Mt(1)−Mt(2) ,斜率
b
^
t
=
2
N
−
1
(
M
t
(
1
)
−
M
t
(
2
)
)
\hat{b}_t=\frac{2}{N-1}(M_t^{(1)} -M_t^{(2)})
b^t=N−12(Mt(1)−Mt(2)),
τ
\tau
τ为超前期预测。
M
t
(
1
)
M_t^{(1)}
Mt(1)为一次移动平均数,
M
t
(
2
)
M_t^{(2)}
Mt(2)表示第
t
t
t期二次移动平均值。二次移动平均法有多期预测能力,短期预测效果较好,操作简单但不能应付突发事件。
确定移动数据个数N的多少对这种预测的影响很大,应根据未来趋势与过去的关系确定。
移动平均预测模型中移动平均数N的选择为:期数越多,对均匀处理的作用越大,趋势就越平滑;反之则反映波动灵敏,一般来说,当时间序列的变化趋势较为稳定时,N可以取大些;当时间序列波动较大,变化明显时,N可以取小些。从理论上说,它应与循环变动或季节变动周期吻合,这样可以消除循环变动和季节变动的影响。实际预测中可以利用试算法,即选择几个N值进行计算,比较它们的预测误差,从中选择使误差较小的N值。
例:某公司2015-2023年营业收入数据如表第二栏所示,试用二次移动平均法预测2024年及之后两年的营业收入,(N=3)。
年份 | 营业收入 | 一次移动均值 | 二次移动均值 |
---|---|---|---|
2015 | 820 | — | — |
2016 | 950 | — | — |
2017 | 1140 | 970 | — |
2018 | 1380 | 1156.67 | — |
2019 | 1510 | 1343.33 | 1156.67 |
2020 | 1740 | 1543.33 | 1347.78 |
2021 | 1920 | 1723.33 | 1536.67 |
2022 | 2130 | 1930 | 1732.22 |
2023 | 2410 | 2153.33 | 1935.55 |
从数据的观察值判断,该时间序列近似值呈直线上升趋势,可用二次移动平均法预测。为了提高灵敏度取N=3。计算一次平均移动平均值和二次移动平均值如表所示,参数的计算如下:
a
^
t
=
2
M
t
(
1
)
−
M
t
(
2
)
=
2
∗
2153.33
−
1935.55
=
2371.11
\hat{a}_t=2M_t^{(1)} -M_t^{(2)}=2∗2153.33−1935.55=2371.11
a^t=2Mt(1)−Mt(2)=2∗2153.33−1935.55=2371.11
b
^
t
=
2
N
−
1
(
M
t
(
1
)
−
M
t
(
2
)
)
=
2
3
−
1
(
2153.33
−
1935.55
)
=
217.78
\hat{b}_t=\frac{2}{N-1}(M_t^{(1)} -M_t^{(2)})=\frac{2}{3-1}(2153.33 -1935.55)=217.78
b^t=N−12(Mt(1)−Mt(2))=3−12(2153.33−1935.55)=217.78
根据
y
t
+
τ
=
a
t
+
b
^
t
τ
y_{t+\tau}=a_t+\hat{b}_t\tau
yt+τ=at+b^tτ 模型,预测公式为:
y
^
t
+
τ
=
2371.11
+
217.78
τ
\hat y_{t+\tau}=2371.11+217.78\tau
y^t+τ=2371.11+217.78τ ,
设2024年
τ
=
1
\tau=1
τ=1,2025年
τ
=
2
\tau=2
τ=2,2026年
τ
=
3
\tau=3
τ=3,则预测值分别为:
y
^
2024
=
2371.11
+
217.78
∗
1
=
2588.89
y
^
2025
=
2371.11
+
217.78
∗
2
=
2806.67
y
^
2026
=
2371.11
+
217.78
∗
3
=
3024.45
\hat y_{2024}=2371.11+217.78*1=2588.89\\ \hat y_{2025}=2371.11+217.78*2=2806.67\\ \hat y_{2026}=2371.11+217.78*3=3024.45
y^2024=2371.11+217.78∗1=2588.89y^2025=2371.11+217.78∗2=2806.67y^2026=2371.11+217.78∗3=3024.45
2.3 基于Python的移动平均法预测模型
使用Python编程实现移动平均法预测模型,并对上例进行求解,结果如下:
import pandas as pd
import numpy as np
import math
#计算[n,m]区间内的count的平均值
def avergae_n_m(data, n, m):
sum = 0;
for i in range(m - n):
sum += data[i + n]
return round(sum / (m - n))
def one_moving_average(data, N): #一次移动平均
#第一个参数是表格数据,第二个参数是 N 跨度的取值
if N > len(data):
return "N 的取值大于数据的数量"
M = [] # 定义 M 来记录预测计算结果
for i in range(len(data) - N):
m = avergae_n_m(data, i, i + N)
M.append(m)
M.append(avergae_n_m(data, len(data) - N, len(data))) #预测值
return M
def standard_deviation(data, M, N): # 一次移动平均 计算标准差
# 第一个参数是表格数据,第二个是预测计算的数据,第三个是 N 跨度的取值
sum = 0
for i in range(len(M) - 1):
sum += (pow(M[i] - data[i + N], 2))
# print("standard_deviation")
S = int(math.sqrt((sum) / (len(M) - 1)))
print("N 为",N ,"时,标准差为:", S)
def two_moving_average(data, N, T=1): # 二次移动平均
M1 = one_moving_average(data, N)
M2 = one_moving_average(M1, N)
a = 2 * M1[len(M1) - 1] - M2[len(M2) - 1]
b = (2 / (N - 1)) * (M1[len(M1) - 1] - M2[len(M2) - 1]) #计算b
print("a:", a, "b:", b)
X = a + b * T #计算 X (预测值)
print("N 为", N, ",T为",T,"时,二次移动平均法预测值:", X)
def one_exponential_smoothing(data, a): # 一次指数平滑法
#第一个参数是表格数据,第二个参数是 a 分析加权系数
S = []
if len(data) > 50: #初始值的计算s
s = round(data[0], 1)
elif len(data) < 3:
s = round(data[0], 1)
else:
s = round((data[0] + data[1] + data[2]) / 3, 1)
S.append(s)
s_flag = s
for i in range(len(data)):
s_now = round(a * data[i] + (1 - a) * s_flag, 1)
s_flag = s_now
S.append(s_now)
return S
def two_exponential_smoothing(data, a): #二次指数平滑法
M1 = one_exponential_smoothing(data, a)
M2 = one_exponential_smoothing(M1, a)
A = round(2 * M1[len(M1) - 1] - M2[len(M2) - 1], 1) #计算a
b = round((a/(1-a))*(M1[len(M1)-1]-M2[len(M2)-1]),1) #计算b
print("a:", A, "b:", b)
T = 1 #计算T
X = A + b * T #计算 X(预测值)
print("a 为", a, "时,二次指数平滑法预测值:", X)
if __name__ == '__main__':
data =[820,950,1140,1380,1510,1740,1920,2130,2410] #读取数据
for i in range(1,4): #二次移动平均法
two_moving_average(data, 3, i)
a: 2371 b: 218.0
N 为 3 ,T为 1 时,二次移动平均法预测值: 2589.0
a: 2371 b: 218.0
N 为 3 ,T为 2 时,二次移动平均法预测值: 2807.0
a: 2371 b: 218.0
N 为 3 ,T为 3 时,二次移动平均法预测值: 3025.0