资讯详情

变压器DGA油色谱数据建模避坑指南:从数据体检到随机森林基线

📅 2026/10/13 17:33:54 | 华诺云谱 👁 阅读
变压器DGA油色谱数据建模避坑指南:从数据体检到随机森林基线
简介这份变压器溶解气体数据.rar面向电力设备运维、故障诊断研究与机器学习建模人员聚焦变压器油中溶解气体分析这一典型场景帮助解决故障类型识别与状态评估问题。数据覆盖中低温过热、高温过热、低能放电、高能放电、局部放电及正常状态六类样本涉及氢气、甲烷、乙烷、乙烯、乙炔等特征气体的浓度规律可用于比值法、判别函数法及智能诊断算法的验证与对比。压缩包约6.97MB文件总数与类型明细上游暂未提供但整体体量轻便便于快速下载与本地实验。目前已有177人学习下载具备一定参考热度。读者可借助实测数据开展特征工程、分类模型训练与故障预测实验理解不同故障下气体生成规律为智能监控系统开发和电力系统可靠性研究提供数据支撑。1. 变压器溶解气体数据.rar一份油色谱数据到手后先别急着训练模型拿到一个名为「变压器溶解气体数据.rar」的压缩包很多人的第一反应是解压、读表、扔进模型跑一遍准确率。但真正做过电力设备状态评估的人会先停一下这份数据到底是 DGADissolved Gas Analysis油中溶解气体分析的原始浓度记录还是已经被人为标注过故障类型的分类数据集两种情况下后面的处理路径完全不同。变压器溶解气体数据在工程里通常对应七种特征气体——氢气、甲烷、乙烷、乙烯、乙炔、一氧化碳、二氧化碳有时还带总烃和微水。这些数值背后是油纸绝缘在过热、放电、受潮等不同劣化机制下产气规律的变化。这份数据能解决的问题很具体用气体浓度组合去判断设备是否存在潜伏性故障以及故障大概属于哪一类。适合谁做电力设备在线监测、状态检修、故障诊断的算法工程师以及想把 DGA 数据用起来的运维分析人员。如果你只是想要一个干净的特征表直接调库那大概率会在数据清洗和标签定义上翻车。2. 先搞清楚七种气体和三类标签DGA 数据的字段含义与选型逻辑2.1 七种特征气体的物理意义与量纲陷阱油中溶解气体不是随便选的七个指标。氢气主要来自局部放电和水分分解甲烷、乙烷是低温过热产物乙烯在较高温度过热时显著上升乙炔则是高能放电的典型标志浓度一高基本可以锁定电弧或火花放电。一氧化碳和二氧化碳反映固体绝缘纸的劣化。问题在于很多压缩包里的数据表只给列名不给单位。常见单位有 μL/L即 ppm和 mg/L 两种前者是体积分数后者是质量浓度数值能差出好几倍。我一般会先看乙炔那一列的数值范围如果最大值只有零点几大概率是 ppm如果出现几十甚至上百要么是严重故障样本要么单位是别的。另一个坑是「总烃」列它通常是甲烷到乙炔四者之和如果数据里既有分项又有总烃训练时不要同时放进去否则共线性会让树模型的重要性排序失真。2.2 标签体系三比值、大卫三角和故障类型编码DGA 数据最常见的标签来源是 IEC 三比值法或罗杰斯比值法也有用大卫三角的。三比值用 C2H2/C2H4、CH4/H2、C2H4/C2H6 三个比值编码每个比值分区间给 0、1、2 三档组合成故障类型。如果你拿到的数据里有一列「故障类型」写着「低温过热」「中温过热」「高温过热」「局部放电」「火花放电」「电弧放电」这类中文那基本就是按比值法或改良版标注的。选型时要注意如果标签是规则生成的模型学到的其实是规则本身换一批数据可能就不准如果标签来自实际检修结论样本量通常很小且类别极不平衡。我的做法是先把标签分布打出来少于 30 个样本的类别要么合并要么用分层抽样别硬做多分类。2.3 用 pandas 读压缩包并做第一轮体检拿到 .rar 文件Windows 上可以用 7-Zip 或 WinRAR 解压Linux 下用 unrar。解压后常见格式是 .xlsx 或 .csv。下面这段代码做三件事读表、看字段、查缺失和量纲异常。import pandas as pd import numpy as np # 读入解压后的 csv注意编码可能是 gbk 或 utf-8 df pd.read_csv(dga_data.csv, encodinggbk) # 统一列名去掉空格和括号 df.columns [c.strip().replace(, ().replace(, )) for c in df.columns] # 查看前五行和字段类型 print(df.head()) print(df.dtypes) # 七种气体列名按实际表头调整 gas_cols [H2, CH4, C2H6, C2H4, C2H2, CO, CO2] # 缺失值统计 print(df[gas_cols].isnull().sum()) # 描述性统计重点看 min 和 max 判断量纲 print(df[gas_cols].describe().loc[[min, max, mean]]) # 检查是否有负值气体浓度不应为负 for col in gas_cols: neg_count (df[col] 0).sum() if neg_count 0: print(f{col} 存在 {neg_count} 个负值需要处理)逻辑说明先统一列名是为了后续按固定列名索引避免因为空格或全半角括号导致 KeyError。缺失值统计能告诉你哪些气体列是「稀疏」的比如乙炔在很多正常样本里就是 0 或未检出这不是缺失而是真实工况。描述性统计里的 max 值如果远大于 mean说明有极端故障样本后面标准化时要考虑用 RobustScaler 而不是 StandardScaler。负值直接置为 0 或按缺失处理因为浓度不可能为负。参数说明encoding参数要根据实际文件调整中文表头常见 gbk如果报 UnicodeDecodeError 就换 utf-8 或 gb18030。gas_cols列表必须和表头完全一致大小写敏感。如果表头是中文「氢气」「甲烷」要么改列表要么在读入后重命名。3. 从原始浓度到可训练特征比值、编码和标准化怎么做3.1 三比值编码的代码实现与边界处理三比值法的核心是把三个比值映射到整数编码。下面这段代码按 IEC 60599 的常见分区实现注意分母为 0 的情况。def ratio_code(df): # 避免分母为 0加一个极小值 eps 1e-6 df df.copy() # C2H2/C2H4 r1 df[C2H2] / (df[C2H4] eps) # CH4/H2 r2 df[CH4] / (df[H2] eps) # C2H4/C2H6 r3 df[C2H4] / (df[C2H6] eps) def code_r1(x): if x 0.1: return 0 elif x 3: return 1 else: return 2 def code_r2(x): if x 0.1: return 1 elif x 1: return 0 else: return 2 def code_r3(x): if x 1: return 0 elif x 3: return 1 else: return 2 df[code1] r1.apply(code_r1) df[code2] r2.apply(code_r2) df[code3] r3.apply(code_r3) df[ratio_combo] df[code1].astype(str) df[code2].astype(str) df[code3].astype(str) return df df ratio_code(df) print(df[ratio_combo].value_counts())逻辑说明加 eps 是为了防止分母为 0 导致除零错误但要注意如果 H2 本身是 0CH4/H2 会变成一个极大值编码会落到最高档。实际工程中H2 为 0 且 CH4 也接近 0 的样本通常是正常老化直接归到正常类更合理。ratio_combo把三个编码拼成字符串方便做分组统计或独热编码。如果要做多分类可以把 combo 映射到故障类型但映射表要按你采用的导则来不同导则的分区边界有差异。参数说明eps取 1e-6 是经验值太小可能受浮点精度影响太大可能改变比值量级。三个 code 函数的边界值 0.1、1、3 来自常见三比值分区如果你的数据标签是按其他导则生成的边界要相应调整。3.2 标准化与不平衡处理为什么不能直接上 SMOTE七种气体的浓度跨度极大乙炔可能是个位数二氧化碳可能上千。不做标准化基于距离的模型KNN、SVM会被大数值列主导。我一般用 RobustScaler因为它对异常值不敏感。下面代码同时做标准化和类别权重计算。from sklearn.preprocessing import RobustScaler from sklearn.utils.class_weight import compute_class_weight gas_cols [H2, CH4, C2H6, C2H4, C2H2, CO, CO2] X df[gas_cols].values y df[fault_type].values # 假设标签列叫 fault_type scaler RobustScaler() X_scaled scaler.fit_transform(X) # 计算类别权重用于模型训练 classes np.unique(y) weights compute_class_weight(balanced, classesclasses, yy) class_weight_dict dict(zip(classes, weights)) print(class_weight_dict)逻辑说明RobustScaler 用中位数和四分位距做缩放比 StandardScaler 更适合含极端故障样本的 DGA 数据。compute_class_weight给出每个类别的权重训练时传给模型的class_weight参数比直接过采样更稳妥。为什么不推荐 SMOTE因为 DGA 样本的特征空间不是欧氏的两个故障样本之间做线性插值可能生成物理上不存在的浓度组合比如乙炔和乙烯的比例关系被破坏模型学到的是假模式。参数说明class_weightbalanced会按类别频率反比给权重频率低的类别权重大。如果某个类别只有几个样本权重会非常大可能导致模型偏向该类别这时可以考虑合并稀有类或改用 focal loss。3.3 特征工程除了比值还能加什么原始七种气体加三个比值编码是最小特征集。实际项目中我还会加几个衍生特征总烃CH4C2H6C2H4C2H2、乙烯占比C2H4/总烃、乙炔占比C2H2/总烃、CO2/CO 比值。CO2/CO 比值对区分固体绝缘劣化和油劣化有帮助一般大于 7 认为纸绝缘正常小于 3 要警惕。这些特征不需要复杂计算但能显著提升树模型的分裂效果。注意不要加太多高度相关的特征否则特征重要性会分散解释性变差。4. 避坑与排查DGA 数据建模中最容易翻车的五个地方4.1 现象模型准确率 99%换一批数据掉到 60%原因标签是规则生成的且训练集和测试集来自同一批规则标注的数据模型学的是规则边界而不是真实故障模式。解决如果标签来自三比值法直接查表输出结果即可不需要训练模型如果一定要用机器学习确保测试集来自不同时间段或不同设备并且标签来自检修结论而非规则。4.2 现象乙炔列大量为 0模型完全忽略这个特征原因乙炔在正常样本中普遍未检出数值为 0但在故障样本中可能很高。如果直接标准化0 值会被缩放到负值区间树模型虽然不受影响但线性模型会出问题。解决对乙炔单独做二值化特征「乙炔是否检出」再保留原始浓度。或者用对数变换 log1p 压缩量纲。4.3 现象训练时 loss 震荡验证集准确率不上升原因学习率太大或者批次里混入了极端值样本。DGA 数据中个别故障样本的乙炔浓度可能是正常值的几百倍梯度会被拉爆。解决先用 RobustScaler 缩放再检查是否有超过 10 倍四分位距的离群点必要时截断或单独分析。学习率从 1e-3 降到 1e-4 试试。4.4 现象三比值编码后某些组合从未出现原因样本量太小或者数据采集时已经过滤掉了某些故障类型。三比值有 27 种组合实际数据可能只覆盖 8 到 10 种。解决不要强行做 27 类分类把稀有组合合并到「其他故障」或按故障大类过热、放电、受潮重新标注。4.5 现象用 CO2 和 CO 做特征后模型性能下降原因CO2 和 CO 受油中气体扩散和吸附剂影响大且与故障类型的关系不如烃类气体直接。解决可以保留但降低权重或者只保留 CO2/CO 比值。如果数据里 CO2 列缺失严重直接去掉。5. 一个可复现的基线用随机森林做 DGA 故障分类并验证5.1 完整训练脚本与交叉验证下面这段代码从读数据到输出分类报告是一条能跑通的最小路径。假设数据已经解压为 csv标签列名为 fault_type。import pandas as pd import numpy as np from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold, cross_val_predict from sklearn.preprocessing import RobustScaler from sklearn.metrics import classification_report, confusion_matrix # 读数据 df pd.read_csv(dga_data.csv, encodinggbk) df.columns [c.strip() for c in df.columns] gas_cols [H2, CH4, C2H6, C2H4, C2H2, CO, CO2] df df.dropna(subsetgas_cols [fault_type]) # 衍生特征 df[total_hydrocarbon] df[CH4] df[C2H6] df[C2H4] df[C2H2] df[C2H4_ratio] df[C2H4] / (df[total_hydrocarbon] 1e-6) df[C2H2_ratio] df[C2H2] / (df[total_hydrocarbon] 1e-6) df[CO2_CO_ratio] df[CO2] / (df[CO] 1e-6) feature_cols gas_cols [total_hydrocarbon, C2H4_ratio, C2H2_ratio, CO2_CO_ratio] X df[feature_cols].values y df[fault_type].values # 标准化 scaler RobustScaler() X_scaled scaler.fit_transform(X) # 随机森林带类别权重 rf RandomForestClassifier( n_estimators300, max_depth8, min_samples_leaf3, class_weightbalanced, random_state42 ) # 分层交叉验证 cv StratifiedKFold(n_splits5, shuffleTrue, random_state42) y_pred cross_val_predict(rf, X_scaled, y, cvcv) print(classification_report(y, y_pred)) print(confusion_matrix(y, y_pred)) # 特征重要性 rf.fit(X_scaled, y) importance pd.Series(rf.feature_importances_, indexfeature_cols).sort_values(ascendingFalse) print(importance)逻辑说明先做缺失值剔除DGA 数据里气体列缺失的样本通常无法用均值填充因为缺失可能意味着未检测。衍生特征里 total_hydrocarbon 是总烃C2H4_ratio 和 C2H2_ratio 反映故障类型倾向CO2_CO_ratio 辅助判断绝缘纸状态。随机森林的 max_depth 设 8 是为了防止过拟合min_samples_leaf 设 3 保证叶子节点有足够样本。交叉验证用 StratifiedKFold 保持类别比例。特征重要性输出能告诉你哪些气体对分类贡献大通常乙炔和乙烯会排前面。参数说明n_estimators300是精度和速度的折中样本量小可以降到 100。max_depth根据样本量调整样本少于 500 时设 5 到 6。class_weightbalanced处理不平衡如果类别已经均衡可以去掉。random_state固定后结果可复现。5.2 结果怎么看混淆矩阵和特征重要性的解读分类报告里重点看 macro avg 的 f1-score因为类别不平衡时 accuracy 会虚高。混淆矩阵能看出哪些类别容易被混淆比如低温过热和中温过热经常互相误判因为它们的产气特征重叠。特征重要性里如果 CO2 排最后说明它对当前标签体系贡献小可以考虑去掉。如果 H2 重要性异常高检查是不是 H2 的量纲和其他气体差太多标准化没做好。5.3 一个容易忽略的验证按设备分组划分数据集如果数据里有一列设备 ID不要随机划分训练集和测试集。同一台设备的不同时间样本高度相关随机划分会导致测试集信息泄漏准确率虚高。正确做法是按设备 ID 分组用 GroupKFold。这个细节在论文里经常被忽略但在工程落地时是致命的。我一般会在数据体检阶段就检查有没有设备 ID 列有的话优先用分组划分。5.4 从基线到落地阈值调整和在线更新基线模型跑通后实际部署时还要做两件事。一是调整分类阈值比如把「电弧放电」的召回率调到 0.95 以上宁可误报不可漏报因为漏掉一个电弧放电样本可能导致设备损坏。二是设计在线更新机制新样本积累到一定数量后重新训练但要用时间序列划分验证确保模型没有退化。DGA 数据的分布会随设备老化缓慢漂移固定模型半年后性能下降是常态。我自己的习惯是每次拿到新的 DGA 数据包先花二十分钟做字段体检和标签分布再决定是直接查表还是训练模型。这个顺序反过来后面返工的时间会多得多。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