ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

时间序列分析实战:从平稳性检验到ARIMA建模与预测

时间序列分析实战:从平稳性检验到ARIMA建模与预测 简介这是一份以时间序列分析为主题的文档型学习资源适合经济学、统计学相关专业学生或对 ARIMA 建模感兴趣的初学者用于课程论文参考与方法入门。文中以我国 1980—2012 年全社会固定资产投资额为研究对象系统介绍了从数据平稳性检验、ADF 单位根检验、差分处理、模型识别到参数估计与残差白噪声检验的完整实证流程并借助 Eviews 软件建立 ARIMA(4,1,3) 模型对 2013 年投资额进行预测。资源共 1 个 doc 文件包体约 1.05MB内容包含摘要、引言、模型原理、实证过程和结论可帮助读者快速理解针对单变量时间序列的建模步骤与论文写作思路。文档目前已有 253 人学习浏览适合用作课程论文写作、时间序列入门练习或投资分析与宏观经济学讨论的辅助材料。全文配有数据表格、时序图及单位根检验结果结构清晰可作为实证研究写作的直观模板。1. 时间序列分析不检验平稳性后面全是花架子拿到一个名为“时间序列分析小论文.doc”的文件时多数人第一反应是去看结论而我会先翻它如何处理平稳性。实际工作里导致预测翻车的往往不是模型不够高级而是把非平稳数据直接塞进ARIMA的拟合函数——这在statsmodels里连个警告都不会有只会默默吐出一份虚高的R²。时间序列分析的核心是顺序依赖今天和昨天、上个月和这个月之间究竟存在什么关系。无论做能源负荷预测、Web访问量监控还是收益率建模第一步都是同一件事确认数据的统计性质随时间是否稳定。这里就按一线工程师做这类分析的常规路径把从平稳性检验到模型定阶再到输出一份能当小论文用的研究报告的全过程讲透包含可直接运行的代码和参数选择逻辑。2. 时间序列分析的平稳性ADF检验与ACF/PACF定阶2.1 为什么先看白噪声而不是直接建模时间序列分析里的“平稳”从来不意味着曲线平缓而是指统计特性不随平移改变均值恒定、方差有限、自协方差只依赖于时间差。严格意义的强平稳要求所有高阶矩都不变工程上通常只要弱平稳对ARIMA类模型来说弱平稳就足够支撑参数估计和假设检验了。一个反直觉的点在于很多人以为做差分只是为了消除趋势其实差分同时也在处理方差的非恒定。单位根检验ADF本质上问的是“这个序列是否包含随机游走成分”。如果ADF的p值大于0.05不能拒绝存在单位根的原假设就需要对序列做至少一阶差分。先搞清楚数据是趋势平稳还是差分平稳再决定后续操作这才是时间序列分析的正确入口。2.2 用ADF检验判断是否继续差分2.2.1 Python里跑ADF的最小示例import numpy as np import pandas as pd from statsmodels.tsa.stattools import adfuller # 模拟一段非平稳数据随机游走 线性趋势 np.random.seed(42) n 300 trend 0.1 * np.arange(n) noise np.random.normal(sizen) series pd.Series(np.cumsum(noise) trend) # 对原始序列跑ADF检验 result adfuller(series, autolagAIC) print(fADF统计量: {result[0]:.3f}) print(fp值: {result[1]:.3f}) print(f使用滞后阶数: {result[2]}) # 一阶差分后再跑一次 result_diff adfuller(series.diff().dropna(), autolagAIC) print(f差分后ADF统计量: {result_diff[0]:.3f}) print(f差分后p值: {result_diff[1]:.3f})adfuller的autolag控制滞后阶数的选择方式AIC表示自动选取让信息准则最小的滞后数。输出里的第三项对应回归中实际用到的lags。如果一阶差分后的p值降到0.05以下就可以认为序列已经平稳。注意dropna不能省diff()产生的第一个NaN会让后续检验报错。2.2.2 ADF检验的3个必调参数参数取值作用autolagAIC/BIC/t-stat决定最优滞后阶数直接影响检验功效maxlagNone或整数限制最大滞后搜索范围样本量小时设10以内更稳regressionc/ct/cttc带常数ct带趋势项ctt带二次趋势选择regressionct的典型场景是数据有明显线性上升或下降。如果趋势存在却用c单位根检验的功效会下降本来平稳的数据也可能被判成非平稳。反之对纯净的随机游走引入趋势项会过度拟合。这个参数没有绝对标准两个都跑一遍是常见做法。2.3 ACF与PACF定阶前先看图ADF只回答“要不要差分”差分阶数确定之后用自相关函数ACF和偏自相关函数PACF看截尾和拖尾是传统时间序列分析里定阶的第一步。from statsmodels.graphics.tsaplots import plot_acf, plot_pacf import matplotlib.pyplot as plt diff_series series.diff().dropna() fig, axes plt.subplots(2, 1, figsize(8, 4)) plot_acf(diff_series, axaxes[0], lags20) plot_pacf(diff_series, axaxes[1], lags20) plt.tight_layout() plt.show()lags控制在多少阶以内画图。样本量小于300时lags超过n/4就没有统计意义。ACF拖尾、PACF在1阶截尾对应AR(1)ACF在1阶截尾、PACF拖尾则是MA(1)。手看图适合简单情形一旦数据混入季节周期或跳变就必须靠信息准则兜底这也是下一章要解决的问题。3. ARIMA与SARIMA的定阶从自相关图到信息准则的完整链路3.1 差分阶数d与数据性质的关系ARIMA(p,d,q)里最容易被忽略的是d。d1表示一阶差分用来去掉线性趋势d2表示在差分结果上再差分一次适合带加速或减速特征的数据。但d越大方差膨胀越明显预测区间也会越来越宽。因此能用d1解决就不要用d2。判断d的辅助手段是看差分数列的标准差如果一阶差分后的标准差明显大于二阶差分那d2可能更合适。更稳妥的做法是同时比较ADF的p值和后续模型的AIC大小。注意对趋势平稳序列做差分并不会导致错误但会丢失部分长期信息这也是为什么有些场景下改用SARIMAX带外生趋势变量效果更好。3.2 用网格搜索自动定阶3.2.1 遍历p、q并记录AIC的代码from statsmodels.tsa.arima.model import ARIMA import warnings warnings.filterwarnings(ignore) best_aic float(inf) best_order None # 对一阶差分后的数据做网格搜索 for p in range(0, 4): for q in range(0, 4): try: model ARIMA(series, order(p, 1, q)) result model.fit() if result.aic best_aic: best_aic result.aic best_order (p, 1, q) except Exception: continue print(f最优阶数: {best_order}, AIC: {best_aic:.2f})这里把原始序列直接传给ARIMA内部会按order里的差分参数自动处理。p和q枚举到3通常覆盖了大多数业务数据的ARMA部分。一旦遇到收敛失败跳过比硬调参数更快因为statsmodels里部分阶数组合确实会出现奇异矩阵。网格搜索的步长可以拆成两轮第一轮粗扫第二轮在最优值附近细化。3.2.2 参数选择为什么AIC比BIC更激进准则惩罚强度在时间序列分析中的典型用途AIC2k适合短序列预测倾向选更多参数BICk*ln(n)长样本下偏好精简模型解释性更强HQIC2k*ln(ln(n))介于两者之间较少直接用于定阶样本量超过500时AIC和BIC选出的模型差别不大样本只有几十个点的时候AIC有高估阶数的风险。写小论文时建议同时打印AIC和BIC用BIC最小对应的阶数作为最终方案因为评阅人会质疑参数冗余。AIC更偏向预测精度而BIC更偏向结构简洁。3.3 季节差分和SARIMA当ACF在滞后12、24的位置出现明显峰值说明存在年季节周期。月点击量数据的周期是12周数据则为7。SARIMA的表示是ARIMA(p,d,q)(P,D,Q,m)其中m是周期长度。seasonal_model ARIMA(series, order(1, 1, 1), seasonal_order(0, 1, 1, 12)) seasonal_result seasonal_model.fit() print(seasonal_result.summary())seasonal_order里的最后一位12指月度数据周期。D1表示做一阶季节差分作用是消除季节性的非平稳。如果数据里同时存在趋势和季节普通差分和季节差分都要做。误把季节差分当成普通差分处理会导致模型里d和D产生重复计算参数估计方差也会变大。4. 用statsmodels从数据准备到预测输出一份可直接抄的完整流程4.1 构造时间索引是最容易出错的一步时间序列分析里50%的报错来自索引没有正确解析。从CSV读进来的日期列默认是字符串直接设置成索引会导致asfreq和shift全部失效。常见做法是用to_datetime先转换再用set_index。对月度数据我会显式指定freqMS否则数据看起来有索引内部却认为没有固定频率预测时的steps也会对不上。df pd.read_csv(page_views.csv) df[date] pd.to_datetime(df[date]) df.set_index(date, inplaceTrue) df df.asfreq(MS) # 月度开始频率 series df[views].astype(float) # 检查缺失值和异常值 print(series.isna().sum()) print(series.describe())asfreq(MS)会把索引规整为每月第一天并把缺失日期填成NaN。后续的填充和插值必须在这一步之后做因为差分和ACF计算遇到NaN会直接返回空结果。astype(float)的作用是防止整型数据在后续差分运算中产生意外溢出。4.2 训练集/测试集划分与滚动预测4.2.1 固定切分 一步预测from statsmodels.tsa.arima.model import ARIMA train series.iloc[:-24] # 留出最后24个月 test series.iloc[-24:] model ARIMA(train, order(1, 1, 0), seasonal_order(0, 1, 0, 12)) result model.fit() forecast result.forecast(steps24) mae (forecast - test).abs().mean() print(fMAE: {mae:.2f})这里的forecast(steps24)输出的是点预测不更新参数。测试集里的真实值不会反馈回模型。如果想让模型在预测第t2个月时使用第t1个月的真实观察值需要用append做扩展窗口预测。固定切分适合快速验证最终结论建议用滚动预测。4.2.2 结果输出成DataFrame方便写进小论文output_df pd.DataFrame({ date: test.index, actual: test.values, forecast: forecast.values }) output_df.to_csv(forecast_result.csv, indexFalse)导出成CSV后在Word或Excel里都能轻松排版。注意forecast.values的长度必须等于steps不一致时用forecast.index重建对齐关系。等到写文档时这个CSV可以直接作为插入表格的数据源避免手动复制小数点。4.3 残差检验判定模型是否可用的关键指标检验原假设程序中的函数结论判断Ljung-Box残差无相关性acorr_ljungboxp0.05通过Jarque-Bera残差正态jarque_bera不通过时看QQ图均值检验残差均值为0直接计算mean绝对值小于0.001即可from statsmodels.stats.diagnostic import acorr_ljungbox resid result.resid lb_test acorr_ljungbox(resid, lags[12], return_dfTrue) print(lb_test)如果Ljung-Box的p值小于0.05说明残差里还有自相关这时的预测置信区间是不准确的。遇到这种情况应该回到上一章的网格搜索把p、q范围扩大重新拟合。真正能写进论文的结论是残差足够接近白噪声模型结构已经涵盖了数据中的时间依赖。提示Ljung-Box的lags可以用列表同时多测几个阶数例如lags[6, 12, 24]。只看一个lag容易漏掉长周期残留。5. 时间序列分析里的真实数据缺失值、异常值和对标模型5.1 缺失值不是用均值填就行的时间序列的缺失值和普通表格不一样均值填充会极大压缩方差让ACF产生虚假强相关。线性插值适合趋势明确的数据但遇到季节性数据还是会有毛刺。更常规的做法是前向填充加季节性修正。对月度带季节性的数据我会手工计算最近3年同月的均值补进去。填充方式适用场景风险均值填充无季节性短序列压缩方差ACF失真线性插值趋势明显、无周期数据周期边界处偏差大同季均值月度/季度数据季节稳定季节变化时反应滞后ffill高频数据短期缺口延长平台期引入惯性series_with_season series.fillna(methodffill)对高频数据来说ffill最直观但连续填充超过3个点就要谨慎。缺失比例超过30%时任何填充方式都会失真这时候应该考虑是否合并更细粒度的数据而不是强行补点。5.2 异常值识别用残差标准差做阈值时间序列分析中的异常值常被误判成真实变化。一种有效做法是先跑一次初步模型把残差3倍标准差之外的点当作异常值替换成预测值再重新拟合。positive (resid 3 * resid.std()) negative (resid -3 * resid.std()) outliers resid.index[positive | negative] cleaned series.copy() cleaned[outliers] result.fittedvalues[outliers]这里用result.fittedvalues能避免人为改变趋势走向。注意重新拟合时要把series换成cleaned否则修改没有意义。阈值取2倍标准差会比3倍更敏感但也会把正常的波动点误伤在业务场景里我会先标出异常点让业务方确认后再决定是否替换。5.3 对标SimpleExpSmoothing和Prophet做时间序列分析小论文时不能只拿一个ARIMA模型就说它最好。至少建两个基线模型一个指数平滑一个带季节的Naive。像下面这样对比MAE才站得住脚。from statsmodels.tsa.holtwinters import ExponentialSmoothing hma ExponentialSmoothing(train, trendadd, seasonalmul, seasonal_periods12) hma_fit hma.fit() hma_forecast hma_fit.forecast(24) print(fARIMA MAE: {mae:.2f}) print(fHolt-Winters MAE: {(hma_forecast - test).abs().mean():.2f})seasonalmul适用于季节振幅随时间增大的数据比如访问量逐年增长、峰值也越来越高振幅稳定时选add。Prophet的处理逻辑与statsmodels不同它把趋势和季节分解得更彻底但本质上还需要通过add_seasonality指定周期和ARIMA的m参数异曲同工。把这三个模型的MAE并排放在表格里小论文才算有对比意识。6. 把时间序列分析结果写进小论文三步收尾技巧6.1 用滚动预测检验模型稳定性一次性切出测试集只能得到一个MAE看不出模型在哪个时段失效。按步长1个月滚动能直观看到误差的离散程度。history train.tolist() rolling_mae [] for t in range(len(test)): model ARIMA(history, order(1, 1, 0)) fit model.fit() pred fit.forecast(steps1)[0] rolling_mae.append(abs(pred - test.iloc[t])) history.append(test.iloc[t]) print(f滚动MAE均值: {np.mean(rolling_mae):.2f}) print(f滚动MAE标准差: {np.std(rolling_mae):.2f})滚动预测的标准差如果远大于均值说明模型在某个时间点产生了系统性偏差需要检查该时段是否有大促、断网或口径调整这类事件。6.2 把置信区间画成论文可用的图直接用matplotlib默认样式画图在Word里会显得很像草稿。我会把95%置信区间画成透明带状图图例标明实际值和预测值字体统一Times New Roman或宋体。import matplotlib.pyplot as plt pred_result result.get_forecast(steps24) mean pred_result.predicted_mean ci pred_result.conf_int() plt.figure(figsize(10, 4)) plt.plot(test.index, test.values, o-, labelactual, markersize3) plt.plot(test.index, mean, s-, labelforecast, markersize3) plt.fill_between(test.index, ci.iloc[:, 0], ci.iloc[:, 1], alpha0.2, label95% CI) plt.legend() plt.savefig(forecast_plot.png, dpi300, bbox_inchestight)conf_int()返回的是上下界DataFrame共有两列。fill_between要求横轴长度一致先确认test.index的长度为24。dpi300是期刊插图的最低要求直接截图插入会模糊。6.3 生成带格式的Word段落最终交的是doc文档不是代码文件。最简单的方式是用pandas把关键数字汇总成一个摘要表再在Word里插入表格。评阅人最想看到的是四项内容平稳性结论、选定阶数的理由、残差检验的p值、预测精度对比。把这些数字填进实验对比表比任何长篇解释都更有说服力。最后记得把dpi300的图插入Word并在附录里保留可复现的数据预处理脚本。本文还有配套的精品资源点击获取
返回列表