☰
CWRU轴承故障数据集全解:特征频率计算与包络谱分析工程实践
2026/10/10 7:10:49 网站建设 项目流程

简介:这是一份面向机械故障诊断研究者和工程师的中文版CWRU轴承数据说明文档。文档以美国凯斯西储大学轴承实验为基础,逐一解读驱动端加速度、风扇端加速度、基座加速度、时间序列和转速等变量的含义,并介绍实验台的组成结构、SKF 6205与SKF 6203轴承的几何尺寸、故障特征频率,以及电火花加工单点损伤的直径等级和损伤位置(3点、6点、12点)的设置。说明中同时区分了12kHz与48kHz两档采样频率的适用场景,并对Matlab数据文件中各变量的命名规则作了逐项解释,方便读者在后续分析中快速定位数据字段。文档还列出了驱动端轴承与风扇端轴承对应的故障频率倍频系数,可用于识别振动信号中的周期性冲击。资源包仅包含1个DOC文档,压缩后约473KB,整体轻量清晰。目前已有673人学习,适合机械工程、工业自动化、状态监测与故障诊断领域的入门学习者参考,也可作为使用CWRU公共数据集进行特征提取与算法验证时的快速查阅手册。

1. 轴承故障诊断绕不开的参考数据集:这份中文文档到底讲清楚了什么

做滚动轴承故障诊断的人,大概率都下载过那份以.mat和.dat混存的开放轴承数据集。数据本身不难找,难的是读懂它——英文变量命名、故障编码规则、转速档位对应关系,这些信息散落在原始英文说明里,翻译版本又往往只翻了开头几段。这份中文版CWRU数据说明文档,把实验台架构成、两种轴承的几何参数与故障频率系数、单点损伤尺寸设置、文件命名规则和实测包络谱特征逐条做了标注,相当于把原版英文说明和读数据时最需要的换算公式合到了一起。如果你正在做故障诊断课题、写状态监测算法,或者刚接触轴承数据不知道怎么下手,这份文档能帮你省掉至少一周的摸索时间。它解决的问题不是「数据是什么」,而是「数据该怎么读、特征该怎么算、哪些坑不能踩」。

2. 实验台架与数据采集体系:先把源头参数吃透再谈分析

2.1 台架布局:电机-扭矩-负载链路与传感器布点

看这份文档首先要理解实验台架的物理构成。整个实验台由一台2马力(1.5 kW)电动机驱动,电机输出轴通过扭矩传感器/译码器连接功率测试计,电子控制器负责调节负载工况。待测轴承支撑电动机转轴,驱动端安装的是SKF 6205深沟球轴承,风扇端安装的是SKF 6203深沟球轴承。两个加速度传感器分别布置在驱动端和风扇端轴承座正上方,用磁力基座固定,用于采集故障轴承的振动加速度信号。

这个布局决定了传感器测点语义:DE(驱动端加速度数据)反映的是承载更大、故障更典型的驱动端轴承状态;FE(风扇端加速度数据)捕捉的是轻载端轴承的振动响应;BA(基座加速度数据)则是整个电机机架上的振动背景。需要注意的是,不是所有数据文件都包含BA变量,这一点在后面读数据时会直接影响批处理逻辑。

负载加载路径是电机→扭矩传感器→功率测试计,通过电子控制器在0、1、2、3马力四档之间切换。对应关系为:0马力≈1797 r/min,1马力≈1772 r/min,2马力≈1750 r/min,3马力≈1730 r/min。这四个转速档位在后面计算故障特征频率时要和RPM变量配合使用,不能只看文件名里的档位编号。

2.2 轴承规格与几何参数:6205和6203的关键差异

文档列出了两种轴承的完整几何参数,这些参数是计算故障频率的基础。驱动端6205轴承为深沟球轴承,滚动体数量9个;风扇端6203同为深沟球轴承,滚动体数量8个。

参数6205驱动端轴承6203风扇端轴承
滚动体数量98
内圈直径25.0012 mm17.0002 mm
外圈直径51.9989 mm39.9999 mm
厚度15.0012 mm11.9990 mm
滚动体直径7.94004 mm6.7462 mm
节径39.0398 mm28.4988 mm

