ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于DGA油色谱数据的变压器故障诊断与机器学习建模实践

基于DGA油色谱数据的变压器故障诊断与机器学习建模实践 干变压器故障诊断这行的手头最金贵的东西往往不是什么高大上的检测仪器而是那厚厚一沓油色谱试验记录。油里溶解的气体就是变压器内部状态的“体检报告”H2、CH4、C2H6、C2H4、C2H2这五种特征气体搭配对应的故障类型标签就能从数据里挖出“绝缘有没有过热”“是不是在局部放电”这些硬核结论。这次拿到的是一个非常经典的变压器故障诊断数据集356组样本、7类标签含正常正好覆盖了从正常状态到各种典型潜伏性故障的全谱系。对于搞电力设备状态检修的技术人员、在做油中溶解气体分析的工程师以及刚接触电力领域小样本分类任务的算法同学这套数据都值得仔细盘一盘。我之前接触过不少类似的数据集说实话这个量级的样本数在电力故障诊断领域非常典型——真实工况下故障样本本来就难收集能凑齐356组已经相当不错。但小样本带来的挑战也很现实七分类任务下每个类别平均只有五十来组数据如果某些故障类型样本分布不均匀模型很容易“偏科”。所以这篇内容我就围绕这个数据集的完整技术链路来写从气体组分和故障机理的对应关系到数据预处理、特征构造再到模型选型评估和避坑经验一条龙讲清楚。1. 先把这个数据集看透气体组分背后是故障的“指纹”1.1 五种气体到底在说什么变压器内部故障的核心诱因是电和热。绝缘油的主要成分是碳氢化合物在电场应力或热应力作用下碳氢键会断裂产生氢气和不饱和烃类气体。这五种气体不是平起平坐的每种气体都指向特定的故障性质浓度高低和比例关系则是关键的判断依据。H2氢气分子量最小键能也相对较弱最容易在低能量密度状态下产生。局部放电、电晕放电哪怕能量很低也会先析出大量氢气所以它是放电性故障的“早期信号”。CH4甲烷热分解的初级产物在温度不太高的过热状态下占主导。变压器油温在300℃上下时甲烷比例会明显上升。C2H6乙烷也是低温热解的产物但相比甲烷它在温度进一步升高时的增长速率反而放缓。它在诊断里更多是充当“配比参照物”。C2H4乙烯高温过热的关键标志。油温超过500℃后乙烯含量会加速飙升温度越高乙烯在烃类气体中的占比越大。中低温过热和高温过热的区分很多时候就看乙烯与乙烷的比例关系。C2H2乙炔这个气体在诊断中的权重极高因为它需要非常高的能量密度才能大量生成。电弧放电、火花放电等高能放电故障下乙炔才会显著出现。如果乙炔浓度异常基本可以直接锁定放电类故障。这五种气体对应的就是一张“故障指纹表”。比如局部放电时氢烃比很高、乙炔几乎没有而高温过热时乙烯和甲烷比例大、乙炔很低。模型学习的本质就是拟合这种气体组分空间和故障类型之间的非线性映射。1.2 七种故障类型的标签体系这个数据集包含7类标签含正常在公开的和工程化的数据集中通常对应的是正常、局部放电、低能放电火花放电、高能放电电弧放电、中低温过热、高温过热以及放电兼过热组合故障。具体标签含义要看数据集字典但整体分类逻辑和大类IEC 60599的故障分类思路一致。有一点值得注意不同来源的数据集对“过热”的温度区间划分不完全一致有的把300℃以下叫低温过热300700℃叫中温过热700℃以上叫高温过热有的干脆就两档低温过热带350℃附近高温过热带900℃附近。所以建模前第一步不是急着跑代码而是先把标签分布和类别含义列清楚否则后面误判分析时根本分不清是模型错了还是标签本身定义不同。1.3 数据量和特征维度带来的客观约束五维特征输入、七分类输出356组样本。这个规模放在深度学习里连“小试牛刀”都谈不上但在传统机器学习和统计学习框架下反而是很健康的复杂度。原因在于五维特征下不需要太深的结构就能拟合决策边界356组样本足以支撑交叉验证但要留出至少20%比例的测试集时训练数据只有280组上下对模型容错要求不低七分类的类别数不算多但如果有类别不平衡少数类的有效样本可能只有二三十组这就会催生一系列工程处理手段。所以别再纠结“为什么不用深度学习”这套数据最适合的玩法是经典机器学习加上扎实的特征工程把每一个样本的气体比值关系榨干净。2. 数据层面深挖小样本分类的“地基工程”2.1 特征空间的量纲和分布问题五种气体的浓度单位通常是µL/Lppm但实际数值范围跨度极大。有的正常样本氢气只有个位数有的高能放电样本乙炔可能直接到几百。这个量级差异会在模型训练时带来两个麻烦一个是距离类算法比如SVM会把数值大的特征当成主导因素另一个是树模型虽然不敏感但如果特征本身存在偏移分裂点选择也会受到影响。所以我拿到数据的第一件事是先看描述性统计确认每个特征的min、max、均值以及是否有异常值。气体浓度数据里偶尔会出现“离谱”的极大值比如某些接近出厂阈值的高放样本虽然真实存在但对模型训练还是会产生干扰。2.2 标签分布是建模前必须核实的硬指标七分类标签的分布直接决定后续用不用采样策略、用不用class_weight。之前我碰过一个项目数据说明写着“故障类型7种”实际打开一看“正常”类占了近40%低能放电只有20来条。常规的准确率标准在这种情况下完全失真因为模型只要全部预测为“正常”就能拿到40%以上的正确率。所以这里给一个很实在的建议拿到数据后第一行代码画个柱状图或者直接value_counts()看一眼。类别不平衡严重的话训练集和测试集划分时必须用分层抽样否则某一次随机划分可能把某一类全部塞进测试集里结果直接没法看。2.3 小样本下的评估策略真正能说明模型实力的不是单次划分出的测试集结果而是交叉验证或者多次重复实验的均值方差。我个人在类似数据集上的习惯是用StratifiedKFold做五折交叉验证看每一折的宏平均召回率和F1然后在固定随机种子下再划分一个最终hold-out测试集作为“对外”报告的数字。这样既能避免单次划分的偶然性也能在交叉验证和独立测试两套口径下交叉印证。波动性也是判断模型是否稳定过拟合的重要指标。如果同一模型在不同折上宏F1从0.5跳到0.9基本可以断定目前的特征或者模型容量配不上这个数据量优先回头精简特征或者用正则化更强的模型。3. 传统DGA判据到机器学习模型这是一次“降维打击”吗3.1 三比值法的天生不足在数据建模之前必须知道行业里传统做法是什么。最经典的是IEC三比值法它把CH4/H2、C2H2/C2H4、C2H4/C2H6三组比值按阈值编码成0/1/2然后查表得到故障类型。工程上确实好用因为它不需要任何训练数据供电人员拿着编码表就能定性。但把三比值法用在这套数据集上会暴露几个问题编码过程中把连续比值离散化丢掉了大量“半饱和”信息阈值区间外的大比值直接截尾比如CH4/H210和CH4/H2100都编码成2损失严重部分组合编码没有对应故障结论查询表时出现“无对应判据”的盲区。这些问题在本数据集上会直接影响诊断准确率正好给了机器学习模型发挥空间。模型可以学习连续阈值下的软边界而不是硬编码的粗粒度区间。所以在文章里我一直强调三比值法适合做先验理解和特征参考而机器学习是被验证过的更优赋能路径。3.2 气体比值特征与原始浓度特征的取舍关于特征构造我们要直面一个经典问题到底直接用五种气体的原始浓度喂给模型还是额外构造气体比值特征我试过两种方案的对比原始浓度直接入模时模型更多学到的是“浓度水平”信息比如某些过热样本整体气体总量偏高。但变压器负荷、油量、运行年限都会影响绝对浓度同一故障类型在不同设备上浓度可能相差一个数量级。比值特征如CH4/H2、C2H2/C2H4、C2H4/C2H6捕捉的是组分之间的“模式”不受总油气量线性缩放影响这更接近色谱诊断的核心逻辑。实战结论对SVM、逻辑回归这类线性模型比值特征带来的提升非常明显对随机森林、XGBoost这类树模型比值特征的效果有所提升但幅度不算惊人。最稳的方案是保留原始浓度和比值特征的组合版本让模型自己决定更依赖哪些视图的信息。这里注意构造比值时如果分母为零通常加一个极小值或者直接保留原始列让模型自行学习处理。3.3 模型选型的适配逻辑在356组样本的小数据背景下模型选择一定要信奉“大道至简”。我的经验排序是模型适配性分析实际效果参考随机森林对五维特征抗过拟合能力强自带特征重要性解释稳定可靠适合当基准模型SVMRBF核对非线性边界拟合精准但需要标准化的配合调好参数后往往是上限最高的XGBoost/LightGBM梯度提升在小样本上反而容易过拟合需要把树深度压低、学习率调小优于随机森林的收益有限除非配合可靠正则化MLP五维特征下优势有限但作为对比实验代表深度学习是必要的容易过拟合需要强正则一般不作为首选要表达的核心观点是不迷信复杂模型。对一个只有356组样本的七分类任务随机森林或者RBF-SVM配合气体比值特征往往已经能逼近90%附近的宏平均F1。真正的瓶颈不是模型复杂度而是特征的构造和标签质量的把控。4. 实操环节从零跑通一个可靠的故障诊断模型4.1 数据加载和初步探查假设数据是CSV格式列名分别为H2、CH4、C2H6、C2H4、C2H2、label。第一步先把数据完整读进内存做基础检查。import pandas as pd import numpy as np from sklearn.model_selection import StratifiedKFold, train_test_split from sklearn.preprocessing import StandardScaler from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC from sklearn.metrics import classification_report, confusion_matrix, f1_score df pd.read_csv(dga_dataset.csv) print(df.shape) print(df[label].value_counts()) print(df.describe())这个阶段重点确认三件事样本数是否356、五类气体列是否有空值、标签列类型是否为字符串或整数。气体浓度在工程记录中可能出现“0.0”值这是合法的但极少数样本可能出现负值或者空字符串需要先清洗成数值类型。4.2 构造气体比值特征根据DGA诊断经验我习惯构造三个核心比值作为额外特征列# 分母极小值处理避免除零 eps 1e-6 df[ratio_ch4_h2] df[CH4] / (df[H2] eps) df[ratio_c2h2_c2h4] df[C2H2] / (df[C2H4] eps) df[ratio_c2h4_c2h6] df[C2H4] / (df[C2H6] eps)除这三个外还可以加H2占总烃的比例、总烃含量五种烃类气体之和。但要注意这里加特征不是越多越好。356组样本下特征数如果超过20个反而容易引入噪声和多重共线性。我实测下来的最好组合常常是“5维原始浓度 3个核心比值 2~3个扩展比值”总共控制在10~12维以内。给个提醒除零处理用eps这种小常数比较省事但会让某些比值的分布出现“离群大值”后续做标准化之前建议先对这类特征做一次对数变换或者分位数裁剪否则一个异常比值就可能主导SVM的边界。4.3 分层划分与标准化X df.drop(label, axis1).values y df[label].values X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, stratifyy, random_state42 )分层抽样这一步不是可选项。正因为样本只有356组不用stratify划分某些小类别很可能在训练集或测试集中彻底缺失那评估结果就完全失真。标准化上树模型可以跳过去但SVM必须做。要在训练集上fit掉StandardScaler再用同一个scaler变换测试集scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)这属于老生常谈但确实是很多新人最容易埋雷的环节——一旦把scaler放到全量数据上fit测试集信息就泄漏进了训练流程交叉验证分数会虚高落地时马上现原形。4.4 模型训练与对比评估我用随机森林和RBF-SVM各跑一遍并在测试集上输出宏平均F1和分类报告。rf RandomForestClassifier(n_estimators200, max_depth8, random_state42) rf.fit(X_train_scaled, y_train) y_pred_rf rf.predict(X_test_scaled) svm SVC(kernelrbf, C10, gammascale, class_weightbalanced) svm.fit(X_train_scaled, y_train) y_pred_svm svm.predict(X_test_scaled) print(RF classification report:) print(classification_report(y_test, y_pred_rf, zero_division0)) print(SVM classification report:) print(classification_report(y_test, y_pred_svm, zero_division0))等代码跑完重点看两类指标一是宏平均F1比准确率更能刻画七分类在类别不平衡下的整体能力二是每个故障类别的召回率。放电类故障召回率如果偏低比如低能放电被大量误判成高能放电往往提示气体比例特征在两类间区分度不足这时候可以针对这两类单独做特征对比分析或者把它们视作“放电大类”做两阶段诊断策略。4.5 五折交叉验证报告单次划分的结果只是抽样结果更严谨的做法是交叉验证。这里给出一个简洁的写法cv_scores [] cv StratifiedKFold(n_splits5, shuffleTrue, random_state42) for train_idx, val_idx in cv.split(X_scaled, y): X_tr, X_val X_scaled[train_idx], X_scaled[val_idx] y_tr, y_val y[train_idx], y[val_idx] svm_clf SVC(kernelrbf, C10, gammascale, class_weightbalanced) svm_clf.fit(X_tr, y_tr) y_pred_cv svm_clf.predict(X_val) cv_scores.append(f1_score(y_val, y_pred_cv, averagemacro)) print(fCV macro-F1 mean: {np.mean(cv_scores):.4f} ± {np.std(cv_scores):.4f})交叉验证分数和测试集分数如果相差在5个百分点以内说明模型稳定性合格差太多就要考虑是不是特征里有离群点或者某一个折的类别分布太极端。之前我跑类似数据集时某折宏F1突然跳到0.6以下排查后才发现是某个“高温过热”样本浓度比其他同类高了上百倍树模型不断被这个点带偏。做一次分位数裁剪就恢复正常。4.6 特征重要性和误判分析用随机森林的特征重要性做个简单排序可以验证哪些气体信息对诊断贡献最大。多数情况下C2H2和C2H4的重要性排名靠前这和乙炔指向放电、乙烯指向高温过热的机理完全吻合。之后把混淆矩阵列出来重点观察相邻故障类型的互相误判这通常能告诉你后续应该往哪个方向补充数据或调整特征。5. 实际做项目时踩过的一些坑5.1 数据集标签含义必须先核对不同来源的“7种故障类型”看起来差别不大实际语义可能完全不同。有的数据集把“低温过热”和“中温过热”分开有的合二为一。如果拿别人的标签语义套用到自己的业务场景模型训练得再好也解释不了现场问题。拿到数据后尽快确认分类边界不明确时宁可先按粗粒度大类合并也别硬着头皮细分。5.2 气体比值的除零处理要比想象中麻烦原始气体浓度存在大量0值是常态比如正常状态下乙炔浓度通常就是0.0。构造C2H2/C2H4时如果不加处理这个比值特征会变成一堆“0.0”夹杂几个极端大值分布严重右偏。我试过几种方案直接加eps简单但会产生虚假的极小数值用np.where判断分母为零时置为某个大常数需要额外处理不使用比值而是同时输入原始浓度和比值让树模型自行处理条件关系。最终我倾向第三种核心比值和原始浓度同时入模树深度控制在10以内既保留比例信息又避免除零虚构值干扰。5.3 类别不平衡时别只盯准确率这个数据集里如果“正常”类占比高而少数故障类样本少模型完全可能靠“预测全为正常”拿到高的整体正确率。所以用宏平均F1或者加权F1更可靠。我一直坚持在项目报告里同时给出混淆矩阵和按故障类型的召回率不然很容易被单指标误导。5.4 随机种子和重复实验是诚信问题同一个模型在random_state1和random_state42下可能跑出完全不同的结论。小样本下随机划分的方差被放得很大。想要确认模型真的有效建议至少跑5个不同的种子看宏F1的均值和极差。极差过大时说明当前特征或模型无法在数据中稳定捕捉可复现的模式一味调参数只是自欺欺人。5.5 先做简单模型再上复杂模型先用逻辑回归或决策树跑通基线再对比随机森林和SVM。如果简单的线性模型已经能有不错表现说明气体特征与故障类别本身就存在较强的线性可分关系这时候再引入复杂模型才有确定的增益空间。不要跳过这一步它能帮你在后续调参时找准自己的位置。6. 这套数据后续还能怎么挖6.1 两阶段诊断策略小样本下直接七分类容易把“放电”和“过热”大类之间的边界当成纠缠重点。更符合工程实际的思路是第一阶段分大类判断是放电、过热还是正常第二阶段在放电内部细分局部放电、低能放电、高能放电。两阶段模型的好处是每个阶段的类别数降到两三个分类难度下降少数类样本也能被更充分地关注。6.2 把模型输出和传统判据融合模型输出的概率值可以和IEC三比值法的判据结果做一致性校验。当模型和传统方法结论一致时诊断置信度可以显著提高不一致时则提示样本可能处于临界状态或标签本身存在争议。这种做法在现场项目中既接地气又能解释给运检人员听。6.3 迁移学习的思路在DGA领域同样有用如果手头有其他来源的DGA数据哪怕只有一两百组可以先用大样本数据预训练一个随机森林或SVM再用本数据集精调。树模型在这方面的收益不一定大但对特征空间的初始覆盖有意义。更常见的方式是先用大量无标签样本估计各气体浓度的正常波动范围再基于此构造异常偏离度特征这比单纯标准化更贴近设备诊断逻辑。我在实际做项目中最大的体会是DGA小样本诊断的重心一定在数据和特征层面。气体种类就这么五种标签类别也相对固定与其追求模型结构的复杂不如把每个样本的原始记录、现场工况、试验条件都吃透把特征构造做扎实。这种东西没有捷径就是从一次次的混淆矩阵和误判回看中磨出来的。这个356组的数据集虽然不算大但把它的价值挖掘到极致足够支撑一次完整的状态检修诊断研究和实用性验证。
返回列表