模型简介

时间序列分析模型是一个很常用的预测模型。给出一组跟时间相关的数据(或者说时间序列),该模型可以预测未来的数据。往往一个时间序列会呈现一定的周期性。比如,洪涝灾害在夏季高发,那么洪涝灾害的发生频率就以一年为周期。一个时间序列的典型分解式为 X t = m t + S t + Y t X_t=m_t+S_t+Y_t Xt=mt+St+Yt m t m_t mt为趋势项,即数据在年与年之间的变化规律; S t S_t St为周期已知(比如一年)的周期项,反映数据在月与月之间的变化规律; Y t Y_t Yt是随机噪声项,反映数据受到未知因素的干扰。时间序列分析模型就是通过一定的方法,把数据中的趋势项和周期项剥离出来,从而达到对真实数据的拟合及预测。

模型求解

假设我们现在有一个时间序列 X = ( x i j ) n ∗ T X=(x_{ij})_{n*T} X=(xij)nT。n表示年数,T表示周期(一般取T代表月数,即T=12)。 x i j x_{ij} xij表示第i年第j月的某个数据。

提取周期项

周期项,即前文提到的 S t S_t St S j S_j Sj表示第j月的数据特征(是一个数)。
先计算每一年的平均值, X i ‾ = ∑ j = 1 T X i j T \overline{X_i}=\frac{\sum_{j=1}^{T}{X_{ij}}}{T} Xi=Tj=1TXij
再对每个月的数据零均值化, s t i j = X i j − X i ‾ st_{ij}=X_{ij}-\overline{X_i} stij=XijXi
对于这些零均值化的数据,每年第j月的数据的平均值即为第j月的数据特征, S j = ∑ j = 1 T s t i j n S_j=\frac{\sum_{j=1}^{T}{st_{ij}}}{n} Sj=nj=1Tstij
这样,就把周期项 S j S_j Sj求出来了。

拟合趋势项

趋势项,即前文提到的 m t m_t mt
由于趋势项和周期没有关系,所以为了拟合方便,先把原始的矩阵X拉成直线,令 x k = x i j , k = ( i − 1 ) ∗ T + j x_k=x_{ij},k=(i-1)*T+j xk=xij,k=(i1)T+j
再把周期项给减掉, n x k = x k − S j nx_k=x_k-S_j nxk=xkSj
这样 n x k nx_k nxk就只剩下趋势项和随机噪声项了。那么为了避免随机噪声项的干扰,我们就需要对 n x k nx_k nxk进行曲线拟合。一般是采用线性拟合(即一次函数拟合)。
假设线性拟合的结果为 { m k } \{m_k\} {mk},那么 { m k } \{m_k\} {mk}就是能反映数据走向的趋势项。

得到预测值

k = ( i − 1 ) ∗ T + j k=(i-1)*T+j k=(i1)T+j,则 m k + S j m_k+S_j mk+Sj表示第i年第j月的预测数据。

代码

这是我写的时间序列分析模型的matlab代码,里面的变量名称基本和文章保持一致。为了让代码读起来更加舒适,我添加了大量的注释,帮助大家理解。在遇到真实情景的时候,只需要按照题目要求在上面进行一些小小的改动就可以运行了。

T=12;%T表示周期,也就是月数
n=4;%n表示年数
z=1;%z表示要预测的年数
x;%x为直线型的原始数据,需要导入
D=reshape(x,T,n)';%把直线型的数据处理成T*n的矩阵
aver=mean(D');%求每年的平均值
st=zeros(n,T);
for i=1:n
	for j=1:T
	st(i,j)=D(i,j)-aver(i);%对每个月的数据零均值化
	end
end
S=zeros(1,T);
S=sum(st)/n;%计算周期项
nx=zeros(n*T,1);
for i=1:n
	for j=1:T
	k=(i-1)*T+j;
	nx(k)=x(k)-S(j);%拉直并减去周期项
	end
end
coef=polyfit(1:n*T,nx,1);%用一次函数拟合nx,得到系数
m=zeros(1,(n+z)*T);
for i=1: (n+z)*T
	m(i)=coef(1)*i+coef(2);%m为对nx线性拟合的结果
end
xx=zeros(1,(n+z)*T);
for i=1: n+z
	for j=1:T
	k=(i-1)*T+j;
	xx(k)=m(k)+S(j);%趋势项加上周期项,得到预测结果
	end
end
plot(x);%绘制实际数据
hold on
plot(1:(n+z)*T,xx);%绘制预测数据
xlabel('月数');
ylabel('数据值');
legend('实际数据','预测数据');

应用实例

以2021年五一杯数学建模比赛B题第二小问的数据为例。进行了一些数据处理之后,得到了4年的出警次数(共48个数据),如下:
79 95 98 51 275 67 63 40 50 31 38 43 58 28 44 14 148 87 23 42 49 33 65 68 54 129 68 71 107 119 59 50 46 44 40 63 67 76 73 44 138 146 72 30 41 26 25 36
将这些数据命名为x,导入到程序中,得到的结果如下:
数学建模之时间序列分析模型-LMLPHP
可以看出,虽然存在一定误差,但是时间序列分析模型对这种带有一定周期性的数据,预测结果还是比较好的。

总结

时间序列分析模型是一个简单又有效的一个模型,也是数学建模比赛中的一个非常好用的预测模型。其实它不仅仅可以处理跟时间相关的数据,也可以处理其它的看上去有周期性的数据。为什么说要看上去有周期性呢,因为周期T在模型中是需要你自己输入的。要是看不出来周期,还是换个方法吧。

11-11 10:42