ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

变压器故障诊断系统实战:基于DGA数据与随机森林的机器学习实现

2026/9/11 5:40:53 拓冰建站 浏览量
变压器故障诊断系统实战:基于DGA数据与随机森林的机器学习实现 简介面向人工智能课程作业与毕业设计场景这份变压器故障诊断系统资料提供了完整源代码、说明文档与配套数据集。系统覆盖数据读取、诊断逻辑到前端展示的闭环流程适合计算机、自动化、电子信息等专业学生用于课程设计、项目答辩或初期立项演示代码经测试运行成功作者也提供远程教学支持可降低上手门槛。资源包共8个文件以4个HTML页面承担可视化交互界面1个XLSX数据集含240余条样本作为诊断依据另有PNG示意图与README说明文档辅助理解整体压缩包仅173KB轻量易部署。已有282人学习下载反馈良好。下载后可依据README快速上手通过首页与查询页面直观查看故障诊断效果亦可基于现有代码修改扩展满足个性化课设或毕设需求。1. 做人工智能作业最容易被扣分的环节不是模型准确率做人工智能作业最容易被扣分的环节不是模型准确率而是评审或同学拿到源代码后无法复现。变压器故障诊断系统是这类作业里很典型的分类选题变压器内部出现放电或过热时绝缘油会分解出多种特征气体把气体浓度整理成特征向量交给机器学习模型即可判断设备处于正常、局部放电、低能放电、高能放电或过热等状态。适合正在做课程设计的学生也适合刚接触设备状态维护的工程师练手。我一般会先定下交付边界源代码、文档说明、数据集三样必须放在一起确定主入口脚本和数据路径相对固定。这样别人跑通的时间不会超过十分钟作业才算真正完成。2. 变压器故障诊断系统的数据准备DGA 特征、数据集划分和标签不平衡处理2.1 用油中溶解气体数据做故障诊断为什么 DGA 特征是标配变压器绝缘油在电、热、氧化作用下会分解出 H₂、CH₄、C₂H₆、C₂H₄、C₂H₂、CO、CO₂ 等气体。行业里把这类数据统称为 DGADissolved Gas Analysis。传统的 IEC 三比值法会先把气体浓度换算成三组比值再查表得到故障类型但查表规则来自经验边界遇到混合故障时经常落在表外的组合上。机器学习模型可以直接从浓度和比值中学习非线性边界所以现在的课程设计和大作业普遍把 DGA 原始浓度作为输入。特征气体主要关联故障物理线索H₂局部放电、低能放电低能量放电最先产生氢气CH₄、C₂H₆中低温过热油热裂解初期产物C₂H₄高温过热温度越高乙烯比例越大C₂H₂高能放电、电弧电弧产生大量乙炔CO、CO₂固体绝缘分解涉及纸绝缘时明显升高这张表不必让模型记住但它是做数据清洗和结果解释的参考。比如某条样本的乙炔浓度很高却被模型判为正常这时候先回查这列原始值是否在录入时被置 0 或换了单位否则先调模型没有意义。单位统一也很关键有的数据源用 μL/Lppm有的用 mg/L模型只看数值换单位会让训练好的模型直接失效。我一般在预处理脚本里统一转成 μL/L并在数据集说明里写清单位。2.2 构造可复现的 CSV 数据集与读取代码课程作业里最省事的整理方式是一张 CSV 一个故障标签列。示例数据长这样h2,ch4,c2h6,c2h4,c2h2,co,co2,fault_label 156.2,28.3,14.1,44.6,0.0,53.0,510.0,1 210.0,45.1,25.7,80.3,0.0,120.0,620.0,3 78.5,12.4,8.2,30.1,56.3,88.0,400.0,4fault_label 用数字编码具体映射写到文档说明里避免中文列名引发的编码问题。读取和划分代码如下import pandas as pd from sklearn.model_selection import train_test_split df pd.read_csv(data/processed/dga_dataset.csv, encodingutf-8) print(df[fault_label].value_counts()) features [h2, ch4, c2h6, c2h4, c2h2, co, co2] X df[features] y df[fault_label] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) print(X_train.shape, X_test.shape)read_csv 的 encoding 参数不要省略很多 Windows 导出的 CSV 实际是 GBK/GB18030直接读会抛 UnicodeDecodeError。这里统一用 utf-8若遇到编码错误就改用 encodinggb18030 处理。stratifyy 是分层抽样能保证训练集和测试集中每类故障的比例与原数据集一致如果省略这参数恰好把样本数很少的低能放电全部切到测试集训练环节的模型会彻底看不到该类别后面调参也救不回来。random_state42 只用于复现不是固定要求但要在文档说明中写清楚否则换台机器每次结果不同作业会被质疑。2.3 处理类别不平衡分层划分与 class_weight 的取舍实际积累的变压器故障样本通常很不均衡正常样本占七成以上局部放电、低能放电这类样本可能只有几十条。分层抽样解决的是“划分比例不一致”不能改变原始分布。最简单有效的办法是让训练算法感知少数类sklearn 里常见做法是设置 class_weightbalanced。以随机森林为例from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier( n_estimators200, class_weightbalanced, random_state42 )class_weight 接收三种常见取值None 表示所有类别权重相同balanced 会自动按样本量反比计算权重样本越少的类权重越高也可以传一个字典手动指定例如想特别关注低能放电就把对应权重调大。需要说明的是如果训练集只有几十条故障样本过重的权重会让模型记住少数字符验证时反而更差。我一般不会在样本量低于 20 的类别上过度调权重而是先看混淆矩阵确认这个类是否真的能被气体特征区分。SMOTE 类过采样方法也可以做但要谨慎它会在少数类样本之间插值可能产生现实中不存在的浓度组合比如同时出现极高乙炔和极低氢气这种样本在 DGA 场景下物理上很可疑。所以先尝试 class_weight再决定要不要引入过采样。3. 用随机森林与逻辑回归实现变压器故障诊断分类器3.1 特征矩阵设计气体浓度归一化与比值特征扩展直接使用 7 种气体浓度时各列量纲差异很大氢气可能从 5 到几千二氧化碳从几百到上万。随机森林、梯度提升这类树模型不关心量纲逻辑回归、神经网络则强烈依赖输入尺度。为了让一份代码兼容多种模型我通常先把浓度列做 RobustScaler再扩展一组比值特征。比值特征参考 DGA 领域的经验规则能放大类别差异from sklearn.preprocessing import RobustScaler X X.copy() X[ratio_ch4_h2] X[ch4] / (X[h2] 1e-6) X[ratio_c2h4_c2h6] X[c2h4] / (X[c2h6] 1e-6) X[ratio_c2h2_c2h4] X[c2h2] / (X[c2h4] 1e-6) scaler RobustScaler(quantile_range(5.0, 95.0)) X_scaled scaler.fit_transform(X)分母加 1e-6 只是防止除零不能替代缺失值处理如果原始浓度列本就有 0加小常数后比值会是 0不会报错但可能掩盖“气体未检出”这个信息。加比值特征对逻辑回归尤其有效因为它能更快拟合不同故障的气体比例关系。RobustScaler 使用中位数和四分位距对 DGA 数据里的高浓度离群点比 StandardScaler 稳。fit_transform 里的参数 quantile_range 默认是 25 到 75我改成 5 到 95 是为了在存在大量 0 值时不把尺度压得过小。注意必须在训练集上先 fit再 transform 训练集和测试集不能对测试集单独 fit否则数据泄露会让评估结果虚高。3.2 训练与评估随机森林参数和混淆矩阵解读核心训练代码尽量独立成脚本方便在作业文档里贴同一段。随机森林适合 DGA 数据的原因是特征数不多但每列都有实际物理含义树模型能自动处理浓度阈值和交互关系并且推理极快适合演示。推荐参数如下from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, ConfusionMatrixDisplay model RandomForestClassifier( n_estimators300, max_depth8, min_samples_leaf2, class_weightbalanced, n_jobs-1, random_state42 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(classification_report(y_test, y_pred)) ConfusionMatrixDisplay.from_predictions(y_test, y_pred).plot()n_estimators 在 200 到 400 之间通常就能收敛再增大只增加模型体积和预测耗时作业演示不需要 1000 棵树。max_depth8 限制单棵树深度防止树记住某些样本的唯一浓度组合。min_samples_leaf2 保证叶子节点不止一个样本对小样本故障类更稳。n_jobs-1 使用全部 CPU 核在只交作业的本机环境没问题若部署到服务器需考虑资源占用。class_weight 在类别不平衡场景下必须保留否则模型会牺牲少数类换取整体准确率。课程里常拿逻辑回归做对照实验。逻辑回归训练更快超参数少但需要归一化特征且对非线性关系拟合能力弱。两者对比通常会出现这样的趋势随机森林整体准确率和少数类召回都更容易调高逻辑回归在干净数据集上推理时间更短但容易把低能放电和高能放电混淆。对比表格可以写进文档说明对比维度随机森林逻辑回归特征尺度不敏感需要归一化小样本类别class_weight 后仍可用权重敏感容易欠拟合训练速度较慢很快推理速度毫秒级微秒级误诊常见模式低能/高能放电混淆低压放电误判为正常在作业里应优先把随机森林作为主模型再用一份比例抽样数据或同特征数据跑逻辑回归作为对照。如果两者结果完全一致反而要检查是不是标签编码、特征选择或数据读取过程中无意间引入了同样的错误。评估时不要只看 accuracy对故障诊断来说某类故障的召回率比整体准确率更重要漏掉一个高能放电的代价远高于多报一次正常维护。3.3 GridSearchCV 调参的三个必看参数调参不用手工试每一组用 GridSearchCV 搜索最关键的三个参数即可。对于 DGA 这种小特征集重点看 n_estimators、max_depth、min_samples_leaffrom sklearn.model_selection import GridSearchCV param_grid { n_estimators: [200, 300], max_depth: [6, 8, 10], min_samples_leaf: [1, 2, 4] } grid GridSearchCV( RandomForestClassifier(class_weightbalanced, random_state42), param_grid, cv5, scoringf1_macro, n_jobs-1 ) grid.fit(X_train, y_train) print(grid.best_params_)scoring 不推荐选 accuracy因为数据本身不平衡。f1_macro 对每个类分别计算 F1 再取平均适合关注少数类的场景若希望更贴近“漏报比误报严重”可以改用 recall_macro或干脆定义带权重的自定义 scorer。cv5 是分层交叉验证已经是大多数课程的默认要求。搜索结束后用 grid.best_estimator_ 在测试集上评估而不是直接用网格搜索结果中的 best_score_因为那是在验证折上的分数不是没见过的数据。4. 把源代码、文档说明和数据集整理成可直接运行的人工智能大作业4.1 目录结构与 requirements.txt评审老师会先看这里代码写得再清楚如果目录乱评审仍会认为不可复现。我一般用最朴素的目录结构不引入训练框架普通 Python 环境即可跑transformer_fault_diagnosis/ ├── data/ │ ├── raw/ # 原始 DGA 数据 │ └── processed/ # 清洗后的 CSV ├── models/ # 输出 pkl 模型 ├── src/ │ ├── data_preprocess.py │ ├── train.py │ └── predict.py ├── docs/ │ ├── README.md │ └── algorithm.md ├── config.yaml └── requirements.txtdata/raw 和 data/processed 分开是个好习惯。原始数据一旦被脚本改写就失去了可追溯性processed 目录内容是清除缺失值、统一单位、完成标签编码之后的结果。models 目录必须存在即使里面只有一个随机森林 pkl 文件也能让作业“训练—保存—加载—预测”的链路完整。requirements.txt 不需要锁定精确版本但至少要指定主版本pandas1.5 scikit-learn1.2 matplotlib3.6 pyyaml6.0如果直接把 pandas2.2.2、scikit-learn1.4.2 锁死在别的机器上可能因 Python 版本不匹配报没有对应 wheel。对课程作业来说给最低版本加 已经足够。安装命令写在 README 最前面pip install -r requirements.txt。个别环境需要用 pip3要与 Python 版本一起写清楚。4.2 文档说明的算法卡片与实验记录怎么写文档说明不是把代码注释复制一遍而是回答“这是什么、用什么算法、输入输出是什么、结果如何”。我习惯在 docs/algorithm.md 里放一张算法卡片字段内容任务类型变压器故障多分类DGA输入特征H2, CH4, C2H6, C2H4, C2H2, CO, CO2 及 3 个比值标签编码0 正常1 局部放电2 低能放电3 高能放电4 过热主模型随机森林class_weightbalanced对照模型逻辑回归RobustScaler 后训练数据规模数据集文件 data/processed/dga_dataset.csv评估方式分层划分 80/205 折交叉验证F1-macro运行命令python src/train.py --model rf --cv 5运行命令这一项必须实际测过。很多作业只写“运行 train.py”但没写参数怎么传也没有前置步骤。写成带命令行参数的形式更清楚python src/train.py --model rf --cv 5 --output models/rf.pkl python src/predict.py --model models/rf.pkl --input data/processed/dga_dataset.csv --output result.csv命令行参数建议用 argparse 实现参数名与 README 保持一致。train.py 里至少接受 --model 选择 rf 或 lr--cv 指定交叉验证折数--output 指定模型保存路径predict.py 接受 --model、--input、--output。文档里再补一段实验记录写清每次改动对应的准确率、召回率、参数变化。这样源代码、文档说明与数据集三个交付物形成了对应关系即使原始报告写得简单评审也知道每个文件是干什么的。4.3 数据集打包时的坑编码、缺失值与脱敏数据集文件名不要用“最终版”“最新版”这类带个人色彩的命名作业提交后一旦改名代码里的路径立刻失效。打包前先在脚本里检查数据质量df.info() print(df.isna().sum()) print(df.duplicated().sum()) for col in [h2, ch4, c2h6, c2h4, c2h2, co, co2]: df[col] df[col].fillna(df[col].median())fillna 用中位数而不是均值是因为 DGA 数据常见个别极高浓度均值会被拉偏。遇到缺失比例超过 30% 的气体列不要直接填充应先回查原始记录确认该气体是未检测而不是设备故障。重复样本需要单独处理如果两条样本来自不同设备同一时刻不应直接删除如果完全相同的记录出现多次则可能是复制录入错误。脱敏是常被忽略的一环CSV 里不能保留设备编号、变压器型号、变电站名称等可识别信息统一替换成 anonymous_id。小数据集不需要任何鉴权但要确保压缩包解压路径不含中文和空格Windows 下尽量避免把代码放在带空格的目录里运行。5. 变压器故障诊断系统的验证技巧用交叉验证和混淆矩阵定位误诊5.1 用 cross_val_predict 获得稳定预测训练集和测试集的一次划分可能受随机种子影响报告里写“准确率 95%”但换 random_state 后变成 90%。更稳的做法是用交叉验证预测每个样本的类别再做混淆矩阵。代码很短from sklearn.model_selection import StratifiedKFold, cross_val_predict from sklearn.metrics import confusion_matrix cv StratifiedKFold(n_splits5, shuffleTrue, random_state42) y_cv_pred cross_val_predict(model, X_scaled, y, cvcv) cm confusion_matrix(y, y_cv_pred) print(cm)StratifiedKFold 保证每一折里各类别比例与整体接近。cross_val_predict 返回的是每个样本在“没见过它的那一折”上被预测的结果等价于让全量数据都当过测试集比一次性划分更抗运气。要注意它比交叉验证的 score 调用慢很多因为要保存所有预测不适用于调参循环里反复执行我一般在最终报告阶段才跑一次。5.2 用混淆矩阵的“错位关系”反查特征混淆矩阵最有用的信息不在对角线上而在其他格子里。若发现低能放电常被预测成高能放电回查这些样本的乙炔与乙烯比值。低能放电和高能放电都能产生乙炔区别在于高能放电的乙炔比例更高如果训练样本里 C2H2 集中在一堆 0 附近模型可能只学到了“有没有”而不是“多少”。处理方式给这两个类单独算召回率再决定是否增加 C2H2/C2H4 这类比值特征或者单独训练一个二分类判别器。论文里常见做法是只放一张五分类混淆矩阵但我在交付文档里会再给一张“真实故障与预测故障的样本数”表格把少数类的错位具体写出来。我一般会在脚本里保留一个 --report 参数把混淆矩阵和分类报告输出到 docs/figures 目录评阅时直接看图片比看控制台输出更直观。本文还有配套的精品资源点击获取