3-预测模型

📅 2026/8/22 9:46:53
3-预测模型
总览类别常见模型主要适合什么情况回归预测线性回归、多元回归、多项式回归、Ridge、Lasso、Elastic Net已知影响因素 (X)预测连续结果 (Y)时间序列预测移动平均、指数平滑、ARIMA、SARIMA、VAR有连续多年的历史数据主要利用时间规律灰色预测GM(1,1)、灰色 Verhulst样本很少、数据不充分增长曲线预测指数模型、Logistic、Gompertz人口、市场规模、技术扩散等有增长上限状态转移预测Markov 链预测“状态如何变化”机器学习预测SVR、随机森林、XGBoost、LightGBM非线性、变量较多、关系复杂深度学习预测MLP、RNN、LSTM、GRU、TCN、Transformer数据较多、时序关系复杂机理预测微分方程、差分方程、系统动力学已知系统运行机制组合预测加权组合、Stacking、ARIMAMLP 等单一模型各有优缺点希望提高稳定性时间序列预测自回归移动平均模型ARMA自回归积分滑动平均模型ARIMA季节性自回归积分滑动平均模型SARIMA向量自回归模型VAR广义自回归条件异方差模型GARCHProphet长短期记忆网络LSTM门控循环单元GRU贝叶斯结构时间序列模型BSTS序列到序列模型Seq2SeqARIMA自回归积分滑动平均模型过去的数据过去的预测误差→预测未来单变量时间序列预测模型ARIMA 模型的三个主要参数分别是p自回归项数AR用自己的过去几期的数据预测自己的未来。d差分次数I对原序列进行几次差分q移动平均项数MA使用多少个历史预测误差即 MA 阶数修正模型是差分后的结果是AR系数MA 系数当前预测误差c常数项也可以理解为差分序列的漂移差分的目的是减弱趋势使时间序列更加平稳。序列数值表示的含义原始序列[100,110,125,145]每个月实际销量一阶差分[10,15,20]每个月销量增加多少二阶差分[5,5]销量增量增加多少训练代码初始化误差为0↓根据误差估计参数↓根据参数重新计算误差↓再根据新误差估计参数↓不断重复预测代码读取模型参数↓取得历史差分值和历史误差↓使用AR项和MA项预测下一期差分值↓把预测值加入历史继续多步预测↓未来未知误差设为0↓得到所有未来差分预测↓通过累计和还原差分↓返回原始尺度预测结果越向未来预测使用的预测值越多因此不确定性通常也会逐渐增大pdq参数怎么确定1d差分次数一般只尝试012需要差分后数值基本都不变必须是平稳过程平稳性要求序列的均值和方差不发生明显变化严平稳序列所有的统计性质(期望方差)都不会随着时间的推移而发生变化宽平稳期望与相关系数(依赖性)不变就是说 t 时刻的值 X 依赖于过去的信息通常采用图检验法(通过时间序列趋势图或者自相关函数图判断) 或ADF 检验p0.052pAR阶数可以通过偏自相关函数 PACF 初步判断PACF 在第1阶后接近0考虑p1。PACF 在第2阶后接近0考虑p2。PACF 缓慢下降可能还需要MA项。一般0123qMA阶数可以通过自相关函数 ACF 初步判断ACF 在第1阶后接近0考虑q1。ACF 在第2阶后接近0考虑q2。ACF 缓慢下降可能还需要AR项。一般0123acf和pacf计算x[t-2] ─────────→ x[t] 直接影响 x[t-2] → x[t-1] → x[t] 间接影响对比项ACFPACF中文名称自相关函数偏自相关函数衡量内容当前值与历史值的总体相关性排除中间期后的直接相关性包含间接影响直接和间接只有直接影响常用于判断MA阶数qAR阶数p模型特征ACF表现PACF表现初步判断AR(p)拖尾在第p阶后截尾用PACF判断pMA(q)在第q阶后截尾拖尾用ACF判断qARMA(p,q)拖尾拖尾需要进一步搜索所以去找pacf和acf在那一阶截尾acfpacfYule-Walker方程或Durbin-Levinson算法3如果acf和pacf判断pq有好几个候选值可以用aicbic最优模型选择方法1、aicbic从训练集的训练误差就可以近似测试误差AIC和BIC是在已经训练好的不同模型里面筛选出相对最好的那个模型与之对应的是L1 L2正则化训练过程中减少参数防止过拟合。适合统计学习2、第二类是重复抽样法即通过训练集多次切分、抽样来模拟训练集、验证集计算多个“样本外误差”比如交叉验证Cross Validation、自助法Bootstrap适合机器学习1.AICAIC -2In(L) 2k其中L指对应的最大似然函数k指对应的模型的变量的个数。2.BICBIC -2In(L) In(n)*kn指对应的数据数量L和k同上所述。kln(n)惩罚项在维数过大且训练样本数据相对较少的情况下可以有效避免出现维度灾难现象。通过网格搜索AICBIC越小越好。4最后残差检验残差是不是接近白噪声如果残差还有明显规律说明模型还有信息没学到。只使用 NumPy 实现一个教学版 ARIMA(p, d, q) 模型。 import numpy as np def difference(series, d): 进行 d 阶差分并保存每一阶序列供预测后还原。 levels [np.asarray(series, dtypefloat)] for _ in range(d): levels.append(np.diff(levels[-1]))#计算相邻元素之差 return levels # levels [原始序列,一阶差分,二阶差分] def build_design(values, errors, p, q):#values:差分后的时间序列errors:残差p:AR阶数q:MA阶数 构造 [常数项, p 个历史值, q 个历史误差] 的回归矩阵。 start max(p, q)#从同时拥有足够AR历史值和MA历史误差的第一个时间点开始训练 rows [] targets [] for t in range(start, len(values)): ar_terms [values[t - i] for i in range(1, p 1)]#获取 AR 项 ma_terms [errors[t - i] for i in range(1, q 1)]#获取 MA 项 rows.append([1.0] ar_terms ma_terms) #[1.0,values[1],values[0],errors[1]] targets.append(values[t]) return np.asarray(rows), np.asarray(targets), start def fit_arima(series, p2, d1, q1, max_iter1000, tolerance1e-8): 使用迭代条件最小二乘法拟合教学版 ARIMA。 series np.asarray(series, dtypefloat) if series.ndim ! 1: raise ValueError(series 必须是一维时间序列) if min(p, d, q) 0: raise ValueError(p、d、q 不能小于 0) levels difference(series, d)#进行差分 values levels[-1]#获取最后一阶差分序列levels[-1] levels[2] start max(p, q) if len(values) start: raise ValueError(时间序列太短无法拟合当前的 p、d、q) # MA 项依赖未知误差先将误差初始化为 0再反复估计参数和误差。 errors np.zeros(len(values)) parameters np.zeros(1 p q)#里面装着常数项、p 个 AR 系数和 q 个 MA 系数 for iteration in range(1, max_iter 1): old_parameters parameters.copy()#保存上一轮参数 design, targets, start build_design(values, errors, p, q)#design引入误差 parameters np.linalg.lstsq(design, targets, rcondNone)[0]#用最小二乘计算根据误差估计参数 # 根据新参数按时间顺序重新计算残差。 new_errors np.zeros(len(values)) for t in range(start, len(values)): ar_terms [values[t - i] for i in range(1, p 1)] ma_terms [new_errors[t - i] for i in range(1, q 1)] features np.asarray([1.0] ar_terms ma_terms) fitted_value features parameters new_errors[t] values[t] - fitted_value#根据参数重新计算误差 errors new_errors if np.max(np.abs(parameters - old_parameters)) tolerance:#判断是否收敛 break fitted_mse float(np.mean(errors[start:] ** 2))#mse return { parameters: parameters, p: p, d: d, q: q, levels: levels, errors: errors, iterations: iteration, mse: fitted_mse, } def forecast(model, steps): 预测未来 steps 期并把差分预测还原到原序列尺度。 if steps 0: raise ValueError(steps 必须大于 0) p, d, q model[p], model[d], model[q] parameters model[parameters] history list(model[levels][-1])#差分结果 error_history list(model[errors]) differenced_forecasts [] for _ in range(steps):#每次预测一个未来时间点 ar_terms [history[-i] for i in range(1, p 1)]#取最近的ar值 ma_terms [error_history[-i] for i in range(1, q 1)]#取最近的误差 features np.asarray([1.0] ar_terms ma_terms) next_value float(features parameters) differenced_forecasts.append(next_value) history.append(next_value) # 未来误差的条件期望为 0。假设刚生成的参数没有误差 error_history.append(0.0) restored np.asarray(differenced_forecasts) # 从第 d 阶差分逐层累加还原为原始序列。 for level in range(d - 1, -1, -1): last_value model[levels][level][-1] restored last_value np.cumsum(restored) return restored def main(): # 某商品连续 36 个月的销量。 sales np.array( [ 120, 124, 127, 133, 136, 142, 145, 149, 155, 158, 164, 168, 171, 177, 181, 186, 190, 195, 199, 205, 208, 214, 219, 223, 228, 234, 238, 243, 247, 253, 258, 262, 267, 273, 277, 282, ], dtypefloat, ) # ARIMA(2, 1, 1)2 个 AR 项、1 阶差分、1 个 MA 项。 model fit_arima(sales, p2, d1, q1) future_sales forecast(model, steps6) parameters model[parameters] print(模型ARIMA(2, 1, 1)) print(f常数项{parameters[0]:.6f}) print(AR 系数, np.round(parameters[1:3], 6)) print(MA 系数, np.round(parameters[3:], 6)) print(f迭代次数{model[iterations]}) print(f差分序列拟合 MSE{model[mse]:.6f}) print(未来 6 个月预测销量, np.round(future_sales, 2)) if __name__ __main__: main()(base) PS D:\桌面\华为杯\code d:/Users/anaconda3/python.exe d:/桌面/华为杯/code/预测模型/arima.py 模型ARIMA(2, 1, 1) 常数项10.840752 AR 系数 [-0.950221 -0.37474 ] MA 系数 [0.220189] 迭代次数22 差分序列拟合 MSE0.589162 未来 6 个月预测销量 [286.62 291.2 295.96 300.56 305.24 309.91]SARIMALSTM