
做PHM故障预测与健康管理落地项目的人应该都有同感真正挡住模型上线的第一道坎往往不是算法选型而是训练数据本身的不平衡。重大装备的正常工况数据要多少有多少可故障样本能凑出几十条都算运气好。设备不能天天坏更不能为了收集数据故意把它弄坏去采集故障信号这就导致了故障样本极其稀缺。你拿一个在正常样本上训得漂漂亮亮的模型一遇到真实故障分类器基本靠猜。这篇博客我想聊聊我们在某个旋转机械健康管理项目里用到的Feature-level SMOTE方法。所谓Feature-level SMOTE就是先在特征级别做数据增强而不是直接在原始信号或原始样本上套用SMOTE。它解决的核心问题是在故障样本严重不足时如何生成物理意义合理、可用的合成故障样本让模型在极端不平衡的数据上仍然保持可接受的故障识别能力。文章会比较完整地讲清楚思路、原理、实操流程和踩坑记录适合正在做设备健康管理、故障诊断、预测性维护或者在工业数据分析里遇到数据不平衡问题的算法工程师和数据科学从业者参考。1. 整体设计思路与问题拆解1.1 PHM场景下不平衡问题的根源先聊聊我们为什么会碰到这个问题。在PHMPrognostics and Health Management故障预测与健康管理项目里数据不平衡不是锦上添花要考虑的而是整个建模流程的第一步。重大装备的振动监测、油液分析、温度与电流信号采集系统的采样频率往往很高——比如我们用的振动传感器采样率是25.6kHz一台设备跑一个月就能产生上亿个数据点。但如果做成一个故障诊断任务把连续时间序列切成一个个样本你会发现正常样本和故障样本的比例可能是100比1甚至1000比1。这种极端不平衡来自设备维护的本质重大装备的设计目标就是长时间稳定运行故障本身是个低频事件。再加上现场有预防性维护策略设备稍微出现异常征兆就被停机检修了所以完整退化的数据很难积累。更麻烦的是故障样本还有类型之分——早期故障的微弱冲击信号和严重故障的剧烈撞击信号差别很大如果不分开建模模型会把它们混成一团。而分开建模之后每个子类的样本量就更少了有的类别可能只有二三十条样本。传统的应对方案无非是重采样欠采样丢掉大量正常样本或者过采样复制故障样本。欠采样的缺点是浪费信息正常样本里包含的工况变化、负载波动信息被白白丢弃复制粘贴的过采样又让模型在重复样本上过拟合训练时指标看起来很好一到现场就露馅。SMOTESynthetic Minority Over-sampling Technique这类合成过采样方法就是为了解决“复制不够用”的问题而出现的它通过对少数类样本的插值生成新样本而不是简单重复已有的样本。1.2 为什么选择在特征层面做SMOTESMOTE的原始做法是在少数类样本之间做线性插值生成新的合成样本。如果直接把SMOTE用在原始振动信号上我们会遇到一个问题——振动信号是时间序列每个样本是几千个采样点的波形。在两个故障波形样本之间做逐点插值生成的“合成波形”在物理上可能完全站不住脚。它可能既不像早期故障的冲击衰减波形也不像严重故障的平稳高幅波形而是两者在时间轴上混乱拼接的产物。卷积神经网络在这种波形上训练学到的是不存在的故障模式。Feature-level SMOTE的思路是换一个空间来操作。先把原始信号通过特征工程压成一组低维特征向量——比如时域的均方根值、峰值因子、峭度频域的重心频率、谱峭度时频域的小波包子带能量占比——每个样本对应一组固定的特征描述。然后在这个特征空间里做SMOTE插值。特征的语义连续性强很多早期故障和严重故障在特征空间里的距离是有物理意义的插值出来的合成特征向量更像是一个“中间退化状态”的设备表现而不是一段毫无物理意义的人造波形。用生活化的类比来说样本级SMOTE就像拿两张人脸照片做像素平均得到的是一张五官错位的“混合脸”而特征级SMOTE像先提取“脸型、肤色、发型”等描述维度再在这些维度上取中间值得到的仍然是一个符合逻辑的“人”。在PHM场景下我们需要的显然是后者。1.3 Feature-level SMOTE的整体技术路线我们在项目中实际采用的完整技术路线分为五个环节一是数据切分与样本构建。从连续监测数据里切出固定长度的信号段同时利用设备台账和维修记录打标签注意必须按设备或按时间段做组级切分避免同一设备的信号段同时出现在训练集和测试集。二是特征提取。从每个信号段中提取多域特征构建初始特征集。三是特征预处理与筛选。标准化、去相关、剔除无效特征再结合故障机理知识做特征筛选把维度控制在合理范围内。四是在训练集内实施Feature-level SMOTE。只在训练特征矩阵内部生成合成样本测试集不参与任何过采样操作。五是模型训练与评估。用合成增强后的特征矩阵训练分类模型在保留的真实测试集上评估故障识别能力。这套路线最大的好处是解耦了“数据增强”和“模型训练”两个环节。特征工程是固定的SMOTE只作用于特征矩阵模型可以随意切换——XGBoost、随机森林、MLP甚至后续接LSTM都没问题。部署时也方便现场的数据流只需要过一遍特征提取再进分类器就行了。2. 核心原理与关键实现细节2.1 SMOTE原始机制回顾先简单回顾一下经典的SMOTE算法因为后面很多参数选择都建立在这个基础理解之上。SMOTE的处理对象是少数类的样本集合算法步骤如下对于少数类中的每一个样本xi用欧氏距离找出它同类的k个最近邻从这k个近邻中随机选择一个样本xj在xi与xj的连线上随机生成一个新样本新样本的特征值等于xi λ × (xj − xi)其中λ是0到1之间的随机数。对这个机制有三个关键认知。第一合成样本只落在已知少数类样本的连线之间绝不超出数据分布范围所以它不会凭空创造新的故障模式只是让已有的故障模式在特征空间里“更密集地采样”。第二k近邻的选择决定了生成样本的局部形态。k太小时生成样本紧贴原有样本多样性不足k太大时容易跨到另一个退化阶段的区域生成不合理的中间态。第三SMOTE对特征空间的度量极为敏感——如果特征不标准化量纲大的特征会在欧氏距离计算中占据绝对主导邻居选择基本只看那一两个维度生成样本的质量自然无法保证。2.2 特征空间构建时域、频域、时频域特征怎么选Feature-level SMOTE的效果上限由特征空间的质量决定。插值只能在你提供的特征维度上做文章如果特征本身不能区分故障模式那么生成再多样本也是噪声。我们在项目中构建了一套三层特征体系。时域特征关注信号的统计量均值、标准差、均方根值、峰峰值、峭度、偏度、波形因子、峰值因子、脉冲因子、裕度因子。这些指标对冲击类故障特别敏感。设备轴承出现早期剥落时时域波形上会出现周期性的冲击脉冲峭度会从正常状态的3左右迅速抬升而均方根值可能变化不大。所以仅靠单一特征无法捕捉故障全貌需要组合使用。频域特征关注信号的频率构成对每个信号段做FFT计算幅值谱的重心频率、均方频率、频率标准差、谱峭度等。正常齿轮箱的啮合频率及其谐波成分较稳定故障发生后会在特定频段出现边带或能量集中谱峭度能较好地捕捉这些变化。时频域特征捕捉瞬态与非平稳成分使用小波包分解将信号分解到不同频带计算各子带的能量占比。比如三层小波包分解产生8个频带每个频带对应一段能量值归一化后形成8维特征向量。早期故障的冲击成分通常是瞬态的在FFT平均谱上可能被淹没但小波包子带能量能保留这种局部频段的变化。我们最终选择了10个时域特征、5个频域特征加8个小波包子带能量特征共23维特征向量每个信号段对应一条记录。2.3 标准化、降维与插值参数的配合把原始信号压成特征向量之后还不能立刻做SMOTE必须先解决量纲问题。23个特征里峭度的数值范围可能是2到20均方根值可能是0.01到0.5小波包能量占比是0到1的归一化值。如果直接在这些原始值上计算欧氏距离欧氏距离几乎完全由峭度这类大数值特征决定其余特征全是摆设。我们在标准化上踩过坑之后项目里定死了规矩标准化必须在过采样之前并且标准化参数只从训练集中估计测试集沿用训练集的均值和方差做转换不能单独拟合。标准化之后还需要审视特征的冗余性。有些特征在不同工况下高度相关比如标准差和均方根值在很多场景下几乎线性相关。如果把这些强相关特征全部保留特征空间的真实维度会比表面维度低很多SMOTE的插值会在冗余方向上浪费生成能力。我们用相关性分析和随机森林特征重要性做过两轮筛选把相关性超过0.9的特征合并或剔除最终保留了18到19个有效特征。插值参数方面我们使用的是imbalanced-learn库的SMOTE实现k_neighbors参数在默认值5的基础上做了调优。当某个故障子类的样本量很少比如只有30条时k取5意味着部分样本的5个近邻需要跨越较大的特征空间距离生成的样本可能偏离合理范围。我们把k调到了3并且在不同故障子类上分开做SMOTE而不是把整个少数类混在一起插值避免了生成“混合故障模式”的假样本。2.4 与样本级SMOTE、边界SMOTE的对比项目早期我们其实先试了直接在原始振动信号段上做样本级SMOTE结果很不理想。对比之下Feature-level SMOTE的优势非常明显。直接对原始信号样本做SMOTE需要对每条信号在时间轴上进行逐点插值这种操作生成的波形在时域上经常出现不自然的相位漂移和幅值突变。模型在合成波形上学到的模式无法迁移到真实故障波形上。而特征级SMOTE生成的合成样本在特征空间里是平滑过渡的从分布上看与真实故障样本一致。ADSYN或者Borderline-SMOTE这类变体在普通表格数据上表现不错但在PHM场景下没有本质差别。我们的经验是先把特征工程做扎实比在算法变体上花时间更有效。另外特征空间本身就自带降噪效果——原始振动信号里混着环境噪声、传感器干扰直接插值会把噪声也一起插进合成样本里特征提取过程相当于先做了一次清洗后续插值才是在“干净”的语义空间里操作。3. 实操记录从振动数据到故障分类模型3.1 场景设定与数据准备我们这次的项目对象是一套大型旋转机械监测系统传感器布置在轴承座和齿轮箱壳体上采样率25.6kHz每次采集4096个采样点作为一个分析样本。设备的健康状态根据现场巡检和维修记录分成三类正常工况、早期故障、严重故障。数据准备阶段遇到的第一件事就是切分方式。我们一开始用随机切分把连续信号段打乱后直接划分训练集和测试集结果训练出来的模型指标虚高。原因是同一台设备同一时间段内的信号段高度相似——一条接近故障的样本切出来的相邻信号段也很像故障随机切分后这些“孪生段”分散在训练集和测试集中模型约等于变相看到了测试数据。之后改成了按时间段分组的切分方式前80%时间段的样本进训练集后20%时间段的样本做测试集确保测试集里的样本在时间上晚于训练集模拟真实场景中的“用历史数据预测未来故障”。最终构建的数据集分布如下正常样本约2000条早期故障样本约60条严重故障样本约40条。不做任何处理直接训练的话绝大多数分类器会把所有样本判成正常类来获取超过95%的准确率这就是不平衡数据最大的陷阱——准确率虚高故障召回率几乎为零。3.2 特征提取实现特征提取我们直接用Python实现核心流程包括时域统计、FFT频谱分析和小波包分解。下面这段代码是时域特征提取的核心逻辑import numpy as np from scipy import stats def time_domain_features(x): rms np.sqrt(np.mean(x ** 2)) peak np.max(np.abs(x)) mean_abs np.mean(np.abs(x)) kurt stats.kurtosis(x) skew stats.skew(x) # 波形因子 RMS / 平均绝对值 wave_factor rms / mean_abs # 脉冲因子 峰值 / 平均绝对值 pulse_factor peak / mean_abs # 峰值因子 峰值 / RMS crest_factor peak / rms # 裕度因子 峰值 / (平均根号绝对值)^2 margin_factor peak / (np.mean(np.sqrt(np.abs(x))) ** 2) return [ np.mean(x), np.std(x), rms, peak, kurt, skew, wave_factor, pulse_factor, crest_factor, margin_factor ]频域特征用rfft做实数FFT取幅值谱后计算重心频率和谱峭度。小波包部分我们用PyWavelets库三层分解后取8个子带的能量占比。整个过程在项目里被封装成一个特征提取管线输入一段4096点的原始振动信号输出一个23维的特征向量。做这件事的时候有个小技巧特征函数的输入输出最好保持统一的接口格式方便后续替换或者增加新的特征域。我们后来加装了包络谱特征和SVD熵特征就是通过在特征字典里增加新键值实现的。3.3 SMOTE实施与参数选择特征矩阵准备好之后正式进入Feature-level SMOTE环节。我们的实施顺序是先用StratifiedKFold做分层交叉验证的划分在每一折的训练集内部执行标准化和SMOTE测试集完全不参与。下面的代码展示了核心流程from sklearn.preprocessing import StandardScaler from imblearn.over_sampling import SMOTE from sklearn.pipeline import Pipeline preprocess_pipeline Pipeline(steps[ (scaler, StandardScaler()), (smote, SMOTE(sampling_strategyminority, k_neighbors3, random_state42)) ]) # 每一折训练集单独执行 X_resampled, y_resampled preprocess_pipeline.fit_resample(X_train, y_train)sampling_strategy参数我们做了一个折中处理。欠采样方案是把故障类扩增到正常类的1/3左右而不是直接追求1比1的完全平衡。原因在于生成样本数量过多会导致合成样本在特征空间里高度重叠分类器会过度拟合插值区域的边界真实故障样本泛化反而下降。我们最终设定的策略是早期故障类的合成样本扩增到约400条严重故障类扩增到约300条与正常类2000条相比处于1比5到1比7的比例区间再用class_weight参数让模型对少数类的误判施加额外惩罚。这样既给了模型足够的故障样本学习机会又保留了数据不平衡的原始约束算是一种平衡策略。另外一个值得注意的参数是k_neighbors。故障样本只有40到60条时默认的k_neighbors5会把近邻范围拉得太远生成样本可能落在早期故障和严重故障特征的模糊地带。我们将k调低到3生成样本分布更贴近各自的故障模式后续验证时F1分数比k5提升了约4个百分点。如果你的故障样本量更少比如少于20条可以考虑把k降到1或者2。如果样本量特别小SMOTE类方法本身就不太适合了需要考虑基于物理模型的仿真或者VAE/GAN生成。3.4 模型训练与评估指标过程采样阶段完成之后我们对比了多种模型输出。实际评估结果如下表所示三个方案分别是不做处理的原始不平衡数据、样本级SMOTE直接在原始信号上做时间序列插值、Feature-level SMOTE本文方法。评估方式统一为5折分层交叉验证测试集为完全未参与过采样的真实故障样本。方案正常类F1早期故障类F1严重故障类F1故障类平均召回率原始不平衡数据0.970.280.360.32样本级SMOTE0.950.510.470.49Feature-level SMOTE0.930.730.690.71正常类的F1分数略有下降是预料之中的——因为模型不再倾向把一切样本都预测为正常类这是过采样纠正偏差的正常代价。关键变化是故障类的召回率从0.32提升到了0.71。在PHM场景里故障被漏报造成的损失远大于正常工况被误报的损失所以这种代价完全可以接受。我们还额外关注了一个指标故障预警的平均提前时间。在实际验证中Feature-level SMOTE模型比直接训练的不平衡模型平均提前约12个采样周期捕捉到早期故障特征这对运维决策有实际意义因为意味着设备可以在故障发展成严重状态之前被安排停机检修。3.5 实际部署时必须注意的模型漂移问题部署阶段还有个容易被忽略的问题特征分布漂移。训练集和测试集来自同一时间段模型表现好但设备运行几个月后工况、负载、环境温度都可能变化特征分布会整体偏移SMOTE生成样本分布的合理性也随之下降。我们在部署系统中设置了周期性漂移检测每个月用最新采集的数据做一次特征分布对比如果KL散度超过阈值就触发增量训练。这个机制保证了模型上线后的稳定性而不是训练一次就一劳永逸。4. 实践中的常见问题与避坑指南4.1 特征泄漏过采样的前置条件问题这是新人在PHM项目里最容易犯的错而且问题隐蔽。如果把SMOTE放在数据切分之前整条数据集过采样后再划分训练测试集合成样本会同时出现在训练集和测试集里模型评估结果虚高得离谱。更要命的是如果SMOTE在标准化之前做合成样本的数值范围会受测试集统计量影响造成信息从测试集倒灌进训练集。正确的顺序必须严格固定为按时间段/设备组切分数据只在训练集内部做标准化和SMOTE测试集只能沿用训练集拟合好的标准化器做转换绝不能单独重新拟合。实践中还有一个容易被忽略的细节是标准化器的fit操作必须放在切分之后而不是在切分前用全部数据对特征做标准化否则测试集的均值方差还是会对训练过程产生间接影响。4.2 过采样比例不是越大越好很多文章在讲SMOTE时都默认把少数类扩增到和多数类一样多我们项目初期也是这么干的。把三类样本全部平衡到2000条之后模型的整体准确率确实很高但进一步分析发现故障类样本在特征空间里只覆盖了一个很小的区域强行生成2000条合成样本意味着大量的样本堆叠在同一个流形上。分类器学到的是那个小区域的精细边界而不是故障类的一般性规律。结果在后续新增的真实故障数据上验证时F1出现了明显下降。建议的策略是采用阶梯式过采样先把少数类扩充到多数类的1/4到1/3观察验证集表现再逐步调整比例。同时用class_weight做二次调节让模型天然对少数类更敏感。这样合成样本数量适度特征空间分布相对稀疏模型更容易学到泛化性的决策边界。我们最后用的比例是正常类2000、早期故障类400、严重故障类300配合自定义的类别权重效果比完全平衡好了不少。4.3 插值生成的样本是否合理如何快速验证Feature-level SMOTE最大的隐忧是生成样本在物理上可能是“假”的——特征值合理但是对应到设备状态并不存在。我们在项目里摸索出一个快速的验证方法用真实样本和合成样本一起做PCA或t-SNE可视化观察合成样本是否落在真实样本所在簇的附近。如果在低维投影中合成样本聚集成一个独立的小岛远离真实故障样本说明插值方向出了问题需要检查特征选择是否恰当或者k_neighbors是否过大跨越了不同退化状态。我们最早用样本级SMOTE时这个现象非常明显合成波形样本投影后散成一片完全看不出与真实故障样本的关联。换成Feature-level SMOTE并调整k参数后合成样本自然嵌入真实样本簇中说明插值生成的样本与真实故障在特征语义上是连续过渡的。做完可视化验证后我们还用了一个更严格的统计检验比较真实故障样本和合成样本在每个特征维度上的分布。对每个特征维度做KS检验如果超过一定比例的特征维度被检验出显著差异说明SMOTE生成的样本在局部细节上与真实故障有系统性差异需要回头调整特征工程方案。4.4 工业落地的额外心得与工程化建议最后分享几个我们在工程化过程中沉淀下来的经验。第一PHM项目的故障样本本质上不是可以无限采集的数据而是长期运维中缓慢积累的资产。SMOTE能解决的是建模阶段的样本不足问题它不能替代真实的故障数据积累和机理知识沉淀。我们在每个项目里都会建议客户建立故障案例知识库每发生一次故障都补充样本和特征标注SMOTE只是让这个过程中的每一步建模都能够用起来。第二特征工程和故障机理知识永远是这种场景下不可替代的价值。同样是做SMOTE特征空间选得好的团队和随手拿几个统计特征就上模型的团队最终效果差异巨大。小波包能量、包络谱特征、谱峭度这些特征也不是凭感觉选的而是结合设备结构轴承特征频率、齿轮啮合频率去设计出来的。想提升项目效果与其在SMOTE参数上反复调优不如多花时间把特征工程做得更贴合设备和故障机理。第三评估体系一定要贴近现场痛点。单纯追求准确率的PHM模型在工业现场站不住脚。现场运维人员关注的是“报警准不准”“漏报警多不多”“每次报警能提前多少时间”。我们在项目交付时用的指标体系包括故障召回率、误报率、平均提前预警时间、维护决策合理率等。模型在测试集上的F1分数再高在真实场景中不能帮助运维人员做出正确的维修决策这个模型就没有价值。如果后续需要在这个方向上继续扩展可以考虑把特征级数据增强与设备物理仿真结合先用仿真生成覆盖不同退化程度的物理样本再通过迁移学习把仿真知识迁移到真实设备上这能在工程师最头疼的“冷启动”阶段大幅增加可用的故障样本覆盖率。