基于Python的齿轮故障诊断:从振动信号到可交付源码的完整路径

发布时间:2026/10/12 14:14:52
基于Python的齿轮故障诊断:从振动信号到可交付源码的完整路径 简介这份资源面向高校学生与初级开发者提供一套基于Python的齿轮故障诊断完整实现方案可用于毕业设计、课程设计或项目开发练手。包内共7个文件以3个py源码文件为核心分别实现基于Adaboost与Logistic的齿轮故障分类诊断2个csv文件为训练与测试数据集2个txt文件记录齿轮测试数据特征压缩包整体约38KB体量轻便、结构清晰便于快速上手与二次开发。目前已有174人学习下载说明该方案在同类课程作业中具备一定参考价值。读者可获得从特征数据到模型训练、测试评估的完整流程代码理解Adaboost与Logistic两种算法在齿轮故障识别中的具体应用方式并可直接在现有数据上运行验证、替换算法或扩充特征作为进一步研究故障诊断的起点。1. 齿轮故障诊断大作业从振动信号到可交付源码的完整路径做旋转机械状态监测的工程师几乎都绕不开齿轮箱这个对象。它结构紧凑、传动比大但一旦齿面点蚀、断齿或轴承磨损整条产线就得停。很多同学在期末大作业里第一次接触「基于python开发的齿轮故障诊断诊断数据测试源码」这类题目拿到手往往一脸懵数据从哪来、特征怎么提、模型怎么选、测试怎么写。这篇笔记就按一线做项目的顺序把这条链路拆开讲清楚——从公开数据集选型到用 Python 做时域频域特征提取再到分类模型训练、测试脚本编写最后落到几个容易翻车的地方。适合正在赶大作业的学生也适合刚转做设备诊断、想用 Python 快速搭一套可复现流程的工程师。整套方案不依赖昂贵采集卡一台普通笔记本就能跑通。2. 齿轮诊断数据从哪来公开数据集选型与本地加载2.1 为什么优先用凯斯西储与齿轮箱专用数据集齿轮故障诊断的公开数据不像图像分类那么随手可得常见做法是两条路一是用凯斯西储大学CWRU的轴承数据做迁移练手二是找齿轮箱专用数据集比如东南大学齿轮箱数据、PHM 2009 齿轮箱挑战赛数据。CWRU 的好处是标注清晰、采样率高、社区资料多缺点是它本质是轴承不是齿轮直接套用会让答辩老师追问「你这到底诊断的是齿轮还是轴承」。所以我的建议是如果大作业允许自选优先找齿轮箱专用数据如果只能用 CWRU就在报告里明确说明这是方法验证齿轮与轴承在故障机理上有共性。选数据时要盯三个参数采样频率、转速、故障类型标签。采样频率决定了你能分析到多高的频率成分齿轮啮合频率通常在几千赫兹采样率至少要 10 kHz 以上才够用。转速决定了转频和啮合频率的换算关系没有转速就没法做阶次分析。故障类型标签则直接决定你是做二分类还是多分类。2.2 用 scipy 读取 mat 与 csv 数据的标准写法拿到数据后第一步是加载。CWRU 是 .mat 格式齿轮箱数据常见 .csv 或 .txt。下面这段代码把两种格式统一读成 numpy 数组并做基本的维度检查。import numpy as np import scipy.io as sio import pandas as pd def load_mat_signal(path, keyNone): 读取 .mat 文件中的振动信号key 为空时自动取第一个非元数据变量 mat sio.loadmat(path) if key is None: # 过滤掉 __header__ 等元数据键 keys [k for k in mat.keys() if not k.startswith(__)] key keys[0] signal mat[key].ravel().astype(np.float64) return signal def load_csv_signal(path, colvibration): 读取 csv 中的单列振动信号 df pd.read_csv(path) signal df[col].values.astype(np.float64) return signal # 使用示例 sig load_mat_signal(gear_data/normal_01.mat) print(采样点数:, sig.shape, 均值:, sig.mean(), 标准差:, sig.std())逻辑说明ravel()把可能的多维数组压成一维避免后续 FFT 报维度错误astype(np.float64)保证数值精度防止整型数据在频域计算时溢出。参数上key用于指定 .mat 里的变量名不同数据集变量名不一样自动取第一个非元数据键是个稳妥的兜底。加载完一定要打印均值和标准差如果均值偏离 0 很远说明信号有直流偏置后面做频域分析前要先减去均值。2.3 数据切片与训练集划分的注意点原始信号往往是一长段连续采集不能整段丢给模型。常见做法是用滑动窗口切片窗口长度一般取 1024 或 2048 点重叠率 50%。窗口太短频率分辨率不够太长则样本数太少。划分训练测试集时绝对不能随机打乱同一条连续信号切出来的窗口否则训练集和测试集会高度相关准确率虚高。正确做法是按采集批次或时间段划分比如前 70% 时间的数据做训练后 30% 做测试。def sliding_window(signal, win1024, step512): 滑动窗口切片返回二维数组 (样本数, 窗口长度) segments [] for start in range(0, len(signal) - win 1, step): segments.append(signal[start:start win]) return np.array(segments) segments sliding_window(sig, win1024, step512) print(切片后样本数:, segments.shape)这里win1024对应采样率 12 kHz 时频率分辨率约 11.7 Hz足够分辨齿轮啮合频率的边带。step512即 50% 重叠能在样本数和信息量之间取得平衡。切片后建议做一次归一化把每个窗口减去自身均值再除以标准差消除不同采集批次的幅值差异。3. 特征工程时域、频域与包络谱三路特征怎么提3.1 时域特征峭度、裕度与均方根的物理含义时域特征是最快能算出来的一批指标。均方根RMS反映振动能量适合判断整体劣化峭度Kurtosis对冲击成分敏感齿轮断齿、点蚀会产生周期性冲击峭度会明显升高裕度因子Crest Factor 的变体是峰值与均方根的比值对早期故障比 RMS 更灵敏。但峭度有个坑当故障严重到一定程度冲击变得密集峭度反而会下降所以不能只看单一指标。from scipy.stats import kurtosis, skew def time_features(x): 计算常用时域特征 rms np.sqrt(np.mean(x ** 2)) peak np.max(np.abs(x)) kurt kurtosis(x, fisherTrue) # 正态分布时接近 0 skewness skew(x) crest peak / (rms 1e-12) # 加小量防止除零 return { rms: rms, peak: peak, kurtosis: kurt, skewness: skewness, crest: crest } feat time_features(segments[0]) print(feat)fisherTrue让正态分布的峭度输出 0 而不是 3便于判断异常。1e-12是防止信号全零时除零的后悔药。实际用的时候这几个特征要按窗口逐个算拼成一个特征向量。3.2 频域特征用 FFT 与包络谱定位啮合频率频域是齿轮诊断的主战场。齿轮啮合频率等于转频乘以齿数故障会在啮合频率及其边带附近出现能量变化。直接对原始信号做 FFT 往往被转频和噪声淹没所以要先做包络解调。常见做法是希尔伯特变换取包络再对包络做 FFT这样能把高频载波上的故障调制信息搬到低频看得更清楚。from scipy.fft import fft, fftfreq from scipy.signal import hilbert def envelope_spectrum(x, fs): 计算包络谱 analytic hilbert(x) envelope np.abs(analytic) envelope envelope - envelope.mean() # 去直流 n len(envelope) yf np.abs(fft(envelope))[:n // 2] xf fftfreq(n, 1 / fs)[:n // 2] return xf, yf xf, yf envelope_spectrum(segments[0], fs12000) # 找出包络谱前 5 个峰值对应的频率 idx np.argsort(yf)[-5:] print(主要频率成分:, xf[idx])hilbert返回解析信号取模得到包络。去直流这一步很关键否则包络谱在 0 Hz 处会有一个巨大峰值把其他成分压得看不见。fftfreq生成频率轴fs是采样率必须和实际采集一致填错了频率轴全错。拿到包络谱后重点看转频的整数倍以及啮合频率附近有没有异常边带。3.3 特征拼接与标准化别让量纲差异毁掉模型时域特征和频域特征的量纲差好几个数量级RMS 可能是 0.1 量级而某个频域幅值可能是几百。如果直接拼起来丢给 SVM 或 KNN量纲大的特征会主导距离计算。所以拼接后必须做标准化常用 Z-score 或 Min-Max。from sklearn.preprocessing import StandardScaler def build_feature_matrix(segments, fs): rows [] for seg in segments: tf time_features(seg) xf, yf envelope_spectrum(seg, fs) # 取包络谱在 0-500Hz 内的能量和作为频域特征 mask xf 500 freq_energy np.sum(yf[mask] ** 2) rows.append([tf[rms], tf[kurtosis], tf[crest], freq_energy]) X np.array(rows) scaler StandardScaler() X_scaled scaler.fit_transform(X) return X_scaled, scaler X, scaler build_feature_matrix(segments, fs12000) print(特征矩阵形状:, X.shape)StandardScaler的fit_transform只能在训练集上 fit测试集要用同一个 scaler 做 transform否则就是数据泄露。这一点在写大作业测试脚本时特别容易翻车很多人图省事对全体数据 fit结果测试准确率虚高答辩时被一问就露馅。4. 分类模型与测试脚本从 SVM 到轻量 CNN 的取舍4.1 小样本下为什么 SVM 往往比深度学习稳大作业的数据量通常不大每个故障类别可能就几十到几百个样本。这种规模下SVM 配合 RBF 核往往比 CNN 更稳训练快、调参少、不容易过拟合。CNN 要发挥作用通常需要上万样本或者用数据增强、迁移学习来补。所以我的建议是先用 SVM 跑一个基线如果准确率已经 90% 以上就没必要硬上深度学习如果 SVM 卡在 70% 上不去再考虑 CNN 或增加特征维度。from sklearn.svm import SVC from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 假设 y 是标签数组按时间段划分训练测试 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, shuffleFalse) # shuffleFalse 按顺序切避免泄露 clf SVC(kernelrbf, C10, gammascale) clf.fit(X_train, y_train) y_pred clf.predict(X_test) print(classification_report(y_test, y_pred))shuffleFalse是按时间顺序切分配合前面按时间段划分的原则。C10是惩罚系数越大越容易过拟合gammascale让核宽度随特征方差自适应比手动设值省心。classification_report会输出每个类别的精确率、召回率和 F1比只看总准确率更能发现问题——如果某个故障类别召回率特别低说明特征对该故障不敏感。4.2 用 pytest 写可复现的测试用例大作业要求「测试」很多人只写一个print(accuracy)就交差。规范的测试应该用 pytest 写成断言这样换台机器、换个数据也能快速验证流程没坏。下面是一个最小测试文件。# test_diagnosis.py import numpy as np import pytest from diagnosis import time_features, envelope_spectrum, sliding_window def test_sliding_window_shape(): sig np.random.randn(5000) segs sliding_window(sig, win1024, step512) assert segs.shape[1] 1024 assert segs.shape[0] 0 def test_time_features_on_sine(): t np.linspace(0, 1, 12000) sig np.sin(2 * np.pi * 50 * t) feat time_features(sig) assert abs(feat[rms] - 0.707) 0.01 # 正弦波 RMS 约 0.707 assert abs(feat[kurtosis]) 0.1 # 正弦波峭度接近 0 def test_envelope_spectrum_peak(): fs 12000 t np.arange(0, 1, 1 / fs) carrier np.sin(2 * np.pi * 2000 * t) modulation 1 0.5 * np.sin(2 * np.pi * 50 * t) sig carrier * modulation xf, yf envelope_spectrum(sig, fs) peak_freq xf[np.argmax(yf)] assert abs(peak_freq - 50) 5 # 包络谱峰值应在调制频率 50Hz 附近这三个测试分别验证切片形状、时域特征数值、包络谱峰值位置。test_time_features_on_sine用正弦波的解析解做基准RMS 理论值 0.707峭度理论值 0容差设 0.01 和 0.1 是给数值计算留余量。test_envelope_spectrum_peak构造了一个 2000 Hz 载波被 50 Hz 调制的信号包络谱峰值应该出现在 50 Hz容差 5 Hz 是考虑 FFT 频率分辨率。跑pytest -v就能看到每个用例通过与否比手动 print 靠谱得多。4.3 混淆矩阵与误诊分析准确率之外的真相总准确率 95% 听起来不错但如果 5% 的错误全集中在「断齿误判为正常」那这个模型在工业场景就是不可用的因为漏报比误报危险得多。所以测试阶段一定要看混淆矩阵重点看每个故障类别的召回率。from sklearn.metrics import confusion_matrix import seaborn as sns import matplotlib.pyplot as plt cm confusion_matrix(y_test, y_pred) sns.heatmap(cm, annotTrue, fmtd, cmapBlues) plt.xlabel(预测标签) plt.ylabel(真实标签) plt.title(齿轮故障诊断混淆矩阵) plt.savefig(confusion_matrix.png, dpi150)画出来之后如果发现某一类召回率低于 80%就要回头查特征是不是该类故障的样本太少或者特征对该故障不敏感。常见补救是增加该类样本的窗口重叠率或者针对该故障机理补充特定频段特征。5. 避坑与排查齿轮诊断大作业里最容易翻车的五件事5.1 采样率填错导致频率轴整体偏移现象包络谱峰值出现在明显不合理的频率上比如转频应该是 25 Hz 却显示 50 Hz。原因fftfreq里的fs和实际采集采样率不一致或者数据做了降采样但没更新fs。解决在加载数据后立刻打印采样率和数据集说明文档核对如果做了降采样fs要同步除以降采样倍数。5.2 训练测试随机打乱造成准确率虚高现象交叉验证准确率 99%但换一批数据测试就掉到 60%。原因同一条连续信号切出的窗口被随机分到训练集和测试集两者高度相似模型等于在背答案。解决按采集批次或时间段划分train_test_split设shuffleFalse并在报告里说明划分依据。5.3 标准化在划分之前做导致数据泄露现象测试集准确率异常高但实际部署效果差。原因先对全体数据做fit_transform再划分测试集的均值和方差信息泄露到了训练过程。解决先划分再在训练集上fit测试集只做transform。用Pipeline可以自动避免这个错误。5.4 峭度指标在严重故障时反而下降现象轻度故障样本峭度高重度故障样本峭度反而低模型把重度故障误判为正常。原因故障严重后冲击变得密集信号趋近高斯分布峭度回落。解决不要单用峭度配合 RMS 和包络谱能量一起判断或者用多个时间尺度的峭度。5.5 包络谱去直流遗漏导致峰值被淹没现象包络谱 0 Hz 处有一个巨大峰值其他频率成分完全看不见。原因希尔伯特变换后的包络含有直流分量没有减去均值。解决envelope envelope - envelope.mean()这一步不能省减完之后再画谱。6. 把大作业变成能写进简历的项目三个进阶技巧如果你想让这个齿轮故障诊断项目不只是交个作业而是能写进简历、面试时讲得出来有三个方向可以加码。第一个是加一个简单的 Web 界面用 Streamlit 把信号加载、特征计算、诊断结果串起来几十行代码就能做出可交互的演示面试时直接打开网页展示比干讲有说服力。第二个是引入阶次分析把时域信号按转速重采样到角度域这样转速波动时啮合频率仍然对齐是工业现场处理变速工况的标准做法。第三个是做一个对比实验表格把 SVM、随机森林、KNN、轻量 CNN 在同一份数据上的准确率和训练时间列出来用数据说明为什么选某个模型这比单纯说「我用了 SVM」有深度得多。模型准确率训练时间适用场景SVM (RBF)92%0.5s小样本、特征维度低随机森林89%1.2s特征维度高、需要特征重要性KNN85%0.1s快速基线、样本分布均匀轻量 CNN94%30s样本充足、端到端学习这张表里的数字是我在自己数据上跑出来的量级你的数据不同结果会变但趋势通常类似小样本下 SVM 性价比最高CNN 要样本够多才能拉开差距。做对比实验时记得固定随机种子否则每次跑结果都不一样没法写进报告。最后说个我自己的习惯每次跑完实验把特征矩阵、标签、模型参数、准确率一起存成一个带时间戳的文件夹命名格式exp_20250101_svm_rbf。这样过两周回头看能清楚知道当时用了什么参数、结果如何不用靠记忆去猜。大作业最怕的就是改了一版代码之后发现还不如上一版却找不回上一版的配置。这个习惯帮我省了无数次重跑的时间。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询