【数学建模笔记 24】数学建模的时间序列模型

2023-11-19

24. 时间序列模型

定义

时间序列是按时间顺序排列的、随时间变化且相互关联的数据序列。分析时间序列的方法构成数据分析的一个重要领域,即时间序列分析。

一个时间序列往往是以下几类变化形式的叠加。

  • 长期趋势变动 T t T_t Tt:朝一定方向的变化趋势;
  • 季节变动 S t S_t St
  • 循环变动 C t C_t Ct:周期一年以上,由非季节因素引起的涨落起伏波形相似的波动;
  • 不规则变动 R t R_t Rt

常见的确定性时间序列模型有

  • 加法模型 y t = T t + S t + C t + R t y_t=T_t+S_t+C_t+R_t yt=Tt+St+Ct+Rt​;
  • 乘法模型 y t = T t ⋅ S t ⋅ C t ⋅ R t y_t=T_t\cdot S_t\cdot C_t\cdot R_t yt=TtStCtRt​;
  • 混合模型。

其中 y t y_t yt 是目标的观测记录, E ( R t ) = 0 , E ( R t 2 ) = σ 2 E(R_t)=0,E(R_t^2)=\sigma^2 E(Rt)=0,E(Rt2)=σ2

移动平均法

当时间序列由于受周期变动和不规则变动的影响,起伏较大,不易显示出发展趋势时,可用移动平均法消除这些因素的影响。

简单移动平均法

设观测序列为 y 1 , … , y T y_1,\dots,y_T y1,,yT,取移动平均项数 N < T N<T N<T,一次简单移动平均值计算公式为
M t ( 1 ) = 1 N ( y t + y t − 1 + ⋯ + y t − N + 1 ) M_t^{(1)}=\frac1N(y_t+y_{t-1}+\dots+y_{t-N+1}) Mt(1)=N1(yt+yt1++ytN+1)

= M t − 1 ( 1 ) + 1 N ( y t − t t − N ) . =M_{t-1}^{(1)}+\frac1N(y_t-t_{t-N}). =Mt1(1)+N1(ytttN).

y ^ t + 1 = M t ( 1 ) \hat{y}_{t+1}=M_t^{(1)} y^t+1=Mt(1),得到预测模型,并有误差
S = ∑ t = N + 1 T ( y ^ t − y t ) 2 T − N . S=\sqrt{\frac{\sum_{t=N+1}^T(\hat{y}_t-y_t)^2}{T-N}}. S=TNt=N+1T(y^tyt)2 .

加权移动平均法

设时间序列为 y 1 , … , y t , … y_1,\dots,y_t,\dots y1,,yt,,加权移动平均公式为
M t w = w 1 y t + w 2 y 2 + ⋯ + w N y t − n + 1 w 1 + w 2 + ⋯ + w N , t ≥ N , M_{tw}=\frac{w_1y_t+w_2y_2+\dots+w_Ny_{t-n+1}}{w_1+w_2+\dots+w_N},t\ge N, Mtw=w1+w2++wNw1yt+w2y2++wNytn+1,tN,
其中 M t w M_{tw} Mtw t t t 期加权移动平均数, w i w_i wi y t − i + 1 y_{t-i+1} yti+1 的权数,得预测公式
y ^ t + 1 = M t w . \hat{y}_{t+1}=M_{tw}. y^t+1=Mtw.

趋势移动平均法

一次移动得平均数为
M t ( 1 ) = 1 N ( y t + y t − 1 + ⋯ + y t − N + 1 ) , M_t^{(1)}=\frac1N(y_t+y_{t-1}+\dots+y_{t-N+1}), Mt(1)=N1(yt+yt1++ytN+1),
在一次移动平均的基础上再进行一次移动平均,就是二次移动平均,计算公式为
M t ( 2 ) = 1 N ( M t ( 1 ) + ⋯ + M t − N + 1 ( 1 ) ) M_t^{(2)}=\frac1N(M_t^{(1)}+\dots+M_{t-N+1}^{(1)}) Mt(2)=N1(Mt(1)++MtN+1(1))

= M t − 1 ( 2 ) + 1 N ( M t ( 1 ) − M t − N ( 1 ) ) . =M_{t-1}^{(2)}+\frac1N(M_t^{(1)}-M_{t-N}^{(1)}). =Mt1(2)+N1(Mt(1)MtN(1)).

设时间序列某时期开始具有直线趋势,则设
y ^ t + T = a t + b t T , T = 1 , 2 , … \hat{y}_{t+T}=a_t+b_tT,T=1,2,\dots y^t+T=at+btT,T=1,2,
则有
a t = y t , y t − 1 = y t − b t , y t − 2 = y t − 2 b t , a_t=y_t,y_{t-1}=y_t-b_t,y_{t-2}=y_t-2b_t, at=yt,yt1=ytbt,yt2=yt2bt,

… \dots

y t − N + 1 = y t − ( N − 1 ) b t . y_{t-N+1}=y_t-(N-1)b_t. ytN+1=yt(N1)bt.


M t ( 1 ) = N y t − [ 1 + ⋯ + ( N − 1 ) b t ] N M_t^{(1)}=\frac{Ny_t-[1+\dots+(N-1)b_t]}{N} Mt(1)=NNyt[1++(N1)bt]

= y t − N − 1 2 b t . =y_t-\frac{N-1}{2}b_t. =yt2N1bt.


y t − M t ( 1 ) = N − 1 2 b t , y_t-M_t^{(1)}=\frac{N-1}{2}b_t, ytMt(1)=2N1bt,
同理有
y t − 1 − M t − 1 ( 1 ) = N − 1 2 b t − 1 , y_{t-1}-M_{t-1}^{(1)}=\frac{N-1}{2}b_{t-1}, yt1Mt1(1)=2N1bt1,