滚动体数量和节径的差异直接导致两种轴承的故障频率系数不同。文档给出的特征频率倍数是:6205内圈5.4152、外圈3.5848、保持架0.39828、滚动体4.7135;6203内圈4.9469、外圈3.0530、保持架0.3817、滚动体3.9874。这些系数是转频的倍数,实际故障频率等于系数乘以当前转速下的转频值。后面第4章会展开计算过程。

有一点值得注意:文档里同时出现了两种轴承的俄文描述,其中提到滚动体直径为8.181818 mm,与英文描述里的7.94004 mm不一致。以英文描述为准,因为采样数据、故障频率系数和后续诊断结论都建立在英文参数体系上。俄语字段只是原文档的翻译残留,不要被它带偏。

2.3 采样参数:12 kHz 与 48 kHz 选哪个

数据采集使用16通道记录仪,风扇端轴承故障数据统一为12 kHz采样频率,驱动端轴承故障数据包含12 kHz和48 kHz两套。选哪一套取决于你要分析的故障类型和频率范围:

  • 12 kHz采样:连续采样时长更长,单文件数据点数更多,适合做包络谱、时域统计特征等常规分析。采样频率12 kHz对应奈奎斯特频率6 kHz,而轴承故障特征频率通常在1 kHz以内,完全够用。
  • 48 kHz采样:频率分辨率更高,适合观察故障特征频率的高次谐波、边频带结构。但缺点是文件体量更大,且没有对应的正常基座数据集可作为对照组,使用时需要和12 kHz正常数据混合分析。

实际项目里,我一般先用12 kHz数据做整体特征筛选,确定故障类型后再用48 kHz数据验证特征频率和高频共振解调效果。两种采样频率下的文件编号体系是相互独立的,批量处理时要分开建索引,避免加载冲突。

2.4 故障注入方式:电火花单点损伤的尺寸与位置语义

故障轴承用电火花加工制造单点损伤,损伤直径分五档:0.1778 mm、0.3556 mm、0.5334 mm、0.7112 mm和1.016 mm,对应英制7 mils、14 mils、21 mils、28 mils和40 mils。SKF轴承覆盖前三档小损伤,NTN轴承承载后两档大损伤。这种尺寸分档与轴承厂商的对应关系有实际意义:小损伤接近早期微弱故障,大损伤对应严重剥落,分析难度和特征明显度完全不同。

外圈损伤点的位置设置是这份数据集最有特色的地方。由于外圈固定,损伤点相对承载区的方位直接影响振动响应,文档将损伤点分别设在3点钟、6点钟、12点钟位置。其中6点钟正对承载区中心(负载区中心),3点钟与承载区成90度正交,12点钟与承载区相对。后面做外圈故障分析时,不同位置的包络幅值和倍频结构差异非常显著,如果只取一个位置的数据做训练,模型的泛化能力会受到明显限制。

3. 文件命名与变量字段:读懂编号规则就能少走一半弯路

3.1 负载工况与转速档位:0-3 HP 对应转速

先明确四档转速与负载的对应关系,这是读文件名的前提。文档记录的电机转速为:0马力时1797 r/min、1马力时1772 r/min、2马力时1750 r/min、3马力时1730 r/min。注意文件名里下划线后的数字表示的正是负载档位:_0对应0马力,_1对应1马力,_2对应2马力,_3对应3马力。

但这里有一个隐藏细节:文档在做故障频率验算时,内圈故障用了1797 r/min计算(5.4152 × 1797/60 = 162.19 Hz),滚动体故障却用了1796 r/min(4.7135 × 1796/60 = 141.09 Hz),外圈故障也用了1796 r/min(3.5848 × 1796/60 = 107.30 Hz)。同一负载档位下转速值出现微小出入,原因是扭矩传感器每次实测记录的转速不完全一致。所以实际分析应该以mat文件里的RPM变量为准,不能教条地套用1797或1796。

3.2 文件名结构:故障类型-尺寸-位置-负载的编码规则

先把命名规则拆开看。

