时间序列模型建模流程图
我们知道平稳序列具有许多良好的统计特性, 是传统时间序列分析的基础. 然而, 在自然界中和经济、工程等应用领域中, 我们所面对的时间序列通常具有非平稳性.
此时, 最自然的想法是通过一些简单的预处理方法将非平稳序列转化为平稳序列. 常用的有确定性分析和随机分析这两类平稳化方法. 在此主要介绍确定性分析方法.
为了能够更加清晰直观的理解时间序列平稳化方法,下面结合具体数据集编写程序,完成对非平稳序列的平稳化.
开发环境:
------------------------------------------------------------------------------------------------
MATLAB 版本: 9.12.0.1884302 (R2022a)
MATLAB 许可证编号: 968398
操作系统: macOS Version: 12.3 Build: 21E230
Java 版本: Java 1.8.0_202-b08 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
------------------------------------------------------------------------------------------------
时间序列数据集:1965年3月至1994年3月澳大利亚毛纱季度产量
特点:具有趋势性和季节性、近似正态分布(柱状图),数据量108个
经过长期的观察实践, 确定性分析法认为产生非平稳现象的确定性因素主要可以分解为两类
第一类: 长期趋势变动. 尽管时间序列一般呈现出随机起伏的形态, 但在一段较长时间内, 仍呈现递增、递减的转变形式. 这种大幅度变化通常是长期因素影响的结果, 如某地区年平均气温的变化, 我国人口总量的变化等都是长期因素所导致的, 它反映客观事物的主要变化趋势.
趋势拟合法就是把时间作为自变量, 相应的序列观测值作为因变量, 建立序列值随时间变化的回归模型. 为了便于理解, 这里暂时假设序列中不存在季节项, 即
X t = T t + R t E ( R t ) = 0 , Var ( R t ) = σ R 2 , (1) \begin{aligned} X_{t} &=T_{t}+R_{t} \\ E\left(R_{t}\right) &=0, \operatorname{Var}\left(R_{t}\right)=\sigma_{R}^{2}, \end{aligned}\tag{1} XtE(Rt)=Tt+Rt=0,Var(Rt)=σR2,(1)
其中,根据序列所表现出的线性或非线性性特征, 拟合法又有线性拟合和非 线性拟合, 对应假设 T t T_{t} Tt 为关于 t t t 的线性函数和非线性函数形式. ( 1 ) (1) (1) 式中 { R t } \left\{R_{t}\right\} {Rt} 的方差齐性是为保证趋势拟合中最小二乘参数估计的可靠性.
根据线性拟合处理后的时序图很容易发现,该处理对趋势项的消除并不理想,于是我们考虑使用高次多项式拟合来对趋势项进行处理.
可以发现,此时趋势项已被基本消除.
线性拟合函数:trend_fitting
function X_hat = trend_fitting(X)
% trend fitting 趋势拟合(线性) 去掉趋势项
% @X 原始时间序列
% @T 趋势项
% @X_hat 趋势拟合(线性) 去掉趋势项后时间序列
N=length(X);
t=1:N;
t_bar=sum(t)/N;
X_bar=sum(X)/N;
beta_1=(1/N*(t*X')-t_bar*X_bar)/(1/N*(t*t')-t_bar^2);
beta_0=X_bar-beta_1*t_bar;
T=beta_0+beta_1*t;
X_hat=X-T;
end
多项式拟合函数:polynomial_fitting
function X_hat = polynomial_fitting(X,n)
%Polynomial Fitting 趋势拟合(多项式) 去掉趋势项
% @n 拟合多项式次数 n
% @X 原始时间序列
% @beta n阶多项式的系数
% @T 趋势项
% @X_hat 趋势拟合(线性) 去掉趋势项后时间序列
N=length(X);
t=1:N;
beta = polyfit( t, X, n);
T=polyval(beta,t);
X_hat=X-T;
end
在许多实际问题中, 我们得到的观测数据序列显然不能近似看作是平稳的, 某些序列并不是稳定在同一水平上, 而是具有明显的增长或减少趋势. 例如某一地区的年平均温度所构成的时间序列 { x t } \left\{x_{t}\right\} {xt}, 短期内可能表现为上下起伏的随机变化, 但由于全球温室效应, 长期内总的温度变化趋势是增长的, 这显然是一个非平稳序列. 但若我们考察温度的增量 ∇ x t = x t − x t − 1 \nabla x_{t}=x_{t}-x_{t-1} ∇xt=xt−xt−1, 可将 { x t } \left\{x_{t}\right\} {xt} 的趋势消除, 转化为增量序列 { ∇ x t } \left\{\nabla x_{t}\right\} {∇xt} 在某一常值周围的平稳波动.
一般地, 对于非平稳序列 { X t } \left\{X_{t}\right\} {Xt}, 可以通过差分运算使之平稳化.通常对于蕴含着显著的线性趋势, 一阶差分就可以实现趋势平稳; 序列蕴含着曲线趋势, 二阶或三阶差分就可以提取曲线趋势的影响.
编写 k 阶差分的函数
从时序图可以看出,使用 1 阶差分法处理后即可较好的消除趋势项.
意料之中, 2 阶差分法同样漂亮的完成了对趋势项的消除.
差分法函数:difference
function X_hat= difference(X,k)
%Difference 计算 k 阶差分
% @k k阶差分
% @X 原始时间序列
% @X_hat k 阶差分后时间序列
X_hat=X;
% X_hat=diff(X_hat,k) %可直接调用 k 阶差分
while k>0
X_hat=diff(X_hat);
k=k-1;
end
end
第二类: 季节性变化. 这类波动主要由本身就具有循环规律变化的影响因素所导致, 如季节规律性变化导致的月平均气温的循环波动, 每年节假日的规律性导致各类消费指数的循环波动等, 通常表现为长期趋势线上下的规律性周期波动. 有时也把循环波动和季节性变化分开考虑, 其实在实际分析时, 很难把固定周期的循环波动和季节性变化严格分解开, 因此此处中我们统一为季节性变化.
广义性的季节变动是指一种由于自然条件、消费习惯等因素的作用使研究对象呈现以一定时期为周期的较为规律性变化. 通常表现为一年内直接受自然季节的更替影响而发生的规律性增减变化, 如温度、降雨量等; 或是受间接影响而产生的规律性变化, 如价格消费指数、景点游客数等. 此外,一些受国家法定节假日和各地民俗民风等社会条件的影响, 工业生产、商品销售、交通运输等经营活动所具有的淡旺季周期性变动也属于广义季节变动的范畴.
季节分析法就是利用时间平均代替空间平均提取季节变动指数, 从而比较科学地对序列的发展作出预测.
季节分析法需要仔细观察数据图来确认序列周期 m m m, 由于我们选取的时间序列数据集:1965年3月至1994年3月澳大利亚毛纱季度产量
,具有趋势性和季节性,故选取周期为 12, 即 m = 12 m=12 m=12.
奇了个大怪,从时序图来看,隐隐约约感觉处理后季节性反而愈发明显了.
季节分析法函数:seasonal_analysis
function [X_hat,I]= seasonal_analysis(X,m)
%Seasonal Analysis 季节分析法去除周期性
% @m 季节周期
% @X 原始时间序列
% @S 趋势项
% @X_hat 季节分析法去除周期性后时间序列
% @I 季节指数
if mod(length(X),m)==0
n=length(X)/m;
X_jbar=zeros(m,1);
I=zeros(m,1);
S_0=zeros(m,1);
X_bar=1/(n*m)*sum(X);
for j=1:m
X_jbar(j)=1/n*sum(X((j-1)*n+1:(j-1)*n+n));
I(j)=X_jbar(j)/X_bar;
S_0(j)=X_bar*I(j);
end
S=repmat(S_0,n,1);
X_hat=X-S;
else
disp('使用季节分析法去除周期性时时间序列长度不能被周期整除');
disp('请修正后重新尝试喔,宝儿~');
end
end
对于蕴含着固定周期的序列需进行步长为周期长度的差分运算, 称为季节差分法. 周期长度为 m m m 的季节差分算子常用 ∇ m = 1 − B m \nabla_{m}=1-\mathscr{B}^{m} ∇m=1−Bm 表示. 如果季节差分运算后为一平稳序列 { η t } \left\{\eta_{t}\right\} {ηt}, 则有
X t = X t − m + η t . X_{t}=X_{t-m}+\eta_{t} . Xt=Xt−m+ηt.
季节差分法的实质是使用延迟一个周期的历史数据作为自变量来刻画当期序列 值, 也是一种自回归方式提取确定性信息的方法.
通过分析我们知道原始数据存在季节性,且周期为 12.
k 步季节差分法函数:seasonal_difference
function X_hat= seasonal_difference(X,k)
%seasonal difference 计算 k 步季节差分
% @k k步季节差分
% @X 原始时间序列
% @X_hat k 阶差分后时间序列
X_hat=zeros(length(X)-k,1);
for i=1:length(X)-k
X_hat(i)=X(i+k)-X(i);
end
end
对于一个存在趋势项和季节性的非平稳数据来说,根据思维导图可以轻松知道,我们选择不同的顺序和组合方式,可以得到 8 种排列的平稳化处理方法.
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去除趋势(多项式拟合)
x_hat = polynomial_fitting(x_hat',4);
% 去周期(季节分析)
[x_hat,I]= seasonal_analysis(x_hat,12);
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去周期(季节分析)
[x_hat,I]= seasonal_analysis(x_hat,12);
% 去除趋势(多项式拟合)
x_hat = polynomial_fitting(x_hat',4);
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去除趋势(多项式拟合)
x_hat = polynomial_fitting(x_hat',4);
% 去周期(k 步季节差分)
x_hat= seasonal_difference(x_hat,12);
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去周期(k 步季节差分)
x_hat= seasonal_difference(x_hat,12);
% 去除趋势(多项式拟合)
x_hat = polynomial_fitting(x_hat',4);
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去除趋势(k 阶差分)
x_hat_1= difference(x,1);
x_hat_1=[x_hat_1;0];
% 去周期(季节分析)
[x_hat_1,I]= seasonal_analysis(x_hat_1,12);
x_hat_1=x_hat_1(1:end-1);
由于作差分后序列长度会变化,故需作补齐处理.
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去周期(季节分析)
[x_hat,I]= seasonal_analysis(x_hat,12);
% 去除趋势(k 阶差分)
x_hat= difference(x_hat,1);
处理顺序:
实验报告
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去除趋势(k 阶差分)
x_hat_1= difference(x,1);
x_hat_1=[x_hat_1;0];
% 去周期(季节差分)
[x_hat_1,I]= seasonal_analysis(x_hat_1,12);
x_hat_1=x_hat_1(1:end-1);
由于作差分后序列长度会变化,故需作补齐处理.
处理顺序:
实验报告
处理结果图:
程序源代码
平稳化处理主程序:smooth
clc,clear
filename='data_woolyrnq.csv';
data = readmatrix(filename, 'OutputType', 'single');
x=data(1:108,1);
x_hat=x;
% 去周期(季节差分)
[x_hat,I]= seasonal_analysis(x_hat,12);
% 去除趋势(k 阶差分)
x_hat= difference(x_hat,1);
季节差分、差分法不同处理顺序的差别
为了能够更加清晰直观的理解时间序列平稳化方法,我们结合具体数据集编写Matlab程序,完成对非平稳序列的平稳化.
通过对时间序列平稳化的 8 种方法比较及Matlab实现,从逐点曼哈顿距离图可以发现,除了季节性差分配合差分法平稳化外,其余几种组合方式的处理结果均与操作顺序有关.
周永道,王会琦,吕王勇.时间序列分析及应用.北京:高等教育出版社,2015.
数据集:
SH600031.csv
data_woolyrnq.csv
shampoo.csv
本人非统计专业,若有不妥之处, 恳请批评指正.
作者:图灵的猫
作者邮箱: [email protected]