y t − y t − 1 = M t ( 1 ) − M t − 1 ( 1 ) = b t , y_t-y_{t-1}=M_t^{(1)}-M_{t-1}^{(1)}=b_t, ytyt1=Mt(1)Mt1(1)=bt,
同理有
M t ( 1 ) − M t ( 2 ) = N − 1 2 b t , M_t^{(1)}-M_t^{(2)}=\frac{N-1}{2}b_t, Mt(1)Mt(2)=2N1bt,
于是有
{ a t = 2 M t ( 1 ) − M t ( 2 ) , b t = 2 N − 1 ( M t ( 1 ) − M t ( 2 ) ) . \left\{\begin{aligned} &a_t=2M_t^{(1)}-M_t^{(2)},\\ &b_t=\frac{2}{N-1}(M_t^{(1)}-M_t^{(2)}). \end{aligned}\right. at=2Mt(1)Mt(2),bt=N12(Mt(1)Mt(2)).
一次移动平均实际上认为最近 N 期数据对未来影响相同,而 N 期以前的数据对未来没有影响。高阶移动平均则认为两端项权数小,中间项权数大,是对称的。

指数平滑法

一般说来,历史数据对未来的影响是递减的,指数平滑法可满足这一要求。

一次指数平滑法

设时间序列 y 1 , y 2 , … , y t y_1,y_2,\dots,y_t y1,y2,,yt α \alpha α 为加权系数,一次指数平滑公式为
S t ( 1 ) = α y t + ( 1 − α ) S t − 1 ( 1 ) S_t^{(1)}=\alpha y_t+(1-\alpha)S_{t-1}^{(1)} St(1)=αyt+(1α)St1(1)

= S t − 1 ( 1 ) + α ( y t − S t − 1 ( 1 ) ) . =S_{t-1}^{(1)}+\alpha(y_t-S_{t-1}^{(1)}). =St1(1)+α(ytSt1(1)).

将式展开,有
S t ( 1 ) = α y t + ( 1 − α ) [ α y t − 1 + ( 1 − α ) S t − 2 ( 1 ) ] S_t^{(1)}=\alpha y_t+(1-\alpha)[\alpha y_{t-1}+(1-\alpha)S_{t-2}^{(1)}] St(1)=αyt+(1α)[αyt1+(1α)St2(1)]

= ⋯ = α ∑ j = 0 ∞ ( 1 − α ) j y t − j . =\dots=\alpha\sum_{j=0}^{\infty}(1-\alpha)^jy_{t-j}. ==αj=0(1α)jytj.

表明 S t ( 1 ) S_t^{(1)} St(1) 是全部历史数据的加权平均,系数分别为 α , α ( 1 − α ) , α ( 1 − α ) 2 , … \alpha,\alpha(1-\alpha),\alpha(1-\alpha)^2,\dots α,α(1α),α(1α)2,,符合指数规律。

有预测模型
y ^ t + 1 = S t ( 1 ) = α y t + ( 1 − α ) y ^ t . \hat{y}_{t+1}=S_t^{(1)}=\alpha y_t+(1-\alpha)\hat{y}_t. y^t+1=St(1)=αyt+(1α)y^t.

二次指数平滑法

一次指数平滑法存在明显的滞后偏差,可以再作二次指数平滑,有
S t ( 1 ) = α y t + ( 1 − α ) S t − 1 ( 1 ) , S_t^{(1)}=\alpha y_t+(1-\alpha)S_{t-1}^{(1)}, St(1)=αyt+(1α)St1(1),

S t ( 2 ) = α S t ( 1 ) + ( 1 − α ) S t − 1 ( 2 ) . S_t^{(2)}=\alpha S_t^{(1)}+(1-\alpha)S_{t-1}^{(2)}. St(2)=αSt(1)+(1α)St1(2).

设时间序列从某时期开始具有直线趋势,可得
y ^ t + T = a t + b t T , T = 1 , 2 , … \hat{y}_{t+T}=a_t+b_tT,T=1,2,\dots y^t+T=at+btT,T=1,2,

{ a t = 2 S t ( 1 ) − S t ( 2 ) , b t = α 1 − α ( S t ( 1 ) − S t ( 2 ) ) . \left\{\begin{aligned} &a_t=2S_t^{(1)}-S_t^{(2)},\\ &b_t=\frac{\alpha}{1-\alpha}(S_t^{(1)}-S_t^{(2)}). \end{aligned}\right. at=2St(1)St(2),bt=1αα(St(1)St(2)).

三次指数平滑法

时间序列变动表现为二次曲线趋势时,需要用三次指数平滑法,即
S t ( 1 ) = α y t + ( 1 − α ) S t − 1 ( 1 ) , S_t^{(1)}=\alpha y_t+(1-\alpha)S_{t-1}^{(1)}, St(1)=αyt+(1α)St1(1),

S t ( 2 ) = α S t ( 1 ) + ( 1 − α ) S t − 1 ( 2 ) . S_t^{(2)}=\alpha S_t^{(1)}+(1-\alpha)S_{t-1}^{(2)}. St(2)=αSt(1)+(1α)St1(2).

S t ( 3 ) = α S t ( 2 ) + ( 1 − α ) S t − 1 ( 3 ) . S_t^{(3)}=\alpha S_t^{(2)}+(1-\alpha)S_{t-1}^{(3)}. St(3)=αSt(2)+(1α)St1(3).

预测模型为
y ^ t + T = a t + b t T + C t T 2 , T = 1 , 2 , … \hat{y}_{t+T}=a_t+b_tT+C_tT^2,T=1,2,\dots y^t+T=at+btT+CtT2,T=1,2,

{ a t = 3 S t ( 1 ) − 3 S t ( 2 ) + S t ( 3 ) , b t = α 2 ( 1 − α ) 2 [ ( 6 − 5 α ) S t ( 1 )     − 2 ( 5 − 4 α ) S t ( 2 ) + ( 4 − 3 α ) S t ( 3 ) ] , c t = α 2 2 ( 1 − α ) 2 [ S t ( 1 ) − 2 S t ( 2 ) + S t ( 3 ) ] . \left\{\begin{aligned} &a_t=3S_t^{(1)}-3S_t^{(2)}+S_t^{(3)},\\ &b_t=\frac{\alpha}{2(1-\alpha)^2}[(6-5\alpha)S_t^{(1)}\\ &\ \ \ -2(5-4\alpha)S_t^{(2)}+(4-3\alpha)S_t^{(3)}],\\ &c_t=\frac{\alpha^2}{2(1-\alpha)^2}[S_t^{(1)}-2S_t^{(2)}+S_t^{(3)}]. \end{aligned}\right. at=3St(1)3St(2)+St(3),bt=2(1α)2α[(65α)St(1)   2(54α)St(2)+(43α)St(3)],ct=2(1α)2α2[St(1)2St(2)+St(3)].

差分指数平滑法

当时间序列变动具有直线趋势时,用一次指数平滑法会出现滞后偏差。可以先对源数据进行差分,构成一个平稳的新序列 (消除直线趋势),再使用指数平滑法预测,再与变量当前实际值迭加作为预测值。
∇ y t = y t − y t − 1 , \nabla y_t=y_t-y_{t-1}, yt=ytyt1,

∇ y ^ t + 1 = α ∇ y t + ( 1 − α ) ∇ y ^ t , \nabla\hat{y}_{t+1}=\alpha\nabla y_t+(1-\alpha)\nabla\hat{y}_t, y^t+1=αyt+(1α)y^t,

y ^ t + 1 = ∇ y ^ t + 1 + y t . \hat{y}_{t+1}=\nabla\hat{y}_{t+1}+y_t. y^t+1=y^t+1+yt.

同样的,当时间序列呈现二次曲线增长时,可用二阶差分指数平滑模型预测
∇ y t = y t − y t − 1 , \nabla y_t=y_t-y_{t-1}, yt=ytyt1,

∇ 2 y t = ∇ y t − ∇ y t − 1 \nabla^2 y_t=\nabla y_t-\nabla y_{t-1} 2yt=ytyt1

∇ 2 y ^ t + 1 = α ∇ 2 y t + ( 1 − α ) ∇ 2 y ^ t , \nabla^2\hat{y}_{t+1}=\alpha\nabla^2y_t+(1-\alpha)\nabla^2\hat{y}_t, 2y^t+1=α2yt+(1α)2y^t,

y ^ t + 1 = ∇ 2 y ^ t + 1 + ∇ y t + y t . \hat{y}_{t+1}=\nabla^2\hat{y}_{t+1}+\nabla y_{t}+y_t. y^t+1=2y^t+1+yt+yt.

自适应滤波法

基本预测公式为
y ^ t + 1 = w 1 y t + w 2 y t − 1 + ⋯ + w N y t − N + 1 \hat{y}_{t+1}=w_1y_t+w_2y_{t-1}+\dots+w_Ny_{t-N+1} y^t+1=w1yt+w2yt1++wNytN+1

= ∑ i = 1 N w i y t − i + 1 . =\sum_{i=1}^Nw_iy_{t-i+1}. =i=1Nwiyti+1.

调整权数的公式为
w i = w i + 2 k ⋅ e i + 1 y t − i + 1 . w_i=w_i+2k\cdot e_{i+1}y_{t-i+1}. wi=wi+2kei+1yti+1.
其中 k k k 为学习常数, e i + 1 e_{i+1} ei+1 为第 t + 1 t+1 t+1 期预测误差。

步骤:

  1. 设定初始权数、学习常数和开始时期 t t t
  2. 根据预测公式计算 t + 1 t+1 t+1 期的预测值 y ^ t + 1 \hat{y}_{t+1} y^t+1
  3. 计算预测误差 e t + 1 = y t + 1 − y ^ t + 1 e_{t+1}=y_{t+1}-\hat{y}_{t+1} et+1=yt+1y^t+1
  4. 根据调整公式更新权数;
  5. t t t 进 1,回到步骤 2,直到 t t t 超出序列的最后一个时期,迭代结果。

季节性时间序列预测

使用季节系数法,步骤如下:

  1. 计算每年所有季度的算数平均值
    a ‾ = 1 k ∑ i = 1 m ∑ j = 1 n a i j , k = m n , \overline{a}=\frac1k\sum_{i=1}^m\sum_{j=1}^na_{ij},k=mn, a=k1i=1mj=1naij,k=mn,
    其中 i , j i,j i,j 分别表示年份、季度的序号;

  2. 计算同季度的算数平均值
    a ‾ ⋅ j = 1 m ∑ i = 1 m a i j , j = 1 , 2 , … , n , \overline{a}_{\cdot j}=\frac1m\sum_{i=1}^ma_{ij},j=1,2,\dots,n, aj=m1i=1maij,j=1,2,,n,

  3. 计算季度系数 b j = a ‾ ⋅ j / a ‾ b_j=\overline{a}_{\cdot j}/\overline{a} bj=aj/a​;

  4. 预测下一年的年加权平均
    y ‾ m + 1 = ∑ i = 1 m w i y i n ∑ i = 1 n w i , \overline{y}_{m+1}=\frac{\sum_{i=1}^mw_iy_i}{n\sum_{i=1}^nw_i}, ym+1=ni=1nwii=1mwiyi,

  5. 得到各季度的预测值
    y m + 1 , j = b j y ‾ m + 1 . y_{m+1,j}=b_j\overline{y}_{m+1}. ym+1,j=bjym+1.

ARMA 时间序列

设随机序列 { X t , t = 0 , ± 1 , ± 2 , …   } \{X_t,t=0,\pm1,\pm2,\dots\} {Xt,t=0,±1,±2,} 满足

  • E ( X t ) = μ = 常数 E(X_t)=\mu=\text{常数} E(Xt)=μ=常数​,
  • γ t + k , t = γ k \gamma_{t+k,t}=\gamma_k γt+k,t=γk t t t​ 无关,

则称 X t X_t Xt 为平稳序列。

ARMA 序列,即自回归移动平均序列,由两部分组成:

  • AR 序列

X t = ϕ 1 X t − 1 + ϕ 2 X t − 2 + ⋯ + ϕ p X t − p + ε t , X_t=\phi_1X_{t-1}+\phi_2X_{t-2}+\dots+\phi_pX_{t-p}+\varepsilon_t, Xt=ϕ1Xt1+ϕ2Xt2++ϕpXtp+εt,

其中 ε t \varepsilon_t εt 是均值为 0,方差为 σ ε 2 \sigma_{\varepsilon}^2 σε2 的平稳白噪声,称 X t X_t Xt 是阶数为 p p p 的自回归序列,记 A R ( p ) AR(p) AR(p)

  • MA 序列

X t = ε t − θ 1 ε t − 1 − θ 2 ε t − 2 − ⋯ − θ q ε t − q , X_t=\varepsilon_t-\theta_1\varepsilon_{t-1}-\theta_2\varepsilon_{t-2}-\dots-\theta_q\varepsilon_{t-q}, Xt=εtθ1εt1θ2εt2θqεtq,

其中 ε t \varepsilon_t εt 是均值为 0,方差为 σ ε 2 \sigma_{\varepsilon}^2 σε2 的平稳白噪声,称 X t X_t Xt 是阶数为 q q q 的移动平均序列,记 M A ( q ) MA(q) MA(q)

于是有
X t − ϕ 1 X t − 1 + ϕ 2 X t − 2 + ⋯ + ϕ p X t − p X_t-\phi_1X_{t-1}+\phi_2X_{t-2}+\dots+\phi_pX_{t-p} Xtϕ1Xt1+ϕ2Xt2++ϕpXtp

= ε t − θ 1 ε t − 1 − θ 2 ε t − 2 − ⋯ − θ q ε t − q , =\varepsilon_t-\theta_1\varepsilon_{t-1}-\theta_2\varepsilon_{t-2}-\dots-\theta_q\varepsilon_{t-q}, =εtθ1εt1θ2εt2θqεtq,

其中 ε t \varepsilon_t εt 是均值为 0,方差为 σ ε 2 \sigma_{\varepsilon}^2 σε2 的平稳白噪声,称 X t X_t Xt 是阶数为 p , q p,q p,q 的自回归移动平均序列,记 A R M A ( p , q ) ARMA(p,q) ARMA(p,q)

模型构建

AIC 准则:选 p , q p,q p,q 使得
min ⁡ A I C = n ln ⁡ σ ^ ε 2 + 2 ( p + q + 1 ) , \min AIC=n\ln\hat{\sigma}_{\varepsilon}^2+2(p+q+1), minAIC=nlnσ^ε2+2(p+q+1),
其中 n n n 是样本容量, σ ^ ε 2 \hat{\sigma}_{\varepsilon}^2 σ^ε2 σ ε 2 \sigma_{\varepsilon}^2 σε2 的估计值。​

参数估计

可以使用矩估计、最小二乘估计、最大似然估计等方法。

模型预测

X k + m X_{k+m} Xk+m 的估计量为 X ^ k ( m ) \hat{X}_k(m) X^k(m),对于 AR 序列
{ X ^ k ( 1 ) = ϕ 1 X k + ϕ 2 X k − 1 + ⋯ + ϕ p X k − p + 1 , X ^ k ( 2 ) = ϕ 1 X ^ k ( 1 ) + ϕ 2 X k + ⋯ + ϕ p X k − p + 2 , … X ^ k ( m ) = ϕ 1 X ^ k ( m − 1 ) + ϕ 2 X ^ k ( m − 2 ) + ⋯ + ϕ p X ^ ( m − p ) , m > p . \left\{\begin{aligned} &\hat{X}_k(1)=\phi_1X_k+\phi_2X_{k-1}+\dots+\phi_pX_{k-p+1},\\ &\hat{X}_k(2)=\phi_1\hat{X}_k(1)+\phi_2X_{k}+\dots+\phi_pX_{k-p+2},\\ &\dots\\ &\hat{X}_k(m)=\phi_1\hat{X}_k(m-1)+\phi_2\hat{X}_k(m-2)+\dots+\phi_p\hat{X}(m-p),m>p.\\ \end{aligned}\right. X^k(1)=ϕ1Xk+ϕ2Xk1++ϕpXkp+1,X^k(2)=ϕ1X^k(1)+ϕ2Xk++ϕpXkp+2,X^k(m)=ϕ1X^k(m1)+ϕ2X^k(m2)++ϕpX^(mp),m>p.
对于 MA 序列,有
{ X ^ k + 1 ( 1 ) = θ 1 X ^ k ( 1 ) + X ^ k ( 2 ) − θ 1 X k + 1 , X ^ k + 1 ( 2 ) = θ 2 X ^ k ( 1 ) + X ^ k ( 3 ) − θ 2 X k + 1 , … X ^ k + 1 ( q ) = θ q X ^ k ( 1 ) + X ^ k ( q ) − θ q X k + 1 . \left\{\begin{aligned} &\hat{X}_{k+1}(1)=\theta_1\hat{X}_k(1)+\hat{X}_k(2)-\theta_1X_{k+1},\\ &\hat{X}_{k+1}(2)=\theta_2\hat{X}_k(1)+\hat{X}_k(3)-\theta_2X_{k+1},\\ &\dots\\ &\hat{X}_{k+1}(q)=\theta_{q}\hat{X}_k(1)+\hat{X}_k(q)-\theta_{q}X_{k+1}.\\ \end{aligned}\right. X^k+1(1)=θ1X^k(1)+X^k(2)θ1Xk+1,X^k+1(2)=θ2X^k(1)+X^k(3)θ2Xk+1,X^k+1(q)=θqX^k(1)+X^k(q)θqXk+1.
X ^ k ( q ) = ( X ^ k ( 1 ) , … , X ^ k ( q ) ) T \hat{X}_k^{(q)}=(\hat{X}_k(1),\dots,\hat{X}_k(q))^T X^k(q)=(X^k(1),,X^k(q))T,得
X ^ k + 1 ( q ) = ( θ 1 1 0 … 0 θ 2 0 1 … 0 ⋮ ⋮ ⋱ ⋮ ⋮ θ q − 1 0 0 … 1 θ q 0 0 … 0 ) X ^ k ( q ) − ( θ 1 θ 2 ⋮ θ q ) X k + 1. \hat{X}_{k+1}^{(q)}=\begin{pmatrix} \theta_1&1&0&\dots&0\\ \theta_2&0&1&\dots&0\\ \vdots&\vdots&\ddots&\vdots&\vdots&\\ \theta_{q-1}&0&0&\dots&1\\ \theta_q&0&0&\dots&0\\ \end{pmatrix}\hat{X}_k^{(q)}-\begin{pmatrix} \theta_1\\ \theta_2\\ \vdots\\ \theta_q \end{pmatrix}X_{k+1.} X^k+1(q)=θ1θ2θq1θq100001000010X^k(q)θ1θ2θqXk+1.
可取初值 X ^ k 0 ( q ) = 0 \hat{X}_{k_0}^{(q)}=0 X^k0(q)=0​,当 n n n​ 充分大后,初始误差的影响逐渐消失。

因此对于 ARMA 序列,令
ϕ j ∗ = { ϕ j , j = 1 , 2 , … , p , 0 , j > p . \phi_j^*=\left\{\begin{aligned} &\phi_j,j=1,2,\dots,p,\\ &0,j>p. \end{aligned}\right. ϕj={ϕj,j=1,2,,p,0,j>p.
有递推式
X ^ k + 1 ( q ) = ( − G 1 1 0 … 0 − G 2 0 1 … 0 ⋮ ⋮ ⋱ ⋮ ⋮ − G q − 1 0 0 … 1 − G q + ϕ q ∗ ϕ q − 1 ∗ ϕ q − 2 ∗ … ϕ 1 ∗ ) X ^ k ( q ) \hat{X}_{k+1}^{(q)}=\begin{pmatrix} -G_1&1&0&\dots&0\\ -G_2&0&1&\dots&0\\ \vdots&\vdots&\ddots&\vdots&\vdots&\\ -G_{q-1}&0&0&\dots&1\\ -G_q+\phi_q^*&\phi_{q-1}^*&\phi_{q-2}^*&\dots&\phi_1^*\\ \end{pmatrix}\hat{X}_k^{(q)} X^k+1(q)=G1G2Gq1Gq+ϕq100ϕq1010ϕq2001ϕ1X^k(q)

+ ( G 1 G 2 ⋮ G q ) X k + 1 + ( 0 0 ⋮ ∑ j = q + 1 p ϕ j ∗ X k + q + 1 − j ) . +\begin{pmatrix} G_1\\ G_2\\ \vdots\\ G_q \end{pmatrix}X_{k+1}+\begin{pmatrix} 0\\ 0\\ \vdots\\ \sum_{j=q+1}^p\phi_j^*X_{k+q+1-j} \end{pmatrix}. +G1G2GqXk+1+00j=q+1pϕjXk+q+1j.

其中 G j G_j Gj 满足 X t = ∑ j = 0 ∞ G j ε t − j X_t=\sum_{j=0}^{\infty}G_j\varepsilon_{t-j} Xt=j=0Gjεtj,可令初值 X ^ k 0 ( q ) = 0 \hat{X}_{k_0}^{(q)}=0 X^k0(q)=0

ARIMA 模型

对差分运算后得到的平稳序列用 ARMA 模型拟合,称 A R I M A ( p , d , q ) ARIMA(p,d,q) ARIMA(p,d,q) 模型,其中 p , d , q p,d,q p,d,q 分别表示 A R AR AR 的项数、差分阶数、 M A MA MA 的项数。

Python 代码

二次指数平滑法

对某厂钢产量作预测,数据如下

t 钢产量 一次平滑 二次平滑 预测值
1 2031 2031 2031
2 2234 2091.9 2049.27 2031
3 2566 2234.13 2104.728 2152.8
4 2820 2409.891 2196.277 2418.99
5 3006 2588.724 2314.011 2715.054
6 3093 2740.007 2441.81 2981.171
7 3277 2901.105 2579.598 3166.002
8 3514 3084.973 2731.211 3360.4
9 3770 3290.481 2898.992 3590.348
10 4107 3535.437 3089.925 3849.752
11 4171.882
12 4362.815

输出如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @ author: Koorye
# @ date:
# @ function: ARIMA 模型

# %%

import numpy as np
import pandas as pd

# %%

# 源数据
df = pd.DataFrame({
    't': [i for i in range(1, 11)],
    'production': [2031, 2234, 2566, 2820, 3006,
                   3093, 3277, 3514, 3770, 4107],
})

# 设 alpha=.3,计算一次、二次指数平滑
alpha = .3
s1, s2 = [int(df['production'][0])],\
    [int(df['production'][0])]

for i in range(1, len(df['t'])):
	s1.append(alpha*df['production'][i] + (1-alpha)*s1[i-1])
	s2.append(alpha*s1[i] + (1-alpha)*s2[i-1])
df['s1'] = s1
df['s2'] = s2

# %%

# 计算过去年的预测值,以及未来年的线性表达式
predict_list = [None]
for i in range(len(df['t'])-1):
	a = 2*df['s1'][i] - df['s2'][i]
	b = (alpha / (1-alpha)) * (df['s1'][i] - df['s2'][i])
	predict_list.append(a + b)

t = 10
a = 2*df['s1'][t-1] - df['s2'][t-1]
b = (alpha / (1-alpha)) * (df['s1'][t-1] - df['s2'][t-1])
df['predict'] = predict_list
print('at =', a)
print('bt =', b)

# %%

# 计算未来年的预测值
pred_df = df.copy()
for i in range(5):
	pred_df = pd.concat([pred_df, pd.DataFrame({
		't': [10+i+1],
		'predict': a + b*i,
	})])
pred_df

# %%

# 画图
import matplotlib.pyplot as plt

plt.plot(pred_df['t'], pred_df['production'],label='production')
plt.scatter(pred_df['t'], pred_df['production'])
plt.plot(pred_df['t'], pred_df['s1'],label='s1')
plt.scatter(pred_df['t'], pred_df['s1'])
plt.plot(pred_df['t'], pred_df['s2'],label='s2')
plt.scatter(pred_df['t'], pred_df['s2'])
plt.plot(pred_df['t'], pred_df['predict'],label='predict')
plt.scatter(pred_df['t'], pred_df['predict'])
plt.legend()

输出如下:

t production s1 s2 predict
0 1 2031.0 2031.000000 2031.000000 NaN
1 2 2234.0 2091.900000 2049.270000 2031.000000
2 3 2566.0 2234.130000 2104.728000 2152.800000
3 4 2820.0 2409.891000 2196.276900 2418.990000
4 5 3006.0 2588.723700 2314.010940 2715.054000
5 6 3093.0 2740.006590 2441.809635 2981.170500
6 7 3277.0 2901.104613 2579.598128 3166.002240
7 8 3514.0 3084.973229 2731.210659 3360.399591
8 9 3770.0 3290.481260 2898.991839 3590.348330
9 10 4107.0 3535.436882 3089.925352 3849.751862
0 11 NaN NaN NaN 3980.948412
0 12 NaN NaN NaN 4171.881925
0 13 NaN NaN NaN 4362.815438
0 14 NaN NaN NaN 4553.748951
0 15 NaN NaN NaN 4744.682464

ARMA 模型

根据 1971~1990 年的太阳黑子数量预测 1991~2000 年的太阳黑子数量,代码如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @ author: Koorye
# @ date: 2021-7-29
# @ function: ARMA 模型

# %%

import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt

# %%

# 源数据
df = pd.DataFrame({
    'year': [i for i in range(1971, 1991)],
    'num': [66.6, 68.9, 38, 34.5, 15.5,
            12.6, 27.5, 92.5, 155.4, 154.6,
            140.4, 115.9, 66.6, 45.9, 17.9,
            3.4, 29.4, 100.2, 157.6, 142.6],
})

# %%

# 画 acf 图
plot_acf(df['num'])

# %%

# 画 pacf 图
plot_pacf(df['num'], lags=9)

# %%

# 建立模型,参考 acf、pacf 代入 p、q,观察 aic
str_list = []
for p in range(1, 6):
    for q in range(1, 3):
        model = sm.tsa.ARMA(df['num'], (p, q)).fit()
        str_list.append('p = {}, q = {}, aic = {}'.format(p, q, model.aic))

for each in str_list:
	print(each)

# %%

# 发现 p=2,q=2 时 aic 最小,取 p=2,q=2
model = sm.tsa.ARMA(df['num'], (2, 2)).fit()
model.summary()

# %%

# 预测和画图
plt.plot(df['year'], df['num'])
plt.scatter(df['year'], df['num'], label='actual')
year_list = [i for i in range(1971, 2001)]
plt.plot(year_list, model.predict(0, len(year_list)-1))
plt.scatter(year_list, model.predict(0, len(year_list)-1), label='predict')
plt.legend()

输出如下:

p = 1, q = 1, aic = 194.84701061998135
p = 1, q = 2, aic = 194.31427174057512
p = 2, q = 1, aic = 188.97865479513626
p = 2, q = 2, aic = 188.92457119015984
p = 3, q = 1, aic = 191.31192040477467
p = 3, q = 2, aic = 192.40349950348713
p = 4, q = 1, aic = 193.19411553305596
p = 4, q = 2, aic = 193.1505615705116
p = 5, q = 1, aic = 194.3858472180579
p = 5, q = 2, aic = 194.78028983920348
Dep. Variable: num No. Observations: 20
Model: ARMA(2, 2) Log Likelihood -88.462
Method: css-mle S.D. of innovations 17.694
Date: Thu, 29 Jul 2021 AIC 188.925
Time: 22:06:42 BIC 194.899
Sample: 0 HQIC 190.091
coef std err z P>|z| [0.025 0.975]
const 75.7977 3.130 24.217 0.000 69.663 81.932
ar.L1.num 1.5399 0.106 14.571 0.000 1.333 1.747
ar.L2.num -0.8567 0.104 -8.245 0.000 -1.060 -0.653
ma.L1.num -0.5612 0.339 -1.658 0.097 -1.225 0.102
ma.L2.num -0.4386 0.291 -1.509 0.131 -1.008 0.131
Real Imaginary Modulus Frequency
AR.1 0.8987 -0.5996j 1.0804 -0.0936
AR.2 0.8987 +0.5996j 1.0804 0.0936
MA.1 1.0001 +0.0000j 1.0001 0.0000
MA.2 -2.2796 +0.0000j 2.2796 0.5000

ARIMA 模型

对 austa 数据集使用 ARIMA 模型作预测,代码如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @ author: Koorye
# @ date:
# @ function: ARIMA 模型

# %%

import numpy as np
import pandas as pd
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt

# %%

# 源数据
df = pd.DataFrame({
    'year': [i for i in range(1980, 2011)],
    'val': [0.82989428, 0.85951092, 0.87668916, 0.86670716, 0.932052,
            1.04826364, 1.3111932, 1.63756228, 2.0641074, 1.91268276,
            2.03544572, 2.17721128, 2.38968344, 2.75059208, 3.0906664,
            3.42664028, 3.83064908, 3.97190864, 3.83160036, 4.143101,
            4.566551, 4.47541, 4.462796, 4.384829, 4.796861,
            5.046211, 5.098759, 5.196519, 5.166843, 5.174744,
            5.440894],
})

# %%

# 作一阶差分
df['val_diff1'] = df['val'].diff()
plt.plot(df['year'], df['val'])
plt.plot(df['year'], df['val_diff1'])

# %%

# ACF 图
plot_acf(df['val_diff1'][1:])

# %%

# PACF 图
plot_pacf(df['val_diff1'][1:], lags=14)

# %%

# 参考 ACF 和 PCAF 代入 p,q
str_list = []
for p in range(1, 4):
    for q in range(0, 4):
        model = ARIMA(df['val'], order=(p, 1, q))
        res = model.fit(disp=0)
        str_list.append('p = {}, q = {}, aic = {}'.format(p, q, res.aic))
for each in str_list:
    print(each)

# %%

# p=2,q=0 使 aic 最小
model = ARIMA(df['val'], order=(2, 1, 0))
res = model.fit(disp=0)
res.summary()

# %%

# 作预测图
res.plot_predict(end=40)

输出如下:

p = 1, q = 0, aic = -13.718554829816128
p = 1, q = 1, aic = -12.644935232547795
p = 1, q = 2, aic = -13.023448862467816
p = 1, q = 3, aic = -11.034475643866699
p = 2, q = 0, aic = -13.534487801792835
p = 2, q = 1, aic = -11.848263794395535
p = 2, q = 2, aic = -11.032058544143538
p = 2, q = 3, aic = -9.036565460115241
p = 3, q = 0, aic = -11.784035132385696
p = 3, q = 1, aic = -9.84986571141387
p = 3, q = 2, aic = -8.617052624191913
p = 3, q = 3, aic = -5.945170779675806

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数学建模笔记 24】数学建模的时间序列模型 的相关文章

  • 如何在 PyCharm 中设置运行配置的默认工作目录

    当我想运行众多 python 脚本之一时 我点击运行 这会创建一个新的运行配置 该配置的工作目录是 python 脚本文件所在的文件夹 相反 它应该从项目范围的固定文件夹运行 我想以某种方式进行设置 但我真的不明白为什么 这有点奇怪 因为我
  • Pandas - 按每个可能的键组合聚合

    我有一个 DataFrame Pandas 我想通过 A B C 和 D 列的组合尽可能按数据进行分组 假设它具有以下形式 A B C D E F G 0 Y X Y Z 1 2 7 1 Y X Y Z 3 4 8 2 X Y U V 1
  • Flask:缓存静态文件(.js、.css)

    我真的找不到任何这方面的资源 那么如何将视图 函数的缓存与静态文件 即 css js 分开 我想将静态对象缓存一周 另一方面 我只需要缓存函数 视图几分钟 当我执行以下操作时 from flask ext cache import Cach
  • uwsgi + Django REST框架:空闲时间后很少有缓慢的请求

    我正在运行 Django REST 框架 白天每分钟的请求率相当低 我注意到一个我无法解释或重现的问题 每天 在夜间或清晨 当我的 RPM 接近于零时 我会收到 1 10 个超慢的请求 我的平均响应时间100 到 200 毫秒之间 但是这个
  • 嵌套重组 - Django

    我有一个包含以下字段的模型 日期 员工 和 计划时间 每个员工对于不同的日期都有不同的计划工作时间 我正在尝试构建我的模板 其中员工按行列出 他们的计划工作时间列在正确的相应日期下的列中 像这样的东西 https i stack imgur
  • Windows 中的信号处理

    在Windows中 我试图创建一个等待SIGINT信号的python进程 当它收到SIGINT时 我希望它只打印一条消息并等待SIGINT的另一次出现 所以我使用了信号处理程序 这是我的 signal receiver py 代码 impo
  • @monthly cron 作业不可靠

    我们的客户希望我们每月创建一份报告 过去 我们使用 monthly cron 作业来完成此任务 但这并不可靠 服务器可能会在这一分钟内宕机 Cron 不会重新运行这些作业 如果服务器已启动 此时数据库可能无法访问 如果服务器已启动且数据库已
  • Ttk Treeview:跟踪键盘选择

    这是一个带有 ttk 树视图的 Tk 小部件 当用户单击该行时 会执行某些功能 此处仅打印项目文本 我需要的是以下内容 最初的重点是文本输入 当用户按下 Tab 键时 焦点应该转到第一行 并且应该执行绑定到 Click 事件的函数 当用户使
  • 包含可变数据的正则表达式 - ply.lex

    我正在使用 python 模块ply lex编写一个词法分析器 我用正则表达式指定了一些标记 但现在我卡住了 我有一个list of Keywords谁应该是token data是一个包含大约 1000 个关键字的列表 这些关键字都应该被识
  • Python Subversion 包装器库

    在颠覆的文档 http svnbook red bean com en 1 7 svn developer usingapi html svn developer usingapi otherlangs有一个从 Python 使用 Subv
  • BeautifulSoup 抓取街道地址

    我正在使用最底部的代码来获取weblink 以及清真寺名称 不过我也想得到面值 and 街道地址 请帮助我被困住了 目前我得到以下信息 Weblink div class subtitleLink a href http www salat
  • 使用 gin 索引和 sqlalchemy 返回排名搜索结果

    我为全文搜索设置了 GIN 索引 我想获取与搜索查询匹配的记录列表 按排名排序 记录与搜索查询的匹配程度 对于结果 我只需要记录及其列 不需要用于排序的实际排名值 我有以下查询 它运行良好并从我的 postgresql 数据库返回预期结果
  • 显示多索引 pandas 数据帧的前 10 行

    我有一个多级索引 pandasDataFrame第一级在哪里year第二级是username 我只有一列已经按降序排序 我想显示每个索引级别 0 的前 2 行 我拥有的 count year username 2010 b 677 a 50
  • Python Pandas:将参数传递给 agg() 中的函数

    我试图通过使用不同类型的函数和参数值来减少 pandas 数据框中的数据 但是 我无法更改聚合函数中的默认参数 这是一个例子 gt gt gt df pd DataFrame x 1 np nan 2 1 y a a b b gt gt g
  • 如何在python中合并具有相同键的嵌套字典

    我有一个这样的数据结构 SNAPSHOT SnapshotVersion 304 SNAPSHOT SnapshotCreationDate 2015 06 21 17 33 41 CafeData CafeVersion 2807 Caf
  • Django:通过外键将两个表连接到第三个表?

    我有三个型号 class A Model class B Model id IntegerField a ForeignKey A class C Model id IntegerField a ForeignKey A 我想要得到 B i
  • 如何检查两个数据集的匹配列之间的相关性?

    如果我们有数据集 import pandas as pd a pd DataFrame A 34 12 78 84 26 B 54 87 35 25 82 C 56 78 0 14 13 D 0 23 72 56 14 E 78 12 31
  • 无法运行特定的 .pyc 文件

    使用编译在unix工作的python文件后 import py compile py compile compile server py 我在同一目录中获得 pyc 文件 但是当我尝试在 putty 中使用 server pyc 运行该文件
  • 使用 PyQt5 拖放 QLabels

    我正在尝试使用 PyQt5 将 Qlabel 拖放到另一个 Qlabel 上 from PyQt5 QtWidgets import QApplication QWidget QToolTip QPushButton QMessageBox
  • 在Python中:检查文件修改时间是否早于特定日期时间

    我用 C 编写了以下代码来检查文件是否已过期 DateTime lastTimeModified file getLastTimeModified if lastTimeModified HasValue File does not exi

随机推荐

  • 60-400-045-使用-binlog-Maxwell读取MySQL binlog日志到Kafka

    文章目录 启动MySQL 创建maxwell的数据库和用户 在MySQL中创建一个测试数据库和表 启动Zookeeper 启动kafka 并创建主题为maxwell的topic 启动kafaka的消费者 检查数据是否到位 启动maxwell
  • [网络安全]sqli-labs Less-17 解题详析

    考察报错注入 本文使用extractvalue进行注入 原理及姿势可参考 网络安全 sqli labs Less 5 解题详析 判断注入类型 由以下回显可知 注入类型为单引号注入 查库名 账号输入admin 密码输入 1 and extra
  • Visual C++6.0的安装及使用教程

    Visual C 6 0下载链接 链接 https pan baidu com s 18ubNr9Gor3GbRrAkJe612w 密码 piek 对刚学习C语言或C 的小伙伴们来说 一款简单好用的编译器必不可少 今天给大家介绍的是Visu
  • 深度学习小白——DenseNet学习

    原论文地址 https arxiv org abs 1608 06993 用Keras写的pre model代码地址 https github com flyyufelix DenseNet Keras 一 主要原理 其借鉴了ResNet的
  • 深度学习如何集成领域知识?IBM研究等《知识增强深度学习》综述,全面阐述科学与经验知识增强的深度学习...

    来源 专知 尽管在过去的几年里 深度学习模型在许多不同的领域取得了巨大的成功 但通常数据匮乏 在不可见的样本上表现不佳 而且缺乏可解释性 目标领域往往存在各种先验知识 利用这些先验知识可以弥补深度学习的不足 为了更好地模仿人类大脑的行为 人
  • 下面是两种解决Redis击穿问题的方法,并给出相应的Java代码实现。

    Redis击穿问题指的是当一个key在缓存中过期时 恰好有大量并发请求访问该key 导致请求直接打到数据库 引起数据库压力过大 甚至宕机 方法一 使用互斥锁 在访问缓存之前 首先获取一个互斥锁 防止多个请求同时访问数据库 只有一个请求可以访
  • 转 用十条命令在一分钟内检查Linux服务器性能

    如果你的Linux服务器突然负载暴增 告警短信快发爆你的手机 如何在最短时间内找出Linux性能问题所在 来看Netflix性能工程团队的这篇博文 看它们通过十条命令在一分钟内对机器性能问题进行诊断 概述 通过执行以下命令 可以在1分钟内对
  • 开发百度地图定位APP(LBS)

    一 注册成为百度地图开发者 并获取开发密钥 获取密钥时需要进入Android studio使用keytool文件获取SHA1码 二 下载开发包解压并导入Android studio 选择自己需要的开发包下载 这里我选择的是基础地图基础定位J
  • C#类和对象--习题(2)成绩管理

    老师口中说 少用static 然后有习题要我们用static来写 实现简单学生成绩管理 两个类 方法带static 1 学生及信息录入 id name grade 2 输出成绩 3 修改成绩 4 查询成绩 5 显示成绩 6 退出系统 Met
  • 卓越性能代码_教你Win10启用卓越性能模式,效果明显!

    本文授权转载自公众号 labulac 当Windows 10更新到内部版本17333后 一些朋友可能发现 以往电源管理模式有节能 标准和高性能三个选项 现在装完系统默认启用的是标准选项 剩下的两个模式被隐藏了 当然我们也可以将这些电源模式找
  • Vue插槽用法,在JSX中的用法

    注意 scopedSlots会包含 slots里面的内容 所以我们两个一起使用的时候 名字要不一样 scopedSlots 里面的属性值是函数 可以调用这个函数进行渲染 scopedSlots会包含 slots slots 里面的属性值是一
  • Java如何设置线程的优先级呢?

    转自 Java如何设置线程的优先级呢 线程 thread 是操作系统能够进行运算调度的最小单位 它被包含在进程之中 是进程中的实际运作单位 一条线程指的是进程中一个单一顺序的控制流 一个进程中可以并发多个线程 每条线程并行执行不同的任务 在
  • 从零开始搭建uni-app框架的小程序开发环境

    个人主页 个人主页 推荐专栏 小程序开发成神之路 作者简介 一个读研中创业 打工中学习的能搞全栈 也搞算法 目前在搞大数据的奋斗者 您的小小关注是我持续输出的动力 文章目录 一 小程序账号的开通 1 注册小程序账号 2 获取小程序身份证 A
  • 寒假小复习2

    package demo public class Demo public static void main String args int i 2 switch i case 1 System out println System out
  • Pytorch学习笔记(二)

    后续遇到一些函数等知识 还会进行及时的补充 tensor的创建 使用pytorch中的列表创建tensor tensor torch Tensor 1 1 0 2 print
  • python 基础

    条件表达式 if 1 gt 2 print 111 elif 2 gt 3 print 222 else print 333 for循环 for i in range 3 10 print i 输出结果 for循环 步长为2 for i i
  • QStyle 自定义QSpinBox外观

    点击查看详细介绍 头文件 ifndef SPINBOX STYLE 1 H define SPINBOX STYLE 1 H include
  • 【高等数学基础知识篇】——函数,极限与连续

    本文仅用于个人学习记录 使用的教材为汤家凤老师的 高等数学辅导讲义 本文无任何盈利或者赚取个人声望的目的 如有侵权 请联系删除 文章目录 一 函数基础知识 1 1 基本初等函数和初等函数 1 2 函数的初等特性 1 3 特殊函数 二 函数题
  • PageHelper的order by方法可替代mybatis中order by必须使用$来避免sql注入

    PageHelper的order by方法可替代mybatis中order by必须使用 来避免sql注入 在my batis中 我们通常使用 字符 来传值 在mybatis中使用order by排序时也习惯性的使用 然后发现sql错误 后
  • 【数学建模笔记 24】数学建模的时间序列模型

    24 时间序列模型 定义 时间序列是按时间顺序排列的 随时间变化且相互关联的数据序列 分析时间序列的方法构成数据分析的一个重要领域 即时间序列分析 一个时间序列往往是以下几类变化形式的叠加 长期趋势变动 T t T t Tt 朝一定方向的变