故障类型前缀:IR代表内圈故障,B代表滚动体(Ball)故障,OR代表外圈故障。紧跟其后的数字是损伤直径档位:007表示7 mils(0.1778 mm),014表示14 mils(0.3556 mm),021表示21 mils(0.5334 mm),028表示28 mils(0.7112 mm)。正常基座数据没有故障类型前缀,直接是Normal_0、Normal_1、Normal_2、Normal_3,对应四个负载档。

外圈文件多一个位置标识,格式为OR007@6_0、OR014@3_1、OR021@12_2,@后面的数字代表时钟位置。@6表示损伤点在6点钟方向(正对承载区),@3表示3点钟方向(与承载区正交),@12表示12点钟方向(与承载区相对)。

下划线后的数字才是负载档位:0-3。文件的实际编号则对应到具体的.mat或.dat文件,例如IR007_0对应105.mat,OR007@6_0对应130.dat。不同故障类型和尺寸组合对应的文件编号没有规律性递增,必须按文档里的映射表逐个建立索引。

3.3 变量字段:DE、FE、BA、time、RPM 的实际含义

每个mat文件加载后,变量名规则很有识别度:

  • X105_DE_time:驱动端加速度时间序列
  • X105_FE_time:风扇端加速度时间序列
  • X105_BA_time:基座加速度时间序列
  • X105RPM:实测电机转速

前缀X加上文件编号,然后再接字段名。前面提到的105.mat,加载后变量名就是X105_DE_time、X105_FE_time、X105_BA_time和X105RPM。注意不是所有文件都带BA字段,例如106.dat对应的数据就只包含DE和FE。而且有个别文件在文档中被标注「多X217」,意味着文件内容与命名存在错位,使用时需要额外核对数据长度和变量完整性。

DE和FE的时域波形特征差异明显:驱动端轴承承载更大,同一故障类型下DE的冲击幅值通常高于FE;风扇端轴承更轻载,同样的单点损伤产生的冲击特征要弱一些。BA基座数据作为全局振动响应,在故障分析中常用来和环境噪声、安装共振做区分。

3.4 用 scipy 批量读取:一套可直接改写的加载模板

读mat格式文件,Python环境下最常用的是scipy.io.loadmat。这里给出一套能跑的批处理模板,把文件编号、故障标签、负载档位和实测转速一次性组织成结构化字段。

import scipy.io as sio import numpy as np import pandas as pd def load_cwru_mat(file_id, base_path): """ 加载单个CWRU格式的mat文件 file_id: 文件编号,如105 base_path: 数据文件所在目录 """ path = f"{base_path}/{file_id}.mat" raw = sio.loadmat(path) # 变量名带文件编号前缀,需要动态拼接 prefix = f"X{file_id}" de = raw[f"{prefix}_DE_time"].flatten() fe = raw[f"{prefix}_FE_time"].flatten() rpm = raw[f"{prefix}RPM"].flatten()[0] # BA字段不是所有文件都有,用get方法兜底 ba_key = f"{prefix}_BA_time" ba = raw.get(ba_key, np.array([])).flatten() return {"file_id": file_id, "DE": de, "FE": fe, "BA": ba, "RPM": rpm} def build_label_from_name(file_id, fault_type, diameter, position, load): return { "file_id": file_id, "fault_type": fault_type, # 'IR'/'B'/'OR'/'Normal' "diameter_mil": diameter, # 7/14/21/28 "position": position, # '6'/'3'/'12'/None "load": load # 0/1/2/3 }

这段代码有两个关键设计。动态拼接变量名前缀是必须的,因为原始文件里的变量名都带X前缀和文件编号,写死变量名换一个文件就会KeyError。BA变量用get方法兜底,是因为部分文件确实没有基座数据,硬取会直接报错。RPM用flatten()[0]转成标量,否则后续计算特征频率时会带着一层数组维度。

