尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

白鲸优化算法与核极限学习机:Python故障诊断实战

发布时间:2026/9/24 12:34:37

资讯中心
01
ARTICLE

白鲸优化算法与核极限学习机:Python故障诊断实战

白鲸优化算法与核极限学习机:Python故障诊断实战
简介面向Python开发者与工业智能运维研究者的故障诊断实战项目融合白鲸优化算法BWO与核极限学习机KELM完整呈现多参数优化、高维非线性故障数据处理、模型自动寻优与结果可视化思路。资源包为单份docx文档共1个文件、79KB内容覆盖环境准备、数据采集与预处理、特征提取、BWO参数优化、KELM模型训练与评估、GUI界面设计以及代码逐段详解模块划分清晰便于按章节研读。文档同时剖析了项目面临的挑战及针对性解决方案如多参数优化复杂性、计算资源限制和泛化能力不足等并给出应用领域与未来改进方向。目前已有55人学习尤其适合具备一定Python和机器学习基础、希望掌握智能优化算法与极限学习机联合应用场景的工程师和研究人员可直接据此复现实验并拓展到工业设备、电力系统、机器人等多类故障诊断任务中。1. 故障诊断 Python 项目BWO-KELM 到底在解决哪一类问题在轴承、齿轮箱和工业机器人关节的故障诊断场景里多数工程师手里攒下的不是“缺一个模型”而是一堆带标签的振动信号。常见做法是先算时域频域特征再丢进 SVM、随机森林或普通极限学习机里做分类。麻烦的是极限学习机虽然训练快却有随机初始化带来的输出波动核极限学习机KELM虽然精度高又把性能压在核宽 gamma 和正则化系数 C 两个参数上手动调到深夜也调不出稳定精度。白鲸优化算法BWO就是把这段“手动调参的玄学”变成迭代寻优的确定流程种群规模、迭代次数、搜索边界设好剩下交给算法自动找那组最适合当前故障样本的 KELM 参数。这篇笔记用 Python 串起一条可落地的路线原始振动信号 → 时域频域特征 → BWO 优化 KELM → 训练与预测 → GUI 可视化操作界面。轴承故障诊断、齿轮箱点蚀、工业机器人关节磨损这几类问题特征构造方式略有差别但模型主流程基本可以平移复用。适合刚接触数据驱动故障诊断的学生也适合手里有现场数据、但建模方案一直定不下来的工程师。2. 白鲸优化算法与核极限学习机这对组合为什么能稳定定位故障2.1 白鲸优化算法BWO的三个阶段与位置更新白鲸优化算法是近年来常用的一类元启发式寻优算法模拟白鲸群体的探索、捕食和鲸落三种行为。先说结论这类算法的工程价值不在数学推导多漂亮而在于它能把“KELM 的两个核心参数该设多少”这个问题变成一个十几行代码就能迭代求解的最优化问题。常见实现里BWO 把种群位置映射到待优化参数上每个个体就是一组 (C, gamma)。迭代过程中有两个主要阶段探索阶段模仿白鲸分散游动个体向随机位置偏移公式可以简写成 X_new X_i 0.3 × (X_rand − X_i) × r开发阶段模仿白鲸向猎物靠近个体朝当前全局最优位置靠拢公式简写为 X_new X_i 0.5 × (X_best − X_i) × r。这里的 r 是 0 到 1 之间的随机向量两个公式里的 0.3 和 0.5 是常见步长系数取值太大容易让位置在边界来回弹跳太小则收敛缓慢故障诊断这种小规模优化问题里一般不用改。还有一个容易被忽略的“鲸落”阶段用于模拟种群中的个体死亡后被随机替换。实际编程时我会保留它每隔一定概率把某个个体重置到搜索空间内防止整个种群过早聚到局部最优。很多网上流传的简化实现把这一步删了换一个数据集就翻车原因常常就是探索能力不足。2.2 核极限学习机KELM的推理逻辑与两个甜点参数极限学习机ELM的核心思想是随机设定输入层权重和偏置只求解输出层权重。把输入样本映射到隐藏层特征空间后得到隐藏层输出矩阵 H求解输出权重 β H†T其中 H† 是 H 的 Moore-Penrose 广义逆。ELM 训练速度极快但随机初始化让同一份数据两次训练结果可能差一两个百分点这在故障诊断里很要命——同一个轴承样本今天训练完准确率 97%明天重跑变 94%文档没法写。核极限学习机把隐藏层映射替换成核函数不再需要显式设定隐藏层节点数。它的预测公式可以写成 f(x) K(x, X) · (K(X, X) I/C)⁻¹ · T其中 K 是核矩阵I 是单位矩阵C 是正则化系数T 是训练标签矩阵。这个形式跟支持向量机有点像但没有 SVM 的拉格朗日乘子求解那么复杂。KELM 只需要调两个参数正则化系数 C 和核宽度 gamma也叫 sigma。C 控制过拟合风险C 越大越容易贴着训练样本走现场数据噪声一大就容易失真gamma 控制核函数的径向作用范围gamma 过小会让核矩阵对角元素主导每两个样本之间的相似度都趋近于零预测结果变成“一票否决制”gamma 过大则所有样本都长得差不多分类边界退化。故障诊断里大多数场景是少样本、类别不均衡、伴随噪声KELM 对小样本的适应能力比深度模型好而且不需要 GPU一台普通工控机就能跑。这也是它至今仍在工业运维代码里大量出现的原因。2.3 耦合与适应度函数BWO 到底在优化什么BWO 和 KELM 的耦合点非常明确BWO 负责搜索 (C, gamma)KELM 负责用这组参数训练并输出一个误差指标这个指标就是适应度。适应度函数设计决定整套方案的上限。常见做法是把训练集再分成五折每次用四折训练 KELM、一折验证算平均错误率而不是简单把训练集自己跑一遍。原因是 KELM 的通用能力受 C 和 gamma 影响明显只在训练集上表现好并不代表能泛化到新采样的振动信号。这里有个经典坑BWO 内部是找适应度最小值所以适应度函数必须返回“错误率”不要顺手写成“准确率”。准确率越高越好错误率越低越好方向反了BWO 会直接往最差的参数方向收敛。画混淆矩阵的时候不会发现问题但看训练日志就会发现 best_fitness 一路飙升。BWO 需要设置的参数说多不多说少不少真正必须调的四个参数如下表参数含义常见范围取值影响n_whale种群个体数1030太小易早熟太大训练时间线性增长max_iter最大迭代次数2050故障诊断样本少50 次以内足够收敛lb / ub搜索边界C: 1e-21e2gamma: 1e-21e1边界太窄容易漏解太宽浪费迭代适应度折数验证折数5 折样本少时用 3 折避免训练集过薄注意表中参数边界说的是线性空间。C 和 gamma 的有效跨度常常跨越几个数量级直接用线性空间搜索会漏掉小数值。经验做法是对 lb、ub 取对数让 BWO 在对数空间里寻优后面第 4 章的代码里我会写清楚。3. 故障信号变特征把振动波形做成 BWO-KELM 能学会的输入矩阵3.1 数据集读入与滑窗分段故障诊断项目的第一步不是建模而是把原始信号切成能喂给模型的样本。以轴承故障诊断为例公开可用的数据集包括凯斯西储大学轴承数据中心以及近年发布的“基于数据驱动的加工产线工业机器人内部轴承故障诊断方法数据集”后者更贴近产线实际负载和噪声环境。不管用哪个数据源读入后的原始数据都是一长串振动幅值序列长度动辄几万点不可能整段丢给模型。常见做法是滑窗分段设定窗口长度 win_len按步长 step 滑动切分每段样本计算一组特征。窗口长度至少要覆盖 2 到 3 个旋转周期比如转速 1500 转/分对应转频 25Hz采样率 2560Hz 时一个周期约 102 个点窗口取 512 或 1024 比较稳妥。步长一般取窗口的一半既保留一定重叠让样本数量足够又不会让相邻样本高度重复导致过拟合。读入阶段顺手做两件事一是检查数据里有没有 NaN 或幅值异常跳变采集卡掉线经常在文件中间留一段常数二是按故障类型建立标签映射比如 0 代表正常、1 代表内圈故障、2 代表外圈故障、3 代表滚动体故障标签用整数编码而不是字符串后面算混淆矩阵省事。3.2 时域统计和频域特征提取哪些信息对故障敏感原始振动波形直接喂给 KELM 不是不行但特征维度高、计算慢而且对噪声和负载变化很敏感。工业现场更常用的是把每段信号压缩成一组统计特征我用得最多的是以下几个时域特征里有效值RMS反映振动能量整体水平故障越严重 RMS 往往越大峰值因子是峰值除以 RMS早期局部损伤会产生明显冲击峰值因子会先升高峭度对冲击信号极其敏感正常轴承峭度接近 3出现点蚀或剥落时峭度会明显增大。这几个特征组合起来基本能把“正常”和“有故障”分开。频域特征里频谱质心反映信号能量在频带中的重心位置故障引起的冲击会抬高高频成分质心随之右移主峰频率则对应转频或其倍频。只取整个频谱的稀疏特征就能大幅降低输入维度又不丢主要诊断信息。下面的代码把上述特征封装成一个函数输入一段信号输出一个六维特征向量import numpy as np from scipy import stats from scipy.fft import rfft, rfftfreq def extract_features(signal, fs2560): # 时域特征均值、有效值、峰值因子、峭度 mean_val np.mean(signal) rms_val np.sqrt(np.mean(signal ** 2)) peak_val np.max(np.abs(signal)) peak_factor peak_val / (rms_val 1e-9) # 避免除零 kurt_val stats.kurtosis(signal, fisherFalse) # 频域特征频谱质心、主峰频率 spec np.abs(rfft(signal - mean_val)) # 去掉直流分量再看频谱 freqs rfftfreq(len(signal), d1.0 / fs) centroid np.sum(freqs * spec) / (np.sum(spec) 1e-9) main_freq freqs[np.argmax(spec)] return np.array([mean_val, rms_val, peak_factor, kurt_val, centroid, main_freq], dtypenp.float32)逻辑说明mean_val 用于后续去直流不直接参与诊断但去掉直流后再算频谱主峰频率才对应真正的旋转频率分量。peak_factor 和 kurt_val 是故障诊断里最有效的两个时域指标齿轮断齿、轴承剥落这类冲击性故障在这两个特征上会同时出现明显偏离。centroid 和 main_freq 反映频带重心和主频率位置用于区分不同故障部位引起的频率结构变化。参数说明fs 必须和采集设备实际采样率一致否则 rfftfreq 生成的频率轴整体偏掉centroid 和 main_freq 全部失去物理意义采样率 2560Hz 是比较保守的工业监测常用值如果采集卡是 12.8kHz记得改这个参数。np.float32 主要是省内存几万段样本时差别明显精度影响基本可忽略。3.3 标准化与训练测试划分别踩数据泄漏样本特征构造完之后标准化是必需步骤因为 RMS 和频谱质心的量级差了几十甚至上百倍KELM 核函数计算的是样本间距离量级大的特征会直接压掉量级小的特征。但标准化这一步最容易踩到数据泄漏很多新手把 StandardScaler 直接 fit 到整个数据集上然后再划分训练集和测试集相当于测试集的均值、方差已经提前偷看到了。正确做法是先按分层抽样切分训练集和测试集再用训练集 fit 标准化器最后用同一个标准化器去 transform 测试集。结合特征提取的完整流程如下from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler X [] # 特征矩阵行是样本列是特征 y [] # 标签向量整数编码 for path, label in data_list: # data_list 为(文件路径, 标签)列表 raw np.loadtxt(path) for start in range(0, len(raw) - win_len, step): seg raw[start:start win_len] X.append(extract_features(seg, fs)) y.append(label) X np.vstack(X) y np.array(y) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, stratifyy, random_state42) scaler StandardScaler().fit(X_train) # 只对训练集 fit X_train_s scaler.transform(X_train) X_test_s scaler.transform(X_test) # 测试集继承同一组统计量逻辑说明train_test_split 里 stratifyy 表示按标签比例分层抽样故障诊断数据里正常样本往往占大头不做分层容易让某一类在测试集里一个样本都没有。random_state42 是固定随机种子保证每次运行切分一致后面调 BWO 参数时才能对比准确率变化。参数说明数据泄漏是个隐蔽问题如果在标准化后再切分验证集上的准确率会虚高 310 个百分点看起来模型很好一到现场新数据就崩。判断标准很简单标准化器的 fit 对象必须严格来自训练集。另外注意滑窗后的相邻样本高度相关如果切分时不做任何处理测试集里可能混着训练样本的“近亲”表现也会虚高更严格的做法是按时间序列顺序切分但本文场景里分层随机切分基本够用。4. Python 完整实现BWO-KELM 训练主流程加 GUI 骨架4.1 KELM 训练和预测子函数KELM 代码实现核矩阵需要 O(N²) 的存储特征维度不高、样本量在几千这个量级时完全没问题。RBF 核矩阵的计算可以写成下面这样import numpy as np def rbf_kernel_matrix(X, Y, sigma): n1, n2 X.shape[0], Y.shape[0] K np.zeros((n1, n2)) for i in range(n1): diff X[i] - Y # 广播计算第 i 行与所有样本的差 K[i, :] np.exp(-np.sum(diff ** 2, axis1) / (2 * sigma ** 2)) return K def kelm_train(X_train, T_train, C1.0, sigma1.0): N X_train.shape[0] Omega rbf_kernel_matrix(X_train, X_train, sigma) A np.linalg.inv(Omega np.eye(N) / C) beta A T_train # beta 就是输出权重矩阵 return beta def kelm_predict(X_test, X_train, beta, sigma): Ks rbf_kernel_matrix(X_test, X_train, sigma) return Ks beta逻辑说明kelm_train 中 Omega 是训练样本间的核矩阵np.eye(N)/C 相当于对对角线加一个正则项C 越大正则越弱越容易过拟合。beta 是输出层权重kelm_predict 直接用测试样本与训练样本的核矩阵乘 beta得到的是每个类别的得分取 argmax 就能得到类别标签。参数说明T_train 不能直接传一维整数标签要做 one-hot 编码否则 KELM 会把类别序号当成回归目标排序关系会误导分类边界。sigma 是核宽度太小核矩阵趋近于单位阵预测时只有“自己像自己”泛化能力几乎为零太大所有样本相似度趋同类别边界消失。常见起点是取特征维度的平方根附近再用 BWO 在这个起点附近搜索。4.2 BWO 主循环与适应度计算BWO 主循环里我们用对数空间表示 C 和 gamma主要是为了让搜索步长在数量级层面均匀变化。下面是一个可直接跑的简化版本def decode_position(pos): 位置向量转成真实参数, 对数空间解码 C 10.0 ** pos[0] sigma 10.0 ** pos[1] return C, sigma def objective(pos, X_train, y_train_onehot, n_folds5): C, sigma decode_position(pos) if C 0 or sigma 0: return 1e9 # 非法参数直接惩罚 # 五折交叉验证, 返回平均错误率作为适应度 fold_size len(X_train) // n_folds err_sum 0.0 for k in range(n_folds): idx_val np.arange(k * fold_size, (k 1) * fold_size) mask np.ones(len(X_train), dtypebool) mask[idx_val] False beta kelm_train(X_train[mask], y_train_onehot[mask], C, sigma) pred kelm_predict(X_train[idx_val], X_train[mask], beta, sigma) pred_label np.argmax(pred, axis1) true_label np.argmax(y_train_onehot[idx_val], axis1) err_sum np.mean(pred_label ! true_label) return err_sum / n_folds逻辑说明objective 内每折只从训练集里切一部分做验证BWO 寻优过程完全不接触测试集。返回平均错误率错误率越低越好。C 或 sigma 小于等于零时直接返回一个极大惩罚值防止 KELM 核矩阵计算出 NaN。接着是 BWO 的种群更新主循环def bwo_optimize(obj_func, dim2, n_whale12, max_iter30, lb(-2.0, -2.0), ub(2.0, 1.0)): # lb/ub 是 C 和 sigma 的以 10 为底的指数范围 pos np.random.uniform(lb, ub, (n_whale, dim)) fit np.array([obj_func(p) for p in pos]) global_best pos[np.argmin(fit)].copy() best_f fit.min() for t in range(max_iter): wf 0.1 0.9 * (1.0 - t / max_iter) # 探索概率递减 for i in range(n_whale): if wf 0.5: # 探索阶段: 向随机个体游动 j np.random.randint(n_whale) new_pos pos[i] 0.3 * (pos[j] - pos[i]) * np.random.random(dim) else: # 开发阶段: 向全局最优靠拢 new_pos pos[i] 0.5 * (global_best - pos[i]) * np.random.random(dim) if np.random.rand() 0.1: # 鲸落重置, 跳出局部最优 new_pos np.random.uniform(lb, ub) new_pos np.clip(new_pos, lb, ub) new_fit obj_func(new_pos) if new_fit fit[i]: pos[i], fit[i] new_pos, new_fit idx np.argmin(fit) if fit[idx] best_f: global_best pos[idx].copy() best_f fit[idx] best_C, best_sigma decode_position(global_best) return best_C, best_sigma, best_f逻辑说明wf 从 1.0 递减到 0.1前期偏重探索、后期偏重开发这是元启发式算法的通用节奏。鲸落概率 0.1 是常见取值太低起不到跳出局部最优的作用太高会让种群一直处于“重置—重学”的状态收敛不稳定。np.clip 必须放在目标函数调用之前确保每次迭代的每个位置都是合法参数。参数说明lb 和 ub 这里取的是对数值(-2, -2) 到 (2, 1) 对应 C 在 10⁻² 到 10²、sigma 在 10⁻² 到 10¹ 之间。最大迭代 30 次、种群 12 个个体时一次寻优要做 12 × 30 360 次 KELM 训练每次训练几十毫秒总共十几秒现场完全接受。如果数据量大可以先把种群减到 10、迭代减到 20优先保障能跑通。4.3 主函数运行与 PyQt5 GUI 骨架主函数把前面几段串起来同时预留 GUI 入口。命令行方式适合调试GUI 方式适合交给不会配环境的同事。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler def main(): data_list load_data_list(data/config.csv) # 文件名和标签的映射表 X, y build_feature_matrix(data_list, fs2560, win_len1024, step512) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, stratifyy, random_state42) scaler StandardScaler().fit(X_train) X_train_s scaler.transform(X_train) X_test_s scaler.transform(X_test) # 标签 one-hot from sklearn.preprocessing import OneHotEncoder enc OneHotEncoder(sparse_outputFalse) y_train_oh enc.fit_transform(y_train.reshape(-1, 1)) best_C, best_sigma, best_err bwo_optimize( lambda p: objective(p, X_train_s, y_train_oh), max_iter30) beta kelm_train(X_train_s, y_train_oh, best_C, best_sigma) pred kelm_predict(X_test_s, X_train_s, beta, best_sigma) acc np.mean(np.argmax(pred, axis1) y_test) print(fbest_C{best_C:.4f}, best_sigma{best_sigma:.4f}, test_acc{acc:.4f}) if __name__ __main__: main()逻辑说明lambda p: objective(p, X_train_s, y_train_oh) 把 BWO 的适应度函数和当前训练集绑定避免在 objective 内部重复读全局变量。训练完成后用测试集做一次最终评估这个准确率才是文档里能写的数字。GUI 骨架方面PyQt5 是 Python 桌面端最稳的选择。BWO 寻优过程要跑几十秒绝不能直接放在按钮的回调函数里否则界面会假死。标准做法是把训练逻辑放进 QThreadfrom PyQt5 import QtCore, QtWidgets class TrainWorker(QtCore.QThread): progress QtCore.pyqtSignal(int) result_ready QtCore.pyqtSignal(dict) def __init__(self, X_train, y_train_oh, X_test, y_test): super().__init__() self.X_train, self.y_train_oh X_train, y_train_oh self.X_test, self.y_test X_test, y_test def run(self): # 子线程入口, 不要手动调用 n_steps 30 for it in range(n_steps): self.progress.emit(int((it 1) / n_steps * 100)) best_C, best_sigma, best_err bwo_optimize( lambda p: objective(p, self.X_train, self.y_train_oh), max_itern_steps) self.result_ready.emit({C: best_C, sigma: best_sigma, err: best_err}) # 界面侧只需要创建 Worker、连接信号、启动线程逻辑说明QThread 里 run() 是子线程入口训练循环和 BWO 寻优都放在这里。progress 信号每迭代一次发一次进度百分比result_ready 信号在训练结束后把参数打包传回主线程。界面侧拿到 result_ready 信号后再刷新文本框和图表。参数说明PyQt5 要求信号参数必须是可序列化类型dict、list、str 都没问题但不要在信号里直接传 numpy 数组。训练前把 X_train、y_train_oh 作为 Worker 的构造参数传入子线程内不要再去访问界面控件这是界面闪退的主要来源。5. BWO-KELM 故障诊断实现避坑5 个容易翻车的地方5.1 标准化时把全部数据先算了一遍准确率虚高 20%现象训练完打印测试准确率 98%感觉很完美换成现场新采集的数据直接掉到 82%。原因StandardScaler 在切分前 fit 了整个数据集测试集的均值和方差已经被模型“偷看”过了属于典型的数据泄漏。解决严格按本文 3.3 的顺序先切分再 fit 训练集再 transform 测试集。判断标准是写代码时问一句scaler.fit 拿到的是不是只有训练集数据5.2 BWO 搜索在参数边界内反复跳动找不到稳定解现象训练日志里 best_fitness 一直在波动每次运行得到的 C 和 sigma 都不一样测试准确率忽高忽低。原因C 和 sigma 的解空间跨度相差几个数量级在线性空间里搜索时小数值区域占的“面积”太小BWO 个体大概率落在高位区间找不到最优的小参数组合。解决把低位、高位对应的对数值作为 lb 和 ub位置解码时用 10 的幂还原真实参数。decode_position 里那一行 pow(10, pos[0]) 看着简单实际提升效果非常明显。5.3 KELM 预测结果全部输出同一个类别现象训练完成测试集准确率只有 30%40%打印预测标签发现全部是类别 0。原因最常见的是 gamma 设得太小RBF 核矩阵除了对角线以外全部接近 0每个测试样本都只“认识”自己输出权重被训练集中占多数的类别主导另一种可能是 one-hot 编码没做把标签当成回归目标训练了。解决先用一个中等大小的固定核宽跑一次比如 sigma sqrt(特征维度)确认分类器能出多类别结果再交给 BWO 去优化。另外检查 T_train 是否经过了 OneHotEncoder。5.4 GUI 点击“开始训练”按钮后窗口无响应、变白现象界面一卡就是二三十秒拖动窗口也没反应甚至被系统提示“未响应”。原因BWO 优化循环被直接写在按钮的 clicked 信号槽里整个训练过程占住了 Qt 主线程界面刷新事件排不上队。解决把 BWO 的优化循环挪到 QThread 的 run() 方法里界面的按钮只负责创建线程、启动线程。记住一条原则界面线程永远只做绘制和事件分发任何超过 0.1 秒的计算都不要直接放在槽函数里。5.5 固定了随机种子两次运行结果还是不一样现象代码里明明设置了 np.random.seed(42)但重复运行测试准确率还是差 12 个百分点。原因BWO 的种群初始化和 KELM 训练本身不涉及随机但 train_test_split 和 KELM 内部如果使用 sklearn 的随机流程需要分别对相关组件设置 random_state更常见的原因是交叉验证切分用的是随机索引每次运行的验证集不同适应度算出来就有波动。解决目标函数里把交叉验证的折索引固定下来比如用 np.arange 预生成 fold 索引不依赖随机函数。不要在 bwo_optimize 里像网上某些示例那样每迭代一次才生成 fold这样最终结果完全没有可复现性。6. 验证方法让 BWO-KELM 的诊断结果可比较、可上线BWO-KELM 跑通之后最容易被质疑的就是“你的准确率是不是凑出来的”。我一般会做三层验证第一层是重复实验。BWO 本身有随机性单次运行的最优参数不能直接信固定随机种子跑 5 次记录每次测试准确率、F1-score 和对应参数最终输出时用 5 次的均值和标准差。如果标准差超过 2%说明搜索空间或种群大小有问题先回头调 lb、ub而不是换网络结构。第二层是类别粒度验证。故障诊断里“正常”样本往往多模型把所有数据都判成正常也能有很高准确率所以只看准确率不够。用 sklearn 的 classification_report 输出每一类的精确率和召回率重点看故障类别是否被漏报。现场故障漏报的代价远大于误报如果召回率低于 90%建议在特征工程里补加频带能量特征或者把损失函数改为类别加权。第三层是混淆矩阵分析。哪个故障类别经常被错分到另一类往往对应特征层面的混淆。比如内圈故障和外圈故障的频域特征接近那就要检查是不是只用了时域统计特征没把特征频率和边带信息加进去。我的习惯是把混淆矩阵随模型一起导出成图片和诊断报告放在同一个目录别人复查时可以直接看到模型的犯错模式。from sklearn.metrics import confusion_matrix, classification_report import matplotlib.pyplot as plt def report_model(y_true, y_pred, class_names): cm confusion_matrix(y_true, y_pred) plt.matshow(cm, cmapBlues) plt.colorbar() plt.xlabel(Predicted) plt.ylabel(True) plt.savefig(confusion_matrix.png, dpi200) print(classification_report(y_true, y_pred, target_namesclass_names, digits4))这一小段代码每次训练完固定执行输出既有人能读的文本报告也有可贴到测试报告里的图片。参数说明class_names 建议用“正常/内圈故障/外圈故障/滚动体故障”这种可读标签别用 0、1、2、3否则现场同事看图还得对着编码表。我自己的习惯是每次调完参数把 BWO 找到的最优参数、5 次重复实验的均值标准差、混淆矩阵三个文件一起归档文件名带上数据批次和日期。这样一个月后回头复查还能清楚当时是怎么调出来的。希望这一步能帮你在故障诊断项目上少走几段弯路也让你交出去的模型不再是个说不清来路的黑匣子。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。