配电网可靠性预测实战:ARMA/ARIMA建模与电网模型预测要点
简介这份rar压缩包面向电力系统可靠性研究人员与配电网运维工程师围绕配电网可靠性评估与ARMA预测建模问题提供基于MATLAB的源码实现。包内总共只有1个MATLAB脚本文件压缩包约4KB核心代码可用于配电网可靠性指标计算如可用度、可靠度、期望寿命、ARMA模型参数估计、未来故障率预测等任务适合作为配电网可靠性分析的基础工具。已有141人学习下载代码结构清晰便于读者结合配电网负荷、故障等时间序列数据直接运行与二次开发理解从可靠性建模到预测决策的完整流程。通过运行和调试该源码可深入掌握MTBF、MTTR等可靠性指标的计算方法以及ARMA模型在电网故障预测中的实际应用思路为制定预防性维护策略和资源分配方案提供量化依据。1. 配电网可靠性预测为什么绕不开 ARMA先搞清楚这个 rar 里到底在算什么假设你手里有一份配电网过去几年的停电记录领导让你预测未来半年的 SAIDI 或 SAIFI用来排检修计划。很多人第一反应是上机器学习模型但样本量往往只有几十个、上百个点数据还带着明显的自相关和季节性这时候 ARMA 这类经典时序模型反而比复杂模型更稳。标题里的“Reliability_配电网可靠性_配电网_ARMA预测_电网可靠性_电网模型预测_源码.rar”核心就是把配电网可靠性指标变成时间序列用 ARMA 做短期预测再把预测结果喂给电网可靠性评估模型。适合配电网规划、运检、可靠性管理人员以及在做电网模型预测方向的研究生。需要先说清楚ARMA 不是黑匣子用不好第一步就会翻车。2. 配电网可靠性指标和 ARMA 预测的适配关系先把口径和数据结构对齐2.1 可靠性指标先对齐SAIDI、SAIFI、CAIDI 和故障率配电网可靠性不是一个单点概念。实际工程里常见的指标有系统平均停电持续时间指标SAIDI单位是分钟/户·年、系统平均停电频率指标SAIFI单位是次/户·年以及用户平均停电持续时间指标CAIDI等于 SAIDI 除以 SAIFI。做时序预测之前必须先确定你预测的是哪条序列。常见做法是把 SAIDI 或 SAIFI 按年、按季度、甚至按月聚合成等间隔序列。如果是“年”数据通常只有十几个点ARMA 勉强能跑但参数估计方差会很大如果原始数据是每一次停电事件那得先按时间窗口聚合不然序列是稀疏事件计数ARMA 根本没有用武之地。除了指标本身统计口径更要命。有的地区把“停电”定义为用户停电有的定义为线路停电有的只统计故障停电有的把计划停电也纳进去。口径不统一会造成序列断点、阶跃后面的差分和定阶全乱套。我拿到这类源码包时第一步不是看模型而是看数据清洗脚本里有没有统一的停电分类映射表。如果没有宁可自己重写一段也别直接用现成的聚合结果。这是整个方案里最不值得省的时间。2.2 ARMA 能预测什么自相关结构、平稳性和随机扰动ARMA 是自回归移动平均模型它假设当前值由过去的自身值AR 部分和过去的随机误差MA 部分线性组合决定。配电网可靠性序列受设备老化、天气、检修策略影响ARMA 能抓住的是“惯性”如果今年停电多明年也可能多这是 AR 部分在起作用一些突发扰动比如某条馈线雷击跳闸的影响会随月份衰减这是 MA 部分在起作用。但 ARMA 有一个硬前提序列平稳也就是均值、方差在不同时间区间保持稳定。配电网的可靠性序列往往不满足供电可靠性随着网架改造逐年上升均值在漂移停电事件方差也随季节变化。所以源码里通常要先做差分把趋势去掉得到平稳序列后再套 ARMA。这就是 ARIMA带差分项的 ARMA做的事。很多源码包命名为 ARMA其实内部会在平稳化时自动做 d 阶差分本质上已经在跑 ARIMA。2.3 源码包里常见的四个模块数据清洗、平稳化、定阶、回验我看过不少“配电网可靠性 ARMA 预测”的源码包结构上大同小异。一般有一个数据预处理脚本把 Excel 或 CSV 里的停电记录聚合成时间序列做缺失值处理然后是一个平稳化模块用 ADF 检验判断是否平稳接着是定阶模块画 ACF/PACF 图或者用 AIC/BIC 遍历 p、q最后是预测和回验模块把历史数据切成训练集和测试集算 RMSE 或 MAPE。这个套路足够应付绝大多数场景。值得留意的是源码里真正的“电网模型预测”往往不是用 ARMA 直接预测每个用户可靠性而是预测馈线或母线级别的停电频率、故障率再代入可靠性评估公式最小割集法、故障模式影响分析法算出系统级 SAIDI。也就是说ARMA 是上游输入下游才是电网可靠性模型。所以你看源码时要分清预测对象是统计指标还是物理模型参数两者的数据要求完全不同。我一般建议先跑通最小的“数据→ARMA→回验”闭环再决定要不要接评估模型。2.4 数据点太少怎么办年度序列改成月度序列但小心季节性这是很多新手上手才会遇到的坑。如果只有 10 年年度数据总共 10 个点ARMA 的 pq 不可能超过 2否则参数估计方差大到没法看。改成月度序列后10 年有 120 个点可以尝试 ARMA(2,2)模型空间大了很多。但月度数据会引入季节性——每年夏季台风多发7、8 月的 SAIDI 明显偏高。这时候纯 ARMA 会漏掉周期信息需要先用季节差分或者直接上 SARIMA。数据清洗这一步可以直接用代码跑出来。下面这段是我处理停电记录时的最小聚合逻辑import pandas as pd # 原始停电记录每一行是一次停电事件含开始时间、结束时间和停电类型 df pd.read_csv(outage_records.csv, parse_dates[start_time, end_time]) df[outage_duration_min] (df[end_time] - df[start_time]).dt.total_seconds() / 60.0 # 只保留故障停电排除计划停电保证口径一致 fault_df df[df[outage_type] fault].copy() # 假设系统总用户数为 total_users来自可靠性统计年报 total_users 50000 # 按月份聚合计算月度 SAIDI 和 SAIFI fault_df[month] fault_df[start_time].dt.to_period(M) saidi_monthly (fault_df[outage_duration_min] * fault_df[affected_users]) \ .groupby(fault_df[month]).sum() / total_users saifi_monthly fault_df[affected_users].groupby(fault_df[month]).sum() / total_users逻辑说明outage_type字段需要你根据手里的数据字典确认不是每个系统都叫这个名字affected_users是每次停电的受影响户数。聚合到月之后saidi_monthly就是一条以月份为索引的等间隔序列。参数说明total_users要取统计期内固定的系统用户数如果用户数逐年变化最好用当年平均值否则 SAIDI 序列会有虚假的下降趋势。3. 用 Python 跑通 ARMA 预测的源码环境、平稳化、定阶和滚动预测3.1 最小复现环境pandas statsmodels matplotlib不需要深度学习框架也不需要 GPU。建议用 Python 3.9 以上安装 pandas、numpy、statsmodels、matplotlib。statsmodels 的ARIMA类封装了差分、拟合和预测比自己手写 ARMA 公式方便得多。环境装好后第一步不是直接跑模型而是检查版本statsmodels 0.13 以后接口有变化旧接口statsmodels.tsa.arima_model.ARIMA已经移除要改成statsmodels.tsa.arima.model.ARIMA。很多从老源码包里复现的报错都是这个问题。建议用虚拟环境管理依赖requirements.txt 里锁死版本。我习惯这样写pandas1.5,2.0 numpy1.23,2.0 statsmodels0.13,0.15 matplotlib3.6 scipy1.9版本范围是一种妥协pandas 2.0 以后部分 API 行为变了statsmodels 0.15 又调整了一些默认值锁得太死影响兼容不锁又容易出莫名问题。3.2 从原始序列到平稳序列ADF 检验和差分拿到saidi_monthly后先画时序图观察有没有趋势和季节性然后做 ADF 检验。原假设是“序列非平稳”所以 p 值小于 0.05 才说明序列平稳。配电网可靠性序列大多是非平稳的需要差分。import pandas as pd from statsmodels.tsa.stattools import adfuller # 读入上一章聚合好的月度 SAIDI 序列 y saidi_monthly.astype(float).dropna() # 原始序列的 ADF 检验 result adfuller(y) print(ADF p-value:, result[1]) if result[1] 0.05: print(序列非平稳需要差分) # 一阶差分后的 ADF 检验 y_diff y.diff().dropna() result_diff adfuller(y_diff) print(ADF p-value after diff:, result_diff[1])逻辑说明如果差分后 p 值仍大于 0.05可以尝试二阶差分或者先对序列做对数变换再差分。配电网 SAIDI 可能有极端值比如台风月对数变换能压低方差。参数说明adfuller默认自动选择滞后阶数一般不用改如果 p 值在 0.05 附近建议再用 KPSS 检验交叉验证两个检验结论不一致时优先考虑序列里可能有结构突变。3.3 定阶ACF/PACF 和 AIC 网格搜索定阶有两种常见做法。第一种是看 ACF 和 PACF 图PACF 在 lag k 处截尾说明 AR 阶数为 kACF 在 lag k 处截尾说明 MA 阶数为 k。但实际数据往往不典型拖尾截尾不明显。所以更省事的做法是用 AIC/BIC 网格搜索遍历 p、q 取最小信息量准则值。import itertools import statsmodels.api as sm from statsmodels.tsa.arima.model import ARIMA import pandas as pd # 这里的 y 是历史 SAIDI 序列已经确定差分阶数 d1 best_aic float(inf) best_order None best_model None for p in range(0, 4): for q in range(0, 4): if p q 0: continue try: model ARIMA(y, order(p, 1, q)).fit() if model.aic best_aic: best_aic model.aic best_order (p, 1, q) best_model model except Exception: # 某些参数组合会导致协方差矩阵奇异直接跳过 pass print(Best AIC:, round(best_aic, 2), Order:, best_order) # 可以同时看 BIC避免选出过复杂模型 print(Best model BIC:, round(best_model.bic, 2))逻辑说明网格范围 p、q 一般取 0 到 3pq 不超过 3 或 4 比较稳妥。配电网可靠性数据噪声大、样本量有限高阶模型会把噪声当信号学进去。参数说明order(p, d, q)里 d 是差分阶数前面检验后确定为 1这里固定传 1。AIC 适合模型对比但只对同一段训练数据有效如果换了数据区间AIC 不能跨区间比较。3.4 滚动预测和回验别一次性前向预测糊弄自己不少源码包展示效果时用前 80% 数据训练、后 20% 数据一次性预测画出来的曲线难看然后怪模型不行。实际工程里更接近的操作是滚动预测每次只预测一步把真实值加入历史然后重新拟合。配电网可靠性预测通常关心未来 3 到 12 个月所以训练集从起点到当前月预测下个月再把真实值滚进历史。import numpy as np from statsmodels.tsa.arima.model import ARIMA # 假设 y 是已经排好序的月度 SAIDI y_list y.reset_index(dropTrue) n_total len(y_list) n_test 12 # 预测最后 12 个月作为回验 history list(y_list.iloc[:n_total - n_test]) predictions [] for t in range(n_total - n_test, n_total): # 每次都用当前全部历史重新拟合 model ARIMA(history, orderbest_order).fit() pred model.forecast(steps1) predictions.append(pred.iloc[0]) # 滚动真实值进入历史不用预测值填充 history.append(y_list.iloc[t]) actual y_list.iloc[-n_test:].values rmse np.sqrt(np.mean((actual - np.array(predictions)) ** 2)) mape np.mean(np.abs((actual - np.array(predictions)) / actual)) * 100 print(RMSE:, round(rmse, 3)) print(MAPE:, round(mape, 2), %)逻辑说明history存的是原始值ARIMA 内部会自动做差分不要把差分后的序列填进 history否则预测的是差分值的未来而不是 SAIDI 本身。参数说明steps1表示一步预测如果要一次性预测未来 12 个月直接model.forecast(steps12)但那样误差会随步长增大滚动回验的意义就在于模拟真实的月度更新节奏。MAPE 对接近 0 的真实值很敏感某些月份 SAIDI 可能接近 0MAPE 会爆炸所以同时看 RMSE。4. 电网模型预测的正确打开方式把 ARMA 预测结果接回可靠性评估流程4.1 先搞清楚预测对象是故障率、修复时间还是系统指标很多来搜这个标题的人是想“预测电网可靠性”但电网可靠性评估本身是物理模型问题已知元件故障率和修复时间可以用解析法或蒙特卡洛法计算 SAIDI、SAIFI。ARMA 在这里的价值不是替代电网模型而是给模型提供输入——预测未来一段时间内各元件的故障率、平均修复时间。如果直接用 ARMA 预测系统 SAIDI那是把电网模型当成黑匣子模型预测结果和实际电网运行机制脱节一旦网架拓扑变化预测就完全失效。我建议源码包里保留两条路径路径 A 直接预测指标适合快速汇报路径 B 预测元件故障率序列再用可靠性评估公式合成系统指标。路径 B 对电网拓扑变化更敏感比如新投一条线路、加一个联络开关故障率合成关系会变但 ARMA 预测的元件级序列仍然可用。路径 A 一旦遇到拓扑变化历史统计指标本身就不可比模型输出自然是错的。4.2 把故障率预测结果转成 SAIDI 的最小示例用一个简单串联系统举例一条馈线由若干元件构成系统故障率近似等于各元件故障率之和系统平均修复时间按故障率加权。如果 ARMA 预测了每个元件的月度故障率就可以写一个转换函数。import numpy as np import pandas as pd # 三个元件的月度故障率预测来自 ARMA 点预测 lambda_pred pd.DataFrame({ line_1: [0.12, 0.10, 0.11], line_2: [0.08, 0.07, 0.09], transformer: [0.02, 0.02, 0.03] }, index[2025-01, 2025-02, 2025-03]) # 平均修复时间单位小时/次 r_hours {line_1: 2.5, line_2: 3.0, transformer: 8.0} # 串联模型系统故障率元件故障率之和系统修复时间故障率加权平均 lambda_sys lambda_pred.sum(axis1) r_sys sum(lambda_pred[col] * r_hours[col] for col in lambda_pred.columns) / lambda_sys # 简化假设每条馈线带 800 户计算系统月 SAIDI小时/户·月 customers_per_feeder 800 monthly_energy_not_supplied lambda_sys * r_sys * customers_per_feeder saidi_hours monthly_energy_not_supplied / customers_per_feeder print(pd.DataFrame({lambda_sys: lambda_sys, r_sys: r_sys, saidi_hours_month: saidi_hours}))逻辑说明这个示例用串联可靠性模型把元件故障率预测合成到系统级指标。实际配电网是网状结构有分段开关、联络开关、备用容量直接串联会高估故障后果。但作为跑通“ARMA→可靠性指标”的闭环这个转换足以说明问题。参数说明r_hours应该来自历史故障修复时间的统计均值不要用设备铭牌值或厂家理论值因为配电网故障修复受交通、备件、自动化水平影响。如果源码里只有这个简单转换对于复杂网络就不够用了。4.3 协变量要不要进模型气象、负荷、检修计划配电网可靠性受台风、暴雨、高温影响很大。ARMA 本身没有外生变量接口ARMAX 才有。statsmodels 的ARIMA类支持exog参数可以把月降雨量、台风天数作为协变量加入。但我不建议一上来就加协变量原因很实际协变量需要未来值才能预测未来而气象预报本身就有不确定性如果协变量数据不可得或者存在缺失模型输出反而更不可信。如果确实要用下面是最小示例from statsmodels.tsa.arima.model import ARIMA import pandas as pd # y_saidi 是月度 SAIDIrainfall 是同期月降雨量rainfall_future 是未来三个月气象预报值 model_exog ARIMA(y_saidi, order(1, 1, 1), exograinfall).fit() pred_exog model_exog.forecast(steps3, exograinfall_future) print(pred_exog)逻辑说明exog矩阵的行数必须和内生变量y_saidi对齐预测时exog未来值必须给全否则报错。参数说明这里的rainfall可以是月累计降雨量也可以是超过某个阈值的强降雨天数。注意如果未来降雨量本身是预报值那么预测结果的置信区间应该更宽实际使用时要提醒领导这是“基于预报的预测”不是精确结果。4.4 验证预测结果是不是真的能指导运维最后要回答一个现实问题预测出来的下个月 SAIDI 上升 20%你拿它做什么如果是安排配网巡检计划可能需要进一步把系统级预测分解到馈线级找出是哪几条线路故障率上升。ARMA 预测的是整体序列不提供空间分布所以源码包里一般还会做聚类或按历史故障占比分解把系统级预测拆到线路级。这一步容易做成“看着合理但没法落地”因为没有标准分解答案。我的经验是先用系统级预测跑几个月记录预测值和实际值的偏差观察分解误差是否稳定再决定要不要用分解结果指导运维。刚开始就追求馈线级精度大概率会翻车因为馈线级故障率序列更稀疏、更不平稳。5. ARMA 预测配电网可靠性的 5 个常见坑现象、原因和排查清单5.1 坑一直接把 SAIDI 原始序列建模非平稳导致预测漂移现象模型拟合得很好AIC 很低但预测未来 6 个月全是直线或者持续上升和实际走势完全不符。原因SAIDI 序列通常有下降趋势——网架改造、运维水平提升让停电时间逐年减少。非平稳序列的均值在变化ARMA 把趋势当成均值回归的一部分预测时会把趋势无限延伸或者直接回归到一个不存在的均值。解决先做 ADF 检验d 至少取 1。如果序列取对数后更平稳先取 log 再差分。我踩过的坑是只看拟合阶段 R²非平稳序列的拟合误差本来就小真正判断标准是滚动预测的 RMSE。排查的时候画出训练集尾部 20 个点和预测曲线的连接图如果预测直接冲向某个水平线先检查平稳化步骤。5.2 坑二AIC 网格搜索选出的最复杂模型并不抗噪现象网格搜索找到 ARMA(3,3)滚动预测误差反而比 ARMA(1,1) 大很多。原因配电网可靠性数据噪声大、样本量有限高阶模型把随机波动当成了可预测的信号拟合阶段表现好预测阶段完全失灵。解决限制 pq 不超过 3或者用 BIC 作为选择标准BIC 对参数数量惩罚更重。我一般遇到 120 个数据点时最多试 p、q 取 0 到 2如果只有 36 个点干脆用 ARMA(1,1) 或指数平滑别折腾高阶模型。源码里如果 p、q 范围写成 range(0, 7)一定要警惕这个范围适合高频金融数据不适合配电网可靠性。5.3 坑三月度序列里有明显季节性ARMA 扛不住现象每年夏季台风季停电多、冬季负荷高峰也有影响模型在特定月份预测总是偏低。原因ARMA 不处理季节周期月度数据里的 12 阶自相关被错误地归到长周期 AR 项上参数解释混乱。解决把月度序列做季节差分周期 12或者改用 SARIMA在seasonal_order里指定(P,D,Q,12)。源码里如果只用了ARIMA遇到月度数据一定要检查是否包含季节项。如果数据量不足 12 的倍数季节项估计会很勉强那就只能退到年度序列或者把季节项简化成哑变量。5.4 坑四滚动预测窗口和模型重估频率没对齐现象离线滚动预测的误差看起来不错部署到线上后越用越差疑似模型漂移。原因线下滚动预测是每一步都用真实值更新历史线上如果每周重估一次模型但预测目标是未来 4 周的月度指标窗口错位了。更常见的是重估周期写死成“每月 1 日”而数据更新延迟到每月 10 日模型用的历史里永远缺最近一个月。解决线上线下必须用同一套滚动逻辑。源码里把重估周期、数据截止日期、预测步长都配置化每次跑之前先打印“数据截止到 X 月预测从 X1 月开始”。我习惯在预测脚本开头加一行assert data_as_of_month expected_month防止数据没更新就出结果。5.5 坑五把预测结果当精确值汇报不带置信区间现象预测下个月 SAIDI 是 12.3 分钟领导拿去做考核基线结果实际是 18 分钟模型被质疑造假。原因ARMA 预测的是条件期望方差随预测步长增大。配电网可靠性序列受到随机停电事件冲击预测误差在 ±30% 以上是常态。解决汇报时用get_forecast().conf_int(alpha0.2)输出 80% 置信区间对外口径只说“预测区间”不说点预测。源码包里如果只输出点预测一定要补上区间计算。我的经验是点预测用于内部排序决策区间预测用于对外汇报两者分开用互不混淆。5.6 注意代码复现时的“黑匣子”防坑最后一条是工程问题不是模型问题。下载的源码包里如果没有固定随机种子、没有锁版本号、输入数据格式和注释不一致复现结果可能和作者报告完全不一样。先核输入数据 shape 和 dtypes再核对resample的默认行为——pandas 1.x 和 2.x 对重采样的边界处理有差异会导致序列头尾不同。如果源码里用了statsmodels.tsa.arima_model.ARIMA旧接口在 statsmodels 0.13 以后已经移除会直接报错改成statsmodels.tsa.arima.model.ARIMA即可。这类“黑匣子”问题占了调源码时间的一半以上不是你算法不行是环境不一致。6. 进阶残差诊断和模型对比给可靠性预测留一道后悔药ARMA 建模不是拟合完就结束最后一道工序是残差诊断。残差序列必须是白噪声否则说明自相关信息没提取干净模型还有改进空间。用 Ljung-Box 检验最直接from statsmodels.stats.diagnostic import acorr_ljungbox from statsmodels.tsa.arima.model import ARIMA model ARIMA(y_train, orderbest_order).fit() resid model.resid lb acorr_ljungbox(resid, lags12, return_dfTrue) print(lb[lb_pvalue].tail())逻辑说明如果 p 值小于 0.05说明残差仍有自相关当前模型信息提取不完整需要增大 p/q 或考虑季节项。但注意数据量大时 Ljung-Box 容易显著配电网几十个点的数据则不容易检出问题所以要结合残差 ACF 图一起判断。我的习惯是同时维护两个候选模型一个是 AIC 选出的最优模型一个是保守的低阶模型比如 ARMA(1,1) 或 SARIMA(1,0,1)(1,0,0,12)。每周用最新数据重新评估两个模型的滚动预测误差好的上线差的留作备选。一旦上线模型遇到极端天气失灵可以直接切回备选而不是临时改参数。这是我踩出来的教训。之前只看 AIC 选出的模型上线两个月后遇到一场台风预测完全失灵又没有备选模型只能连夜调参非常被动。从那以后我所有可靠性预测脚本里都会加一段模型对比和回退逻辑。这套源码包如果只有单模型预测建议你自己补上这一层。先跑通滚动预测再对照第 5 章的坑排查最后用残差诊断验证这个方向值得投入但每一步都要留一手。希望帮到你。本文还有配套的精品资源点击获取