# 批量加载示例 file_list = [ {"file_id": 105, "fault_type": "IR", "diameter": 7, "position": None, "load": 0}, {"file_id": 118, "fault_type": "B", "diameter": 7, "position": None, "load": 0}, {"file_id": 130, "fault_type": "OR", "diameter": 7, "position": "6", "load": 0}, {"file_id": 100, "fault_type": "Normal", "diameter": 0, "position": None, "load": 3}, ] records = [] for item in file_list: data = load_cwru_mat(item["file_id"], "./cwru_data") data.update(item) records.append(data) df = pd.DataFrame(records) print(df[["file_id", "fault_type", "diameter", "position", "load", "RPM"]])

批量加载后,每条记录的RPM变量会被统一读取出来,故障类型、损伤直径、位置、负载都被结构化存储。后面做特征频率计算、包络谱峰值比对时,直接从这个DataFrame里取对应字段,不用再回到文件名里解析。

4. 故障频率计算:用轴承几何参数推导特征频率并验算

4.1 故障特征频率公式:BPFO、BPFI、BSF、FTF

轴承故障诊断的核心是特征频率计算。单点损伤在滚动体旋转过程中周期性撞击缺陷边缘,产生冲击脉冲,冲击频率由轴承几何参数和转频决定。四个基本特征频率对应四种故障部位:

  • 外圈故障特征频率:BPFO = (n/2) × f_r × (1 - (d/D) × cosα)
  • 内圈故障特征频率:BPFI = (n/2) × f_r × (1 + (d/D) × cosα)
  • 滚动体故障特征频率:BSF = (D/d) × f_r × (1 - (d/D × cosα)²)
  • 保持架故障特征频率:FTF = (f_r/2) × (1 - (d/D) × cosα)

其中n为滚动体数量,d为滚动体直径,D为节径,α为接触角,f_r为转频。深沟球轴承接触角近似为0,cosα≈1,公式可以简化为文档给出的倍数系数形式。这些倍数是几何参数固定后的常量,不随转速变化。文档里直接给出的5.4152、3.5848、0.39828、4.7135等数值,本质就是把6205轴承的几何参数代入上式后得到的倍数。

4.2 按文档系数验算:6205与6203的完整计算

实际计算分两步走:先把电机转速换算成转频,再用系数乘以转频得到故障频率。这里用文档标注的验算数据做对照:

def fault_frequency(freq_coeff, rpm): """ 由故障频率系数和实测转速计算故障特征频率 freq_coeff: 内圈/外圈/保持架/滚动体对应的倍数系数 rpm: 实测转速 """ rot_freq = rpm / 60.0 # 转频,单位Hz return freq_coeff * rot_freq, rot_freq # 6205驱动端轴承,0马力,实测转速1797 rpm coeff_6205 = {"IR": 5.4152, "OR": 3.5848, "FTF": 0.39828, "BSF": 4.7135} for part, coeff in coeff_6205.items(): ff, rf = fault_frequency(coeff, 1797) print(f"6205 {part}: 故障频率={ff:.2f} Hz, 转频={rf:.2f} Hz") # 6203风扇端轴承,0马力,实测转速1797 rpm coeff_6203 = {"IR": 4.9469, "OR": 3.0530, "FTF": 0.3817, "BSF": 3.9874} for part, coeff in coeff_6203.items(): ff, rf = fault_frequency(coeff, 1797) print(f"6203 {part}: 故障频率={ff:.2f} Hz, 转频={rf:.2f} Hz")

这段代码把转速除以60得到转频,再乘以对应系数。运行结果中,6205内圈故障频率162.19 Hz,与文档中IR007_0数据实测包络谱峰值156 Hz基本吻合,偏差来自实际转速波动和频谱分辨率限制;6205滚动体故障频率141.09 Hz,与118.mat文件包络峰值的对应关系可以直接验证;6203外圈故障频率91.44 Hz,文档中实测包络峰值出现在相同频段。

4.3 包络谱验证:把计算结果和实测峰值对齐

需要说明的是,遗憾我无法直接读取你提供的原始信号文件来做实时计算验证,如果你能告诉我文件编号(比如105.mat或130.dat),我可以给出更有针对性的结果——这里用文档中记录的实测包络谱观察做说明。文档记录的一个关键现象是:外圈7 mils故障、6点钟位置,包络谱最大峰值出现在故障频率处,且存在清晰的倍频序列;同一尺寸故障在3点钟位置,峰值幅度与6点钟相当,但倍频基本消失;12点钟位置包络峰值明显变小。这个现象说明外圈故障的倍频结构与损伤位置强相关,原因在于损伤点相对承载区的方位改变了冲击激励的幅值和调制方式。

