
干这行的人大概都经历过这个场景导师或者领导丢来一句“用ARIMA做个电价预测顺手把置信区间也算出来”听起来就是个小任务真上手才发现坑比想象中多。电价序列跟股票、气温这些常规时间序列不太一样它有日内双峰、季节性突变、还有极端价格尖峰直接用教科书上的ARIMA四步流程套上去大概率会得到一份“看起来拟合很好、实际预测全偏”的结果。这篇东西就是我实际用Matlab做ARIMA电价预测并计算置信区间的完整记录从数据清洗、定阶、残差诊断到区间计算每一步都说清楚“为什么这么做”以及“哪里容易翻车”希望能帮你少踩几个我已经替你踩过的坑。1. 电价数据的“反常识”特征为什么ARIMA容易水土不服电价预测之所以不能照搬普通时间序列方案是因为电力市场的数据生成机制太特殊了。先从统计特征上把电价的真实面目拆开看你才能理解后面每一步操作的理由。1.1 电价序列的三个统计硬核特征第一个特征是强周期性。居民和工业用电习惯决定了电价有清晰的日内规律——早高峰和晚高峰各出现一次价格爬升凌晨和午后出现低谷。如果用的是小时级或30分钟级数据24小时或48个采样点的周期几乎是铁律如果是工作日数据还会叠加上“周末效应”。这意味着只做一阶差分根本去不干净季节性你需要明确处理周期项。第二个特征是尖峰与厚尾。极端天气、发电机组跳闸、需求突增都会让电价瞬间冲到正常水平的5到10倍然后又快速回落。这些尖峰在数据里表现为明显的异常值不处理的话ARIMA的参数估计会被拉扯得面目全非。有人可能会说“ARIMA对异常值有一定鲁棒性”实际测试下来一个极端尖峰足以让MA项的系数偏移30%以上非常夸张。第三个特征是异方差性通俗说就是“波动率本身在波动”。同等时间段的电价在夏季高温日和温和春秋日其方差可能差出一个数量级。传统ARIMA假设残差方差恒定这个假设在电价数据上天然不成立。所以你在做区间估计时如果还坚持“预测值加减1.96倍标准差”那一套区间要么窄得离谱要么宽得没意义。1.2 ARIMA在电价预测里的定位说了这么多电价的怪脾气那ARIMA是不是就不能用了恰恰相反。我个人的判断是ARIMA或者带季节项的SARIMA在当前电价预测领域里依然是不可绕开的基准模型。原因有三个。第一它的计算速度快一份一万多条的电价序列定阶加估计加预测在Matlab里跑完用不了几秒钟这在需要滚动回测几百上千次的时候优势巨大。第二它的结果可解释你能直接看到AR项、MA项、差分阶数到底在干什么出了问题容易定位。第三也是最重要的任何新方法LSTM、Transformer、XGBoost想证明自己有效都得先跟ARIMA比一场。如果连ARIMA这个baseline都打不过那新方法的说服力就要打个问号。所以我的建议是别把ARIMA当终点但一定要把它当起点。先把ARIMA链路跑通把误差水平摸清楚后面接入机器学习方法时你心里才有底。2. 数据准备阶段公开电价数据集里那些意料之外的脏数据我用的数据是澳大利亚AEMOAustralian Energy Market Operator公开的30分钟级电价数据Matlab加载和处理都方便学术和工程场景里也很常见。这个数据集免费、无需注册、数据量大非常适合学习和复现你在官网按区域和时间范围筛选下载CSV即可。拿到数据以后绝对不能直接进入建模环节你至少要学会识别并处理这三类问题。2.1 时间戳与缺失值的处理细节AEMO下载下来的CSV时间字段格式是“yyyy/mm/dd hh:mm:ss”。很多人第一步就栽在这用readtable读进来以后发现时间是字符串直接用不行。你需要先转成datetime格式再按采样间隔补齐时间轴data readtable(price_data.csv); t datetime(data.TradingInterval, InputFormat, yyyy/MM/dd HH:mm:ss); price data.RRP; % 按固定30分钟间隔生成完整时间轴 t_full (t(1):minutes(30):t(end));补齐时间轴以后缺失值就显形了。这里有第一个容易翻车的地方不能随便用线性插值去填缺失电价。因为电价有日周期相邻时刻的均值还可能掩盖尖峰特征比较稳妥的做法是“同周期中位数替换”——比如缺失值发生在中午12点就用过去若干天中午12点的价格中位数来填。Matlab里先按时刻分组统计中位数再替换效率也很高。如果缺失的是一个很长的连续时间段比如某天的数据全没了那我的经验是直接删除这一段而不是硬插。长段连续缺失即使插值出来也大概率与实际的供需规律不符留着只能污染模型参数。2.2 异常值和极端尖峰的清洗策略电价数据里一定有极端值但这不代表所有极端值都是“脏数据”。2019年南澳地区出现过接近14000澳元/MWh的极端尖峰这种价格是真实发生的市场结果但你如果拿它直接训练ARIMA模型大概率会被这一个点带偏代价是牺牲正常价格区间内的预测精度。我推荐的办法是Hampel滤波器配滚动中位数。它会计算每个点与窗口内中位数的偏离程度偏离超过若干倍绝对中位差MAD的才被判定为异常然后自动用中位数替换。Matlab自带hampel函数用起来非常方便% 窗口大小设为1443天的30分钟点阈值设为5倍MAD [price_clean, ~, ~] hampel(price, 144, 5);阈值选5倍比较稳妥如果选3倍真实的价格尖峰也会被过滤掉一部分——你需要分清楚自己是“建模需要”还是“分析需要”。另外做这一轮清洗要保留处理日志记录哪个时间点被替换、替换值是多少方便后面追溯。千万别静悄悄地改数据否则后面做结果分析时你根本解释不清模型的误差来自哪里。2.3 要不要做对数变换取决于你是否遇到负电价常规时间序列教程都会建议对强波动的数据做log或Box-Cox变换来稳定方差。但在电价预测领域这条建议要打个问号。原因很简单不少电力市场的实时电价会出现负值风电大发、需求极低时发电商宁愿贴钱卖电换取不停机。负值没法取对数强行平移会扭曲数据的相对幅度关系。我的习惯是这样先看一眼数据范围和分布。如果价格全为正且动态范围很大比如从20到10000可以做log变换预测完再指数还原。如果数据里有负电价那就不做变换直接用原始值建模但要在残差诊断环节更加小心异方差问题。如果你的预测目标是“价格等级”而不是“具体数值”也可以尝试分箱处理不过这就超出ARIMA的常规范畴了这里不展开。3. 定阶与参数估计统计检验 信息准则双管齐下ARIMA模型的完整记法是ARIMA(p,d,q)三个参数分别代表自回归阶数、差分阶数、移动平均阶数。如果考虑季节性还要多一组(P,D,Q,m)。电价数据通常需要先做一次非季节性差分再做一次季节性差分针对24小时或48个采样点周期也就是d1D1m24或48。3.1 差分阶数ADF检验和眼睛看的不一样很多时候画个图你就能判断电价序列“大概”非平稳但具体差分几次统计检验仍然有必要。Matlab里自带adftest函数[d1, pval1] adftest(price_clean); % 若pval1 0.05说明不平稳需要一阶差分 if pval1 0.05 d1_series diff(price_clean); [d2, pval2] adftest(d1_series); end注意这里的坑是电价的“非平稳”很可能主要表现在周期和日内模式上而不是在趋势上。所以你做一阶差分后会看到序列仍然有明显的周期波动这时候就要考虑季节性差分而不是继续做二阶差分。二阶差分会白白损失大量信息还容易造成过度差分over-differencing。识别季节周期的办法很直白对一阶差分后的序列画自相关图autocorr看看在第24阶、第48阶、第168阶如果按小时计就是24、168有没有显著的相关峰值。如果ACF在这几个滞后阶附近出现明显的非零值那就说明周期成分残留需要做季节性差分或建模季节项。3.2 定p、q阶时AIC和BIC怎么权衡确定完了d和D接下来是定p、q、P、Q。理论上的规范流程是观察ACF和PACF图的截尾和拖尾模式判断用AR还是MA。但真实电价数据的ACF/PACF通常“拖尾拖得乱七八糟”人的眼睛很难判断。我的做法是直接跑网格搜索用AIC和BIC做自动定阶% 设置搜索范围 pRange 0:5; qRange 0:5; results table(); for p pRange for q qRange mdl arima(p, 1, q); [est, ~, logL] estimate(mdl, price_diff, Display, off); [aic, bic] aicbic(logL, p q 1, length(price_diff)); results [results; table(p, q, aic, bic)]; end end % 按BIC排序取最小的模型 results sortrows(results, bic);BIC的惩罚项比AIC重选出来的模型更简洁不容易过拟合。电价数据量通常上万条AIC倾向于选一个非常复杂的模型预测时反而泛化能力差。所以我默认按BIC选除非业务上你特别看重样本内拟合的细节。这里还有一个容易犯的错搜索模型的阶数时arima的输入数据应该是已经完成季节差分和普通差分后的平稳序列。如果你直接把原始序列传给arima(p,1,q)又在外面套一个季节性差分那实际上就变成重复差分模型结构就错了。正确的做法是先用diff和lag做差分得到平稳序列再把它传给估计函数。或者直接用arima的seasonality参数Matlab里arima支持Seasonality选项把季节周期交给模型自己处理但要小心参数数量会急剧增加。3.3 参数估计的初值和收敛问题Matlab的estimate函数默认使用条件最小二乘Conditional Least Squares作为初值估计再用最大似然Maximum Likelihood精调。大多数序列都能顺利收敛但如果你在估计时碰到“Optimization terminated”不收敛的警告通常有两个原因一是差分后序列还有残余的季节性二是搜索到的p、q过高导致模型参数过多。解决的办法也很简单把搜索范围从0:5缩小到0:3或者把数据标准化。另外Matlab的arima支持你手动指定初值mdl arima(ARLags, 1:2, MALags, 1, Constant, 0);指定ARLags而不是简单写p2可以让你只选择特定的滞后阶数有时候比全阶模型效果好得多。比如电价数据常常是高阶AR主导你想用AR(1)AR(2)AR(24)那就可以用这种写法精确指定滞后项减少自由参数模型更稳定。4. 残差诊断模型建得好不好都得看它脸色模型估计完很多人看一眼拟合图就宣布大功告成这是大忌。ARIMA的信条是“残差必须是白噪声”否则你的参数估计、预测区间都是不可信的。残差诊断是决定模型能否用于预测的关键门槛。4.1 白噪声检验Ljung-Box的核心用途Matlab里最方便的是lbqtest函数res infer(est, price_diff); [h, p] lbqtest(res, Lags, [5 10 15 20], Alpha, 0.05);如果p值小于0.05说明残差在对应滞后期上仍存在显著的自相关模型还没有把信息提取干净。这时候最常见的处理是加大p或q或者把季节性差分阶数加多。但更常见的情况是——残差的自相关主要出现在季节性滞后处比如第24阶附近的Q统计量显著这时候加普通p、q阶没用需要增加季节项阶数P和Q或者在建模前把日内周期消除得更彻底。如果Ljung-Box检验“过了”也不要高兴太早。电价序列频率高、数据量大Q统计量有时候会因为样本量太大而“过度敏感”——本来无伤大雅的微小相关性也被判定为显著。我的经验是不要只盯着p值0.05的生死线要结合ACF图看相关性幅度。如果ACF在某个滞后期虽然显著但相关系数绝对值不到0.05那基本可以忽略反之如果相关系数又大又呈现周期性那就必须处理。4.2 正态性检验电价残差几乎不可能正态既然要做置信区间很多人会顺手用jb检验看看残差是否正态。我可以给你个剧透电价序列的残差99%是不正态的。JB检验的p值通常会小到一个不可思议的程度这是因为厚尾和尖峰天然把正态假设破坏了。这里的关键分岔是你打算用什么方法构造置信区间。如果你坚持用传统的“预测值±1.96×标准差”你就是在隐含地假设残差正态这个假设越不成立你的区间就越失真。如果你愿意改用经验分位数法构造区间那正态性就不是前提条件了。所以我的建议是别在这个环节浪费精力“试图让残差变得正态”而是把你的区间构造策略整体切换到更稳健的方法上去这正是下一节的核心内容。4.3 条件异方差看见ARCH效应别慌电价残差还有个毛病就是波动的“成群性”平静的时候残差一直很小遇到尖峰事件时残差连续好几期都很大。这种条件异方差可以通过archtest检验捕捉到。如果你检验发现残差存在显著的ARCH效应从工程角度给出两个选择一是接受它。如果你的最终目标是点预测不是区间预测ARCH效应对点预测的影响远不如对区间的影响大。二是升级为ARIMA-GARCH模型用GARCH来描述残差的波动变化。但代价是模型复杂度上升不少且GARCH的估计对异常值敏感你前面清洗阶段没做干净的话这里会非常痛苦。我个人的取舍标准是如果只是常规日度预测和调度参考ARIMA就够用区间不够准的问题通过经验分位数法补足。如果你的场景涉及电价波动率衍生品定价或者极端风险度量那才需要认真考虑ARIMA-GARCH以及更极端的极值理论模型。5. 置信区间计算的真实实现路径别死磕正态区间置信区间是这篇研究的重头戏。但坦白讲Matlab的arima模型自带forecast函数输出的区间工程上不太实用。下面直接对比三种方案你按场景选。5.1 Matlab自带置信区间的局限Matlab的forecast函数可以同时输出预测值和预测均方误差MSE传统做法是[Y_hat, YMSE] forecast(est, h, Y0, price_diff); lower Y_hat - 1.96 * sqrt(YMSE); upper Y_hat 1.96 * sqrt(YMSE);这套逻辑的风险我前面已经铺垫过了YMSE是在模型误差为正态白噪声的假设下推导出来的电价残差不满足这个条件所以你画出来的区间大概率过窄尤其对尖峰时刻的覆盖能力很差。另外这个误差只考虑了模型动态结构产生的误差完全忽略了参数估计误差——样本量不足时参数估计误差带来的不确定性会被严重低估。但它的优点是计算快、无偏性理论上说得过去所以适合大样本下做粗筛、快速看个大概区间。如果你数据有几万条且预测步长比较短用这个方案也不是不可以。5.2 残差经验分位数法工程上的务实之选我目前在项目里实际使用的是经验分位数法。思路非常简单把模型在训练期内的残差序列收集起来然后直接取它的历史分位数作为预测不确定性的经验估计。res infer(est, price_diff); % 取训练残差的2.5%和97.5%分位数 lower_q quantile(res, 0.025); upper_q quantile(res, 0.975); lower Y_hat lower_q; upper Y_hat upper_q;这种做法本质上是在说“模型的历史预测误差是怎么分布的未来大概率也类似”。它完全不依赖正态性假设对厚尾、偏态数据适应得非常好。实测下来经验分位数区间的覆盖率实际价格落在区间内的比例通常比正态区间高出5到10个百分点。这里有个细节值得注意如果你想提高覆盖精确度可以考虑按预测步长分别取分位数。比如预测未来24步那就把训练集中所有“第1步预测残差”收集起来取分位数所有“第2步预测残差”单独取分位数以此类推。这样得到的区间能更真实地反映“越往远期预测不确定性越大”的自然规律代价是需要做一轮滚动建模来收集分步残差计算时间会增加但结果会让你觉得值得。5.3 蒙特卡洛模拟法最灵活但最慢的备选还有一种思路是直接利用估计出的模型参数和残差分布蒙特卡洛模拟未来路径rng(123); numPaths 2000; simPaths simulate(est, h, NumPaths, numPaths, Y0, price_diff); lower_sim quantile(simPaths, 0.025, 2); upper_sim quantile(simPaths, 0.975, 2);模拟法能轻松处理非线性变换如果你做了log或Box-Cox变换模拟以后还需要还原和更复杂的误差分布设定。缺点是慢——2000条路径跑24小时预测在普通电脑上也要走到秒级如果做滚动回测几百次时间成本就挺直观了。我的最终建议是常规场景优先使用经验分位数法它兼顾了计算速度和区间可靠性如果你需要的是事前风险分析或极端情况压力测试再去上模拟法。正态区间可以作为快速参照但不要作为结论。6. Matlab核心代码骨架从estimate到forecast的完整链路讲了这么多原理和取舍下面把整套代码串起来给你一个可以直接复现的骨架。数据用前面说的AEMO公开电价或者你本地任意小时级电价序列做24小时预测。6.1 训练/测试集划分与模型训练% 加载并清洗数据 data readtable(price_data.csv); t datetime(data.TradingInterval, InputFormat, yyyy/MM/dd HH:mm:ss); price data.RRP; [price, ~] hampel(price, 144, 5); % 划分训练集和测试集留出最后24小时做验证 horizon 48; % 30分钟粒度预测未来24小时就是48步 trainPrice price(1:end-horizon); testPrice price(end-horizon1:end); % 一阶差分平稳化 trainDiff diff(trainPrice); % 定阶利用前面搜索的记录比如BIC优选得到 p2, q1 mdl arima(2, 1, 1); est estimate(mdl, trainDiff, Display, off); % 残差诊断 res infer(est, trainDiff); [h, p] lbqtest(res, Lags, [5 10 15 20]);模型训练完先别急着预测把残差图、ACF图画出来看一眼。只有Ljung-Box检验通过、ACF没有明显周期性的模型才值得继续往下走。否则回头调整p、q不要带着病上路。6.2 24小时预测与经验区间计算% 预测未来48步24小时 [Y_hat, ~] forecast(est, horizon, Y0, trainDiff); % 还原差分得到电价预测值 % 这里要小心差分预测还原需要累积加上训练集最后一个真实值 lastVal trainPrice(end); Y_hat_price lastVal cumsum(Y_hat); % 经验分位数区间 lower_q quantile(res, 0.025); upper_q quantile(res, 0.975); lower_price Y_hat_price lower_q; upper_price Y_hat_price upper_q; % 可视化 figure; plot(t(end-horizon*21:end), price(end-horizon*21:end), k-, LineWidth, 1); hold on; plot(t(end-horizon1:end), Y_hat_price, b-, LineWidth, 1.5); plot(t(end-horizon1:end), lower_price, r--, LineWidth, 1); plot(t(end-horizon1:end), upper_price, r--, LineWidth, 1); legend(实际电价, 预测电价, 95%下界, 95%上界);这里有几个操作细节值得专门说关于差分还原如果你对序列做了一阶差分预测结果必须做累积和才能回到价格水平。一个很常见的bug是预测出来以后直接当电价用导致预测曲线整体偏移一个常数。上面的lastVal cumsum(Y_hat)就是干这个活的。如果你用的是log变换记得还要取指数exp()还原顺序别弄反。关于Y0参数Matlab的forecast函数的Y0参数要求的是差分后序列的最后若干值不是原始电价。很多人在这里传错了导致预测结果完全对不上。一个稳妥的办法是Y0传递trainDiff的最后max(p,q)个值让模型有足够的记忆长度。关于区间可视化如果要把区间画成阴影带而不是上下两条线可以用fill或patchxfill [t(end-horizon1:end); flipud(t(end-horizon1:end))]; yfill [lower_price; flipud(upper_price)]; fill(xfill, yfill, [0.9 0.9 0.9], EdgeColor, none, FaceAlpha, 0.4);填充色建议用浅灰色或者浅蓝色透明度调到0.3~0.4既不遮挡实际曲线又看得清楚不确定性范围。6.3 预测效果评估RMSE、MAE和覆盖率区间计算出来以后还需要一个客观评估判断区间到底有没有用。我的做法是同时报告三个指标指标公式说明RMSEsqrt(mean((Y_test - Y_hat).^2))点预测精度的主指标大误差惩罚重MAEmean(abs(Y_test - Y_hat))对尖峰不敏感的平均误差区间覆盖率mean(Y_test lower Y_test upper)区间是否“包得住”真实值rmse_val sqrt(mean((testPrice - Y_hat_price).^2)); mae_val mean(abs(testPrice - Y_hat_price)); coverage mean(testPrice lower_price testPrice upper_price); fprintf(RMSE: %.2f, MAE: %.2f, Coverage: %.2f%%\n, rmse_val, mae_val, coverage * 100);区间覆盖率的目标应该接近95%如果你用的经验分位数是2.5%/97.5%理论上覆盖率就是95%。实际数据里因为模型设定误差覆盖率可能偏低比如落在90%~93%左右这时候我会把分位数适当放宽到1%、99%来重新标定。7. 滚动回测框架评估模型真实泛化能力的关键动作不少初次接触这个方向的同学喜欢拿最后一段数据做一次预测就算完事画出来的图“预测和实际挺像”就认为建模成功了。这在统计上有一个巨大的陷阱如果你只是幸运选中了一段电价平稳、无重大突变的时段你的评估分数会好得反常但同一套模型放到下一周可能一塌糊涂。应对办法是在完整的时间轴上做滚动预测回测。7.1 滚动窗口设计具体操作是设定一个固定长度的训练窗口比如过去30天或者60天每次只预测未来24小时然后窗口向前滑动一个预测步长比如24小时重复训练和预测。假设你有90天的数据预测最后30天那你需要训练30次模型。Matlab循环实现并不复杂但计算时间会明显拉长如果每次定阶搜索都做完整的网格遍历总耗时可能会到分钟级建议在滚动回测时固定p、q用第一段数据选好参数即可不再重新搜索。% 滚动回测伪代码 trainDays 30; step 1; % 每天滚动一次 for startIdx 1:step:(length(price) - trainDays*48 - horizon) trainData price(startIdx : startIdx trainDays*48 - 1); testData price(startIdx trainDays*48 : startIdx trainDays*48 horizon - 1); % 建模、预测、评估 % ... results(i, :) [rmse_val, mae_val, coverage]; end滚动回测能暴露模型在不同市场环境下的稳定性比如风季和用电旺季的误差差异如果某几个窗口误差突然放大你需要回头检查是不是遇到了节假日或者极端天气事件然后再决定是否需要引入外部变量来修正预测。7.2 滚动结果的三个观察角度跑完回测我一般会看三样东西第一误差分布的中位数而不是平均值因为少数极端行情会把平均误差拉得很高中位数更能反映“平常状态下的水平”第二覆盖率的稳定性如果大部分窗口覆盖率都在90%以上但个别窗口掉到50%说明区间在某些场景下会严重失准第三是否有误差自相关如果第t天预测误差偏大第t1天大概率也偏大这说明你没有把波动率聚集效应建模进去可以考虑用GARCH类模型做残差修正。另外提醒一句滚动回测的结果要谨慎地与更简单的基准方法对比特别是上一周平均电价或昨日同时刻电价Naive方法。如果ARIMA连这种无脑基准都赢不了你就要认真考虑这套模型在当前数据上是否有价值了。8. 经验与补充几个常被忽略但影响结论的地方前面几节基本把从数据到模型的完整链路讲完了最后再集中说几个我踩过、而且周围同行也反复踩的坑算是额外的经验补充。8.1 节假日效应是置信区间失准的头号元凶电价在公共假日的模式和普通工作日完全不同——工业负荷下降需求曲线整体下移日内峰值也会变平。如果训练集包含大量普通工作日节假日期间预测误差会系统性偏大经验区间覆盖不到真实值。处理办法是在建模前把节假日从训练集中剔除或者单独为节假日建立一个简化模型。更省事的办法是预测之前先判断预测日是否为节假日如果是直接用历史同类型日的中位数曲线做预测不给ARIMA添乱。8.2 连续输入的真实电价数据单位统一很重要AEMO的电价单位是澳元/MWhRRP字段国内电力市场可能用元/MWh国外其他数据集可能用欧元/MWh。拿到数据第一件事先看单位预测结果如果不是用于学术对比而是工程调度单位的错误换算可能直接导致重大偏差。另外注意时区问题Matlab读入时间戳时如果时区设置不对预测的日内峰值时段会整体平移几个小时看起来像是模型预测不准实际上是你把时间轴搞偏了。8.3 置信区间用于业务决策时建议叠加安全裕度不管是做售电公司购电成本预测还是做电力现货交易的风险控制单纯依赖95%置信区间上限作为采购预算都是不够稳妥的。统计区间只描述了模型内部的不确定性但市场环境突变、规则调整、极端天气这些“模型之外”的因素并没有被纳入。我的做法通常是在区间上界再叠加一个比例裕度比如5%~10%作为内部可执行的上限参考。这个裕度不属于统计范畴属于业务风险偏好的设定需要跟业务方达成一致不可混为一谈。以我个人的使用体感来说ARIMA加经验分位数区间这套组合在当前的电价预测基准测试里依然是性价比最高的方案之一。它既能给出稳定可靠的点预测也能在区间上覆盖大多数常规风险场景。想继续往下提升精度下一步无非就是两个方向要么加入外生变量气温、负荷预测值、发电结构做成SARIMAX或回归ARIMA要么把点预测模型换成梯度提升树或深度学习然后用同样的经验分位数思路构造区间。无论走哪个方向你今天在这套ARIMA链路上积累的数据清洗、定阶、残差诊断和区间构造经验都是可以直接迁移过去的基础设施。