文章目录
前言一、示例二、代码实现----Matlab全部数据的平稳性检验ADF检验图检验法 划分训练集平稳性检验确定 p,q结果分析和模型检验模型预测
前言
接上一篇博客,用 Matlab 完成代码编写。
【学习笔记】时间序列模型(ARIMA)
一、示例
已知一个上市公司一段时期的开盘价,最高价,最低价,收盘价等信息,要求建立模型,预测股价。这里只需要股票的收盘价(close),我们可以把数据提取出来,并划分为训练集和测试集本题我们把1-3月份的数据作为训练集,4-6月份的数据作为测试集二、代码实现----Matlab
全部数据的平稳性检验
%% 数据读取% 读取 CSV 文件filename = 'ChinaBank.csv';data = readtable(filename);% 读取文件中的两列close_data = data.Close;date_data = data.Date;% 一阶差分close_dif1 = diff(close_data);% 二阶差分close_dif2 = diff(close_data, 2);% 创建一个新的图形窗口并设置其大小figure('Position', [100, 100, 1200, 1000]); subplot(3, 1, 1);plot(date_data,close_data); title('原始数据');xlabel('日期');ylabel('收盘价');% 绘制一阶差分数据subplot(3, 1, 2);plot(date_data(2:end), close_dif1);title('一阶差分');xlabel('日期');ylabel('差分值');% 绘制二阶差分数据subplot(3, 1, 3);plot(date_data(3:end), close_dif2);title('二阶差分');xlabel('日期');ylabel('差分值');
运行结果:
结果分析:
可以看出,一阶差分和二阶差分后,平稳性变好。
ADF检验
Matlab 的 adftest
函数
[h, pValue, stat, cValue] = adftest(y);
返回值解释
h
:检验结果
h
是一个逻辑值,表示检验结果:
1
:拒绝原假设(即,时间序列是平稳的)。0
:无法拒绝原假设(即,时间序列可能存在单位根或是非平稳的)。 pValue
:p 值
pValue
是一个实数,表示检验统计量的 p 值。p 值越小,拒绝原假设的证据越强。通常,如果 p 值小于某个显著性水平(如 0.05),则拒绝原假设。
stat
:检验统计量
stat
是一个实数,表示 ADF 检验的统计量。这个值用于与临界值进行比较,以决定是否拒绝原假设。
cValue
:临界值
cValue
是一个向量,包含不同显著性水平(如 1%、5%、10%)下的临界值。用于与统计量 stat
进行比较。
Matlab 代码
% 进行ADF检验[h, pValue, stat, cValue] = adftest(close_data);% 显示结果disp(['ADF 检验结果: ', num2str(h),' ','p 值: ', num2str(pValue),' ','统计量: ', num2str(stat),' ','临界值: ', mat2str(cValue)]);
运行结果:
结果分析:
ADF 检验结果为 0,则无法拒绝原假设,表示时间序列可能是非平稳的。p 值为 0.96618,大于 0.05,无法拒绝原假设。统计量为 1.485,大于临界值 -1.9416,无法拒绝原假设。图检验法
原始数据% 计算并绘制自相关函数(ACF)figure('Position', [100, 100, 1200, 700]); subplot(2, 1, 1);autocorr(close_data, 20);title('自相关函数(ACF)');% 计算并绘制偏自相关函数(PACF)subplot(2, 1, 2);parcorr(close_data, 20);title('偏自相关函数(PACF)');
运行结果:
结果分析:
ACF中,大部分的值没有落在置信区间内,所以不具有平稳性。
一次差分% 计算并绘制自相关函数(ACF)figure('Position', [100, 100, 1200, 700]); subplot(2, 1, 1);autocorr(close_dif1, 20);title('自相关函数(ACF)');% 计算并绘制偏自相关函数(PACF)subplot(2, 1, 2);parcorr(close_dif1, 20);title('偏自相关函数(PACF)');
运行结果:
结果分析:
由图形可以看出,大部分的值都落在了置信区间内。
划分训练集
train = close_data(1:62);test = close_data(63:127);
平稳性检验
ADF检验
原训练集% 进行ADF检验[h, pValue, stat, cValue, reg] = adftest(train);% 显示结果disp(['ADF 检验结果: ', num2str(h),' ','p 值: ', num2str(pValue),' ','统计量: ', num2str(stat),' ','临界值: ', mat2str(cValue)]);
运行结果:
平稳性并不理想,所以考虑一次差分。(和python运行出来的结果不一致,此处存疑)
train_dif1 = diff(train);% 进行ADF检验[h, pValue, stat, cValue, reg] = adftest(train_dif1);% 显示结果disp(['ADF 检验结果: ', num2str(h),' ','p 值: ', num2str(pValue),' ','统计量: ', num2str(stat),' ','临界值: ', mat2str(cValue)]);
运行结果:
通过平稳性检验。
图检验法
原训练集% 计算并绘制自相关函数(ACF)figure('Position', [100, 100, 1200, 700]); subplot(2, 1, 1);autocorr(train, 20);title('自相关函数(ACF)');% 计算并绘制偏自相关函数(PACF)subplot(2, 1, 2);parcorr(train, 20);title('偏自相关函数(PACF)');
运行结果:
平稳性并不理想,所以考虑一次差分。(和python运行出来的结果不一致,此处存疑)
训练集进行一次差分% 计算并绘制自相关函数(ACF)figure('Position', [100, 100, 1200, 700]); subplot(2, 1, 1);autocorr(train_dif1, 20);title('自相关函数(ACF)');% 计算并绘制偏自相关函数(PACF)subplot(2, 1, 2);parcorr(train_dif1, 20);title('偏自相关函数(PACF)');
运行结果:
通过平稳性检验。
确定 p,q
1. 相关函数法
由训练集一次差分后的 ACF 和 PACF 图可以看出,呈现不规则衰减,p 、q的值难以直接判断。
2. AIC、BIC准则
% 定义候选模型阶数范围maxP = 8;maxQ = 8;n = length(train);% 初始化结果存储aicValues = NaN(maxP, maxQ);bicValues = NaN(maxP, maxQ);% 迭代计算所有候选模型的AIC和BIC值for p = 0:maxP for q = 0:maxQ try Mdl = arima(p,1,q); [~,~,logL] = estimate(Mdl, train, 'Display', 'off'); numParam = p + q + 1; % p个AR参数, q个MA参数, 1个差分项 [aicValues(p+1, q+1),bicValues(p+1, q+1)] = aicbic(logL, numParam, n); catch % 忽略无法估计的模型 continue; end endend% 找到AIC最小值对应的(p, q)[minAIC, idxAIC] = min(aicValues(:));[pAIC, qAIC] = ind2sub(size(aicValues), idxAIC);pAIC = pAIC - 1;qAIC = qAIC - 1;% 找到BIC最小值对应的(p, q)[minBIC, idxBIC] = min(bicValues(:));[pBIC, qBIC] = ind2sub(size(bicValues), idxBIC);pBIC = pBIC - 1;qBIC = qBIC - 1;fprintf('AIC选择的模型阶数: p = %d, q = %d\n', pAIC, qAIC);fprintf('BIC选择的模型阶数: p = %d, q = %d\n', pBIC, qBIC);
运行结果:
姑且先选择 AIC 准则的结果:p = 7,q = 6。此处存疑
结果分析和模型检验
残差序列的随机性可以通过自相关函数法来检验,即做残差的自相关函数图
model = arima(7,1,6);md1 = estimate(model, train, 'Display', 'off');% 检查残差的自相关性residuals = infer(md1, train);figure;autocorr(residuals);title('Residuals Autocorrelation');
运行结果:
结果分析:从 ACF 图中可以看出残差之间独立性比较高。
模型预测
numPeriods = length(test);[Y, YMSE] = forecast(md1, numPeriods, 'Y0', train);origin_close = close_data(1:127);origin_date = date_data(1:127);% 绘制预测结果与真实值的比较figure('Position', [100, 100, 1200, 700]); plot(origin_date,origin_close, test_date, Y);legend('真实值','预测值');title('ARIMA 模型预测结果');xlabel('时间');ylabel('值');
运行结果:
向后预测了三个月的数据。
代码改进见博客:
时间序列模型(ARIMA) — — 预测未来(含 python 和 Matlab 的完整代码)