实际验证时,流程是:对DE信号做带通滤波,取共振频段;再用希尔伯特变换提取包络信号;最后对包络做FFT得到包络谱,在包络谱上寻找对应特征频率处的谱峰。文档中还记录了一个特殊现象:旋转频率的三倍频恰好落在某些故障频率上,比如某个工况下转频29 Hz的三倍频87 Hz接近外圈故障频率88 Hz。这种频率重合会干扰诊断判断,依靠单一频点峰值容易误判故障位置,需要用边频带结构或倍频序列做交叉验证。高频谐波的衰减情况、边频间隔是否等于转频,这些特征比单点峰值更有判别力。

5. 避坑指南:数据集使用中的高频翻车点

5.1 外圈0.014英寸故障数据的包络谱异常现象

现象:文档中明确标注OR014@6系列外圈14 mils故障数据的包络谱效果「非常不好,不能用」。多个负载档位下的实测结果都出现特征频率峰值不明显、谱线杂乱的问题。

原因:14 mils(0.3556 mm)处于中间损伤档位,冲击能量不够集中,同时外圈损伤位置在承载区内的激励方向与传感器测点方向不在最优传递路径上,导致包络谱被噪声淹没。文档中还提到21 mils和7 mils外圈故障数据反而特征明显,说明问题不在数据质量,而在这一档尺寸和测点方向的组合恰好落在信号可辨识度的盲区。

解决:分析外圈故障时优先选用7 mils和21 mils数据,特别是21 mils在6点钟位置的峰值特征最稳定。14 mils外圈数据如果一定要用,需要先做共振频带增强或小波去噪预处理,否则直接提取包络谱特征训练模型会导致误分类率明显上升。

5.2 转速取值不一致

现象:同一负载档位下,文件名里的档位编号对应四种转速,但文档验算内圈故障时用1797 r/min,验算滚动体和外圈故障时用1796 r/min。如果全部用1797计算,滚动体故障频率会偏差0.08 Hz,虽然数值差异不大,但和谱线峰值对齐时会产生肉眼可辨的偏移。

原因:扭矩传感器/译码器每次实测的转速值不同,文档作者分别取用了不同数据文件对应的实测转速。RPM变量才是每次测试的真实记录值。

解决:不要用转速档位查表换算,直接从mat文件里提取RPM变量做频率计算。批量处理时把RPM一起读入结构化字段,计算时逐文件代入,能避免频率对齐误差。

5.3 外圈故障位置对包络幅值和倍频结构的影响

现象:外圈损伤在3点钟、6点钟、12点钟三个位置,包络谱特征差异非常大。6点钟位置(正对承载区)峰值幅度最高、倍频清晰;3点钟位置峰值幅度与6点钟相当但倍频消失;12点钟位置峰值幅度显著变小。

原因:损伤点相对承载区方位决定了滚动体经过缺陷时的冲击能量强弱。正对承载区时滚动体受载最大,冲击也最强;12点钟位置处于卸载区,滚动体基本不受力,冲击能量微弱。3点钟处于过渡区,冲击存在但激励不连续,倍频结构不完整。

解决:构建训练集时不要把三个位置的数据混为一类,建议按位置拆分子类,或者单独用6点钟位置的数据训练、用3点和12点做验证。做模型泛化测试时也应当保留位置维度,避免在单一位置上学到的特征掩盖真实故障辨别能力。

5.4 部分文件标注「不可用」或「无法下载」

现象:文档表格里多处标注「* = Data not available」和「不能下载」。例如OR014@6_1、OR014@6_2系列数据缺失,风扇端OR014@3系列部分文件同样缺失。部分文件编号下有「多X217」的记录,说明文件内容与名称对应关系存疑。

原因:原始数据采集过程中部分工况未完成记录,或文件上传不完整。数据集的可用样本数量并非表格中所有组合的总和。

