ARIMA 模型简介
ARIMA(Auto-Regressive Integrated Moving Average)模型,是一种广泛应用于时间序列预测的统计学方法,特别适用于具有历史数据模式的预测问题。ARIMA 模型通过结合自回归(AR)、差分(I)、滑动平均(MA)三个组成部分,来捕捉和预测时间序列数据中的规律。其核心思想是:通过分析时间序列的历史数据,建立一个能够预测未来的数学模型。
1. ARIMA 模型的基本原理
ARIMA 模型的名称包含三个主要部分:
- AR(Auto-Regressive,自回归):自回归部分表示当前值与其过去值之间的关系。简单来说,它使用过去的观察值(通常是前几个时刻的数据)来预测当前值。
- I(Integrated,差分):差分操作用于消除时间序列中的趋势,使数据变得平稳。时间序列如果具有明显的趋势(如上升或下降),那么就需要通过差分将其转换为平稳序列,以便建模和预测。
- MA(Moving Average,滑动平均):滑动平均部分表示当前值与过去的预测误差之间的关系。它通过使用历史预测误差来调整当前预测,捕捉随机波动。
ARIMA 模型通常以 ARIMA(p, d, q) 的形式表示,其中:
- p 是自回归(AR)部分的阶数,表示使用过去多少期的观测值。
- d 是差分(I)部分的阶数,表示对数据进行多少次差分使其平稳。
- q 是滑动平均(MA)部分的阶数,表示使用过去多少期的预测误差。
在 ARIMA 模型中,选择 p、d 和 q 的合适值是建模过程中非常关键的一步。通常,选择这些参数需要通过分析数据的自相关性和偏自相关性,或者通过模型的拟合结果来决定。
在我的代码中,通过以下方法自动确定了 ARIMA 模型的 p、d 和 q 参数:
1. 差分操作确定 d(差分阶数)
ARIMA 模型要求输入数据是平稳的,因此需要通过差分操作使数据平稳。差分操作的阶数 d 是通过单位根检验(ADF 检验)来确定的。在代码中,首先进行了去趋势操作,去除掉数据中的趋势部分。然后,通过 adftest 函数来判断数据是否平稳。如果数据是非平稳的,则进行差分操作,并再次使用 adftest 来检查是否平稳。直到数据变得平稳为止。具体操作如下:
[H, PValue, TestStat, CriticalValue] = adftest(TempData); % 进行单位根检验
difftime = 0;
SaveDiffData = [];
while ~H
% 如果数据非平稳,则进行差分操作
SaveDiffData = [SaveDiffData, TempData(1, 1)];
TempData = diff(TempData); % 一次差分
difftime = difftime + 1; % 记录差分次数
[H, PValue, TestStat, CriticalValue] = adftest(TempData); % 进行平稳性检验
end
这里,adftest
进行的是 Augmented Dickey-Fuller (ADF) 检验,检查时间序列是否存在单位根(即是否是平稳的)。如果 H = 0 表示数据非平稳,就会进行差分,直到数据平稳为止。d 的值即为差分次数 difftime
。
2. 确定 p 和 q(自回归和滑动平均阶数)
接下来,你通过 AIC(Akaike 信息准则) 和 PACF(偏自相关函数)、ACF(自相关函数) 来选择最优的 p 和 q 阶数。你采用了 ARMAX 模型的 AIC 值来评估模型的好坏,选择 AIC 最小的阶数组合作为最终的 p 和 q。
具体实现方式如下:
test = [];
% 自回归对应PACF, 给定滞后长度上限p和q
for p = 0:5
% 移动平均对应ACF
for q = 0:5
if (p + q ~= 0)
m = armax(TempData, [p q]); % 训练 ARMAX 模型
AIC = aic(m); % 计算 AIC 值
test = [test; p q AIC]; % 将阶数和对应的 AIC 值保存
end
end
end
% 选择 AIC 值最小的模型
for k = 1:size(test, 1)
if test(k, 3) == min(test(:, 3))
p_test = test(k, 1); % 选择 p 的值
q_test = test(k, 2); % 选择 q 的值
break;
end
end
在这段代码中,首先通过双重循环遍历所有可能的 p 和 q 阶数组合(在这里分别设置为 0 到 5)。每次组合,通过 armax
函数训练 ARMAX 模型并计算其 AIC 值。然后,将每组 p、q 和对应的 AIC 值存储在 test
数组中。最终,选择具有最小 AIC 值的 p 和 q 作为模型的阶数。
2. ARIMA 模型的应用条件
ARIMA 模型适用于以下情况:
- 平稳性:ARIMA 模型要求时间序列是平稳的,即其统计特性(如均值、方差等)随时间变化而不发生显著变化。如果数据具有趋势或季节性,可以通过差分操作将其转化为平稳序列。
- 自相关性:ARIMA 模型能够捕捉数据中的自相关性,即过去数据与当前数据之间的关系。这使得 ARIMA 特别适用于那些时间序列值与其历史值密切相关的情况。
3. ARIMA 模型的建模步骤
建立 ARIMA 模型的过程通常包括以下几个步骤:
3.1 数据预处理
在应用 ARIMA 模型之前,首先需要对时间序列数据进行预处理。主要步骤包括:
- 去趋势化:去除数据中的长期趋势(如果存在),使数据变得更加平稳。
- 差分操作:如果数据是非平稳的(例如,存在趋势性),则需要通过差分操作将其转换为平稳序列。差分的目的是消除时间序列中的趋势性,使其均值和方差不随时间变化。
3.2 检查平稳性
使用单位根检验(如 ADF 检验)来判断时间序列是否已经平稳。如果时间序列非平稳,需要进一步进行差分操作,直到数据变得平稳。
3.3 确定模型的阶数
ARIMA 模型的核心是选择合适的 p、d 和 q 值。可以通过以下方式来选择这些参数:
- ACF(自相关函数)和 PACF(偏自相关函数):这些函数可以帮助识别 AR 和 MA 阶数的合适选择。
- AIC(Akaike 信息准则):通过计算不同阶数模型的 AIC 值来选择最佳的模型阶数。通常选择 AIC 值最小的模型。
3.4 模型拟合
在选择了合适的 p、d 和 q 后,使用最大似然估计(MLE)方法来估计模型参数,并拟合 ARIMA 模型。拟合后的模型可以用于预测。
3.5 模型预测
使用拟合好的 ARIMA 模型进行预测。可以使用模型来预测未来的时序数据。通常分为两类预测:
- 点预测:直接预测未来某个时刻的值。
- 区间预测:给出未来值的预测区间,提供更为灵活的预测结果。
3.6 模型评估
在模型训练完成后,需要对模型进行评估。常用的评估指标包括:
- 均方根误差(RMSE):衡量预测值与实际值之间的差异,值越小表示预测效果越好。
- R2 值:表示模型对数据的拟合优度,值越接近 1 表示模型拟合效果越好。
- MAPE(平均绝对百分比误差):衡量预测误差相对于实际值的比例,值越小说明预测精度越高。
4. ARIMA 模型的优势与局限性
4.1 优势
- 简单有效:ARIMA 模型结构简单,容易理解,并且能够处理非平稳时间序列数据,适用于多种实际应用场景。
- 强大的自回归能力:通过利用历史数据进行预测,ARIMA 模型能够捕捉到数据中的长期依赖关系。
- 广泛应用:ARIMA 模型在金融市场、气象预测、销售预测、股票分析等领域有着广泛的应用。
4.2 局限性
- 对季节性数据不敏感:ARIMA 模型适用于非季节性数据,对于季节性数据,ARIMA 模型可能需要进行扩展(例如 SARIMA,季节性 ARIMA)。
- 需要平稳性:ARIMA 模型要求输入数据必须是平稳的。如果数据是非平稳的,必须进行差分,或者通过其他方法进行处理。
- 无法捕捉非线性关系:ARIMA 模型本身假设数据的线性关系,对于复杂的非线性关系,ARIMA 可能表现不佳。
5. ARIMA 模型的扩展
对于季节性时间序列数据,ARIMA 模型可以扩展为 SARIMA(Seasonal ARIMA)模型。SARIMA 模型在 ARIMA 的基础上增加了季节性成分,能够处理带有季节性周期的时间序列数据。
此外,随着机器学习和深度学习的发展,越来越多的复杂模型(如 LSTM、GRU、Prophet 等)也被应用于时间序列预测任务,ARIMA 作为传统统计方法,在某些场景下仍然是非常有用的工具。
6. 结论
ARIMA 模型是时间序列预测中常用的基础模型,它通过自回归、差分和滑动平均成分来捕捉数据中的模式。尽管 ARIMA 有一些局限性,但它仍然是许多预测任务中的有效工具,尤其是在数据相对简单且平稳时。通过合理选择模型的参数和对数据进行预处理,ARIMA 模型能够在许多实际问题中提供有效的预测结果。
Matlab代码手把手教运行
为了帮助更多的萌新更快上手数学建模建等竞赛,这里直接手把手教会如何直接使用本文中的ARIMA代码:
代码全文:
warning off
close all
clear
clc
%% 导入数据
data=xlsread('data.xlsx');
%预报步长
step=24;
TempData=data;
output=data;
%去趋势线
TempData=detrend(TempData);
%趋势函数
TrendData=data-TempData;
%差分,平稳化时间序列
[H,PValue,TestStat,CriticalValue] = adftest(TempData);
difftime=0;
SaveDiffData=[];
while ~H
%差分,平稳化时间序列
SaveDiffData=[SaveDiffData,TempData(1,1)];
TempData=diff(TempData);
%差分次数
difftime=difftime+1;
%adf检验,判断时间序列是否平稳化
[H,PValue,TestStat,CriticalValue] = adftest(TempData);
end
%模型定阶或识别
test = [];
%自回归对应PACF,给定滞后长度上限p和q
for p = 0:5
%移动平均对应ACF
for q = 0:5
if(p + q ~= 0)
m = armax(TempData,[p q]);
%armax(p,q),计算AIC
AIC = aic(m);
test = [test;p q AIC];
end
end
end
for k = 1:size(test,1)
%选择AIC值最小的模型
if test(k,3) == min(test(:,3))
p_test = test(k,1);
q_test = test(k,2);
break;
end
end
%armax(p,q),[p_test q_test]对应AIC值最小
m = armax(TempData,[p_test q_test]);
ARIMA_Predict = predict(m,TempData,step);
ARIMA_Forcast = forecast(m,TempData,step);
PreR=[ARIMA_Predict' ARIMA_Forcast'];
%还原差分
if size(SaveDiffData,2)~=0
for index=size(SaveDiffData,2):-1:1
%差分还原
PreR=cumsum([SaveDiffData(index),PreR]);
end
end
%预测趋势并返回结果
TrendData=TrendData';
mp1=polyfit(1:size(TrendData,2),TrendData,1);
xt=[];
for j=1:step
xt=[xt,size(TrendData,2)+j];
end
TrendResult=polyval(mp1,xt);
ARIMAoutput=[TrendData,TrendResult]+PreR;
ARIMAoutput_Predict=ARIMAoutput(1:end-step)';
ARIMAoutput_Forcast=ARIMAoutput(end-step+1:end)';
%% 数据输出
error=ARIMAoutput_Predict-output;
pererror=error./output;
avererror=sum(abs(error))/length(error);
averpererror=sum(abs(pererror))/length(pererror);
RMSE = sqrt(mean((error).^2));
R2 = 1 - norm(error)^2 / norm(ARIMAoutput_Predict - mean(ARIMAoutput_Predict))^2;
disp('ARIMA模型预测平均绝对误差MAE');
disp(avererror)
disp('ARIMA模型预测平均绝对误差百分比MAPE');
disp(averpererror)
disp('ARIMA模型预测均方根误差RMSE')
disp(RMSE)
disp('ARIMA模型预测均方根误差R2')
disp(R2)
disp('未来年预报')
disp(ARIMAoutput_Forcast)
%% 可视化
figure
plot(ARIMAoutput,':.','linewidth',2);
hold on
plot(data,'g--','linewidth',2);
legend('预测值', '实际值','Location','NorthWest')
title('ARIMA模型预测')
xlabel('时间')
ylabel('结果')
axis tight
hold off
set(gcf,'color','w')
%-------------------------------------------------------------------------------------
figure
subplot(2,1,1)
autocorr(data)
subplot(2,1,2)
parcorr(data)
set(gcf,'color','w')
%-------------------------------------------------------------------------------------
figure()
plot(pererror,'-.','Color',[128 0 255]./255,'linewidth',2)
legend('ARIMA模型预测相对误差','Location','NorthEast','FontName','华文宋体')
title('ARIMA模型相对误差图','fontsize',12,'FontName','华文宋体')
ylabel('误差','fontsize',12,'FontName','华文宋体')
xlabel('样本','fontsize',12,'FontName','华文宋体')
axis tight
set(gcf,'color','w')
%-------------------------------------------------------------------------------------
figure();
histogram(error);
title(['Error Mean = ' num2str(mean(error)) ', Error StD = ' num2str(std(error))]);
xlabel('Error Histogram');
set(gcf,'color','w')
data.xlsx格式如下:
数据 |
---|
112.3 |
118.5 |
132 |
129 |
121 |
135 |
148 |
148 |
136 |
119 |
104 |
118 |
115 |
126 |
141 |
135 |
125 |
表格只有一列数据,第一行为“数据”两字,从第二行开始放入时间序列数据即可!