解决:使用前先对照文档表格标注,建立一份「可用文件清单」,只保留标注可用的文件。批量训练时把这部分缺失和异常文件从索引里剔除,避免加载空文件导致程序中断。

5.5 变量名前缀与文件格式混用陷阱

现象:mat文件里的变量名带X前缀和文件编号(X105_DE_time),不是简单的大写DE。部分数据文件是.dat格式,同样存在变量名带前缀的情况。个别文件只包含DE和FE字段,没有BA基座数据。

原因:数据记录仪导出的原始格式就带编号前缀,后续做样本整理时保留了这一命名习惯。不同批次实验的字段完整性不一致。

解决:读取代码里用动态变量名拼接,不要写死。按文件编号自动生成变量名字符串,再传入loadmat的变量字典。对BA字段用get方法兜底读取,文件缺失时置为空数组。读取后统一检查字段数量和数组长度,发现异常立即排查该文件编号。

6. 进阶:批量做包络谱并自动比对故障频率的验证技巧

6.1 包络谱分析完整流程

包络谱分析的目的是把高频振动冲击从宽频信号里解调出来,获得周期性冲击频率。流程分为带通滤波、希尔伯特解调、FFT频谱估计三步。带通滤波的频带选择是关键:通常选2 kHz到6 kHz之间的共振频段(以12 kHz采样数据为例),避开转频和齿轮啮合的低频干扰,同时保留轴承冲击激发的结构共振响应。

from scipy.signal import hilbert, butter, filtfilt from scipy.fft import fft, fftfreq import numpy as np def envelope_spectrum(signal, fs, low=2000, high=6000): """ 包络谱分析核心函数 signal: 加速度时域信号 fs: 采样频率 low/high: 带通滤波截止频率 """ order = 4 b, a = butter(order, [low / (fs/2), high / (fs/2)], btype="band") filtered = filtfilt(b, a, signal) analytic = hilbert(filtered) envelope = np.abs(analytic) spec = np.abs(fft(envelope)) freqs = fftfreq(len(envelope), 1/fs) return freqs[:len(freqs)//2], spec[:len(spec)//2] def find_peaks(freqs, spec, top_n=5, min_height_ratio=0.1): """简易峰值查找:谱峰幅度超过频谱包络均值的10倍""" threshold = np.mean(spec) * min_height_ratio * 10 indices = np.where((spec[1:-1] > spec[:-2]) & (spec[1:-1] > spec[2:]) & (spec[1:-1] > threshold))[0] + 1 peak_indices = indices[np.argsort(spec[indices])[-top_n:]] return sorted(freqs[peak_indices])

带通滤波用四阶巴特沃斯滤波器,filtfilt做零相位滤波避免相位畸变。希尔伯特变换提取包络,FFT得到包络谱。峰值查找采用局部极大值加高度阈值双重筛选,返回前几个最大的谱峰频率。

6.2 批量验证与理论频率自动比对

theoretical = {"IR": 162.19, "OR": 107.30, "B": 141.09} for _, row in df.iterrows(): if row["fault_type"] == "Normal": continue freqs, spec = envelope_spectrum(row["DE"], 12000) peaks = find_peaks(freqs, spec) expected = theoretical[row["fault_type"]] diff = np.min([abs(p - expected) for p in peaks]) print(f"file_{row['file_id']} {row['fault_type']}: " f"理论频率={expected:.2f} Hz, 最近谱峰偏差={diff:.2f} Hz")

这段代码逐个文件计算包络谱,自动提取前五个谱峰,并与当前文件故障类型对应的理论频率求最小偏差。偏差在2 Hz以内时特征频率验证通过;偏差过大则大概率是转速取值不对或该文件本身存在标注问题。

做诊断分析时我会把偏差超过2 Hz的文件单独列出来,逐个回到原始数据检查。多数情况是RPM变量里的实测转速和表格里的标称转速不一致导致的,少数情况是数据文件本身不可用——这种情况直接放弃该文件,绝不硬凑进训练集。从那以后,我每次跑新一批数据前都强制走一遍批量加载、转速提权、特征频率验算的流程,先把理论频率算清楚再谈模型训练。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询