资讯详情

资讯详情

CWRU轴承数据集Python整理指南:从mat读取到特征校验的全流程避坑

简介凯斯西储大学CWRU轴承数据集是机械故障诊断领域广泛使用的经典数据集面向故障诊断研究人员、算法工程师及专业学生可用于滚动轴承正常、内圈、外圈、滚珠等状态的振动信号分析与故障识别。整套资源共172个文件压缩包230.77MB其中165个mat文件为不同工况下的原始振动信号3个Python脚本负责数据整理与特征分析另有txt说明文档mat文件名按故障位置与损伤尺寸命名便于按需筛选。已有超过2.4万人学习或下载属领域高热度资料。资料附完整数据包与整理好的Python程序能帮助用户完成从数据读取、预处理到特征提取的整个流程规避格式处理中的常见问题配套说明文档介绍数据来源、采集方法和故障类型划分可直接用于模型训练、算法验证与教学演示。1. 为什么一个 1990 年代的轴承数据集到今天还在被追着用凯斯西储大学(CWRU)轴承数据集是滚动轴承故障诊断方向流传最广、被论文引用最多的公开基准数据。它的价值不在数据量大而在于对照严谨同一套轴承在正常、内圈、外圈、滚动体四种状态下用不同故障直径、不同负载、不同采样率反复采集信号被组织成一批天然带标签的样本。对三类人尤其有用做故障诊断算法验证的研究生做预测性维护落地的工程师以及想快速评估自己特征提取方案是否靠谱的算法新人。但它的门槛也集中在一点mat 文件格式和命名看似整齐真正用 Python 整理时处处有细节直接 loadmat 往往会第一步就卡住。2. 先读懂数据包12k/48k 采样、驱动端和故障直径怎么对应2.1 文件编号与命名规律把 mat 文件和故障工况对上打开一个整理过的 CWRU 数据包一般先看到按采样率分的两个大目录12k Drive End 和 48k Drive End有些版本还会带 Fan End 子目录。每个目录里面是大量 .mat 文件文件名像105.mat、130.mat这样光看编号并不知道里面是什么状态。这里有第一个关键认知CWRU 的 mat 文件编号不是随便排的而是按「正常 → 内圈故障 → 滚动体故障 → 外圈故障」分段每段内部再按故障直径和负载递增。常见组织方式如下编号段故障位置说明97–99 区间正常Normal不同负载下的健康状态105–117 区间内圈 0.007 英寸故障直径较小118–130 区间滚动体 0.007 英寸滚珠损伤131–144 区间外圈 0.007 英寸外圈损伤169–185 区间内圈 0.014 英寸故障直径增大209–? 区间内圈 0.021 英寸更大故障不同渠道打包的编号段会有出入但规律一致。所以在写整理程序时不要硬编码具体文件名而是先读一遍数据包里的使用说明或清单文件把「编号段 → 故障类型 → 故障直径」映射表单独抽出来程序只依赖这份映射表。这也是我拿到任何数据包的第一步先建立主清单而不是急着写读取代码。2.2 四个标签维度负载、转速、故障直径与安装位置每个 mat 文件里的信号对应一组完整工况不能只记一个「内圈故障」标签。CWRU 数据集的每一条记录至少带四个维度信息负载0/1/2/3 hp、对应转速、故障直径0.007/0.014/0.021/0.028 英寸、故障位置内圈 / 滚动体 / 外圈 / 正常。负载和转速的对照在数据包使用说明里通常会给出负载近似转速0 hp1797 rpm1 hp1772 rpm2 hp1750 rpm3 hp1730 rpm这个映射必须跟着样本一起保存。为什么因为负载会影响振动幅度和特征频率。同一个内圈故障在 0 hp 和 3 hp 下的波形幅度、包络谱峰值位置都不同如果训练时把负载维度丢掉模型很容易把「负载差异」当成「故障差异」换到实际工况就翻车。外圈故障还有一个容易被忽略的维度加载位置。文件名或内部信息里会出现类似OR6、OR3、OR12的标注表示故障点相对承载区的钟表位置。这部分信息在整理时要么作为一个显式标签保留要么只取同一个位置的数据做训练最忌讳的是把不同位置外圈故障混在一起直接归成一类后面我会在避坑章专门讲。3. 用 Python 读 CWRU 的 mat 文件v7.3 回退与字段解析3.1 scipy 读不动时的 hdf5storage 回退写法CWRU 数据集年代跨度大早期版本的 mat 文件是 MATLAB v7 格式scipy.io.loadmat可以直接读但后来重新打包、或经 MATLAB R2014 之后保存过的文件会变成 v7.3 格式底层是 HDF5。直接用 scipy 读会抛NotImplementedError: Please use HDF reader for matlab v7.3 files。这是整理程序第一个要处理的分岔口。我一般的做法是写一个兼容函数优先 scipy捕获异常后再切到hdf5storage。不要一上来就用 hdf5storage因为它的返回结构和 scipy 不同统一处理反而多一层转换。import numpy as np from scipy.io import loadmat import hdf5storage def load_cwru_mat(path, wanted_vars(DE, FE, BA)): 读取 CWRU 的 mat 文件兼容 v7 与 v7.3 两种格式。 Args: path: mat 文件完整路径 wanted_vars: 需要提取的通道名CWRU 常见 DE/FE/BA Returns: data: dict键为通道名值为一维 float 数组 try: # 优先尝试 MATLAB v7 格式 raw loadmat(path, squeeze_meTrue) except NotImplementedError: # v7.3 格式内部是 HDF5用 hdf5storage 读取 raw hdf5storage.loadmat(path) data {} for var in wanted_vars: if var in raw: arr np.asarray(raw[var]) # 部分 hdf5storage 读出来是二维列向量拍平成一维 data[var] arr.ravel() return data # 使用示例 if __name__ __main__: signal load_cwru_mat(12k Drive End/105.mat) print(signal[DE].shape, signal[DE].dtype)这段代码的逻辑很简单先用squeeze_meTrue让 scipy 把单元素维度消掉如果失败说明是 v7.3交给 hdf5storage。最后统一做一次ravel()因为 HDF5 读出来的列向量 shape 是(N, 1)不拍平后面切片会很别扭。参数说明wanted_vars里DE是驱动端加速度计FE是风扇端BA是基座。对于绝大多数 12k 驱动端实验DE 是最常用的通道。注意 hdf5storage 返回的数组可能是只读的如果你后面要做原地修改先np.array(arr)复制一份。3.2 从字典到一维波形过滤系统键与长度核查读出来之后字典里除信号外还有__header__、__version__、__globals__这类 MATLAB 系统键直接遍历字典会把它们当成通道所以要用白名单方式取键不要用raw.keys()盲扫。另外一个值得做的检查是信号长度CWRU 每个 mat 文件的采样长度并不完全一致有的约 12 万点有的约 48 万点不同文件之间差很多。import os from pathlib import Path def inspect_folder(data_dir): 遍历目录下所有 mat 文件输出通道字段与信号长度概览。 for mat_path in sorted(Path(data_dir).glob(*.mat)): sig load_cwru_mat(str(mat_path)) if DE in sig: info f{mat_path.name}: DE{len(sig[DE])} if FE in sig: info f, FE{len(sig[FE])} print(info) inspect_folder(12k Drive End)这个概览函数是整理数据集的第一个体检工具。它回答两个问题第一这批 mat 文件的字段名是否统一第二信号长度分布是否合理。如果某个文件 DE 长度明显短于同类文件说明它可能是早期实验版本或采集异常直接标出来避免它混进训练集时造成样本数突增或不足。还有一个细节inspect_folder里的sorted是按文件名字符串排序的105.mat会排在97.mat前面但这对概览没有影响。真正要注意的是后续划分训练集和验证集时用文件名排序会让相邻文件高度相关这个坑留到第 5 章细说。4. 把波形切成可训练样本滑动窗口与三类标签映射4.1 滑动窗口参数长度、步长和重叠率的取舍拿到一维 DE 信号后下一步是把长序列切成短样本。CWRU 里单个 mat 文件信号长度在十万到几十万点量级直接整段喂给模型会丢失样本数量优势所以滑动窗口是标配做法。窗口长度取多少没有绝对标准常见做法是 1024 或 2048 点步长通常取窗口的一半即 50% 重叠。def sliding_windows(signal, win1024, step512): 滑动窗口切分一维信号。 Args: signal: 一维 float 数组 win: 窗口长度默认 1024 step: 步长默认 512即 50% 重叠 Returns: numpy 数组shape (样本数, win) samples [] n len(signal) if n win: return np.empty((0, win)) for start in range(0, n - win 1, step): samples.append(signal[start:start win]) return np.vstack(samples) segments sliding_windows(signal[DE], win1024, step512) print(f段数: {segments.shape[0]}, 每段长度: {segments.shape[1]})窗口和步长的选择直接影响样本数量和样本相关性。窗口越大频域分辨率越高但样本数越少重叠越多样本数越多但相邻样本相关性越高。50% 重叠是诊断领域最常见的折中一段 12 万点的信号大约能切成 230 多个样本样本量足够做 CNN 或普通分类器。参数说明step大于win时样本不重叠独立性强但数量骤减step接近win时相当于近全重叠样本几乎复制粘贴训练集和验证集一旦没分好测试准确率会虚高到假象。另外n - win 1这个边界是保证最后一个窗口不截断末尾不足一个窗口的尾巴直接丢弃不要做补零因为补零会让样本里混入非真实信号。4.2 从文件名到多标签编码故障、直径、负载一起生成切完样本后要打标签。不能只打「内圈 / 外圈」这种单标签至少要生成(故障类型, 故障直径, 负载)的三维标签因为后续做跨工况泛化实验时这三个维度都要能单独筛出来。常见做法是先维护一个文件映射表把 mat 文件名解析成结构化标签。# 文件映射表示例文件名 - (故障位置, 故障直径, 负载) # 实际使用时从使用说明里提取不要硬编码在程序里 FILE_MAP { 105.mat: (IR, 0.007, 0), 106.mat: (IR, 0.007, 1), 118.mat: (B, 0.007, 0), 131.mat: (OR6, 0.007, 0), 97.mat: (NORMAL, 0.0, 0), } def encode_label(meta): 把标签元组映射成整数编码。 Args: meta: (故障位置, 直径, 负载) 元组 Returns: dict: 包含整数类别、直径、负载三个字段 fault_code { NORMAL: 0, IR: 1, B: 2, OR6: 3, OR3: 4, OR12: 5, } return { class: fault_code[meta[0]], diameter: meta[1], load: meta[2], } label encode_label(FILE_MAP[105.mat]) print(label)FILE_MAP是整理程序的核心人工产物。拿到任何一批 CWRU 数据第一步都是把使用说明里的编号和工况抄成这张表而不是直接写死 if 分支。因为有的包把外圈OR6标成OR有的标成OR6你不看说明就会把不同位置混在一个类别里。猫腻藏在fault_code里这里把OR6、OR3、OR12设成不同类别是为了保留加载位置信息。如果你只是做基础分类可以不做区分但一旦做跨负载测试位置标签会显著影响外圈故障的识别率建议保留原始信息后处理时再决定是否合并。5. 避坑CWRU 数据集最常见 5 个翻车点与排查方法5.1 scipy.io.loadmat 报 NotImplementedError 或读出来是 bytes现象loadmat直接抛NotImplementedError或者读出来的字典值全是numpy.bytes_类型打印arr[0]出来是一串乱码。原因mat 文件是 v7.3 格式内部是 HDF5 容器scipy 不认而 bytes 乱码一般是squeeze_meFalse时把单元素数组包在了对象数组里或者混用了 hdf5storage 的对象引用。解决按第 3 章的方式写 try/except 回退到 hdf5storage读完后统一np.asarray(...).ravel()。切片后顺手打印dtype如果读到的是object类型不是float64说明解析层次不对检查是否漏了对 hdf5 引用调用.value或np.array。5.2 DE/FE/BA 通道取错模型「学」到了安装位置而不是故障现象训练集准确率很高但在测试集上表现不稳定或者模型对正常数据的误报率偏高。原因CWRU 每个 mat 文件同时包含驱动端、风扇端和基座信号位置不同振动传播路径不同。统一用signal[DE]取是对的但有些整理脚本为了省事把所有通道都塞进一个 feature 拼接测试时又只喂 DE训练和推理数据结构不一致。解决固定只取 DE 作为主通道或者固定取 DEFE 双通道并保持顺序一致。建立一条铁律特征顺序一旦定下来任何后续脚本都不允许改变把通道名写进样本文件名或元数据比如IR_0.007_load0_DE.npy避免几百个 npy 文件后面分不清。5.3 外圈故障的 3/6/12 位置信息被混成一类现象外圈故障识别准确率低尤其做跨负载实验时明显下降而且模型对位置特别敏感换一段数据就崩。原因外圈故障点在承载区不同位置时振动到传感器的路径不同波形形态差异大。很多整理程序直接把所有外圈 mat 文件归为OR一类等于把位置信息作为噪声丢掉了。解决保留位置子类即OR6、OR3、OR12作为独立类别如果业务上只关心「是否外圈故障」那就只取同一个位置的 mat 文件建数据集比如只用OR6其余位置作废也不混入测试。这样至少保证训练集内部是一致的。5.4 重叠滑动窗口跨文件划分造成数据泄漏现象按 9:1 随机切训练集和验证集验证准确率高达 99%换到别的工况数据却掉到 70%。原因滑动窗口 50% 重叠后相邻样本高度相似。一旦按样本而不是按「文件」划分同一个 mat 文件切出来的样本会同时出现在训练集和验证集模型等于提前看到了答案。解决划分数据时必须按文件粒度切分一个 mat 文件所有样本要么全在训练集要么全在验证集。代码上用GroupShuffleSplitgroup 参数传 mat 文件名而不是直接train_test_split(X)。如果按时间做 train/val/test也按时间顺序切文件不用随机函数。5.5 用全量数据做归一化测试时分布已经泄漏现象离线评估指标漂亮但部署到新数据后预测结果方差很大。原因归一化时用整个数据集的均值和标准差验证集信息被提前引入训练过程。这在统计上是典型的分布泄漏和 5.4 的样本泄漏并列是最容易被忽略的暗坑。解决归一化参数只在训练集上fit验证集和测试集只transform。归一化基准应该是「训练集的均值和标准差」而不是全量。每整理一批数据都要检查一遍是scaler.fit(X_train)还是scaler.fit(X_all)这一个fit放错位置后面所有评估都要推翻。6. 进阶不训练也能验证样本质量的包络谱双检查6.1 希尔伯特包络与特征频率核对整理完数据集先别急着丢给分类器做一个快速物理校验用希尔伯特变换计算包络谱看能不能在理论特征频率附近找到峰值。这一步能在不训练任何模型的情况下验证两个事——标签是否对上了样本以及切窗后信号是否还能保留故障特征。import numpy as np from scipy.signal import hilbert, spectrogram fs 12000 # 12k 采样率 rpm 1797 # 0 hp 负载转速 fr rpm / 60 # 转频 ≈ 29.95 Hz # SKF 6205 轴承参数滚动体数 9节径 39.04mm球径 7.94mm bpfi 5.415 * fr # 内圈故障特征频率 ≈ 162 Hz bpfo 3.585 * fr # 外圈故障特征频率 ≈ 107 Hz def envelope_spectrum(signal, fs, win2048): analytic hilbert(signal) env np.abs(analytic) freqs, times, spec spectrogram(env, fsfs, npersegwin, noverlapwin//2) mean_spec np.mean(spec, axis1) return freqs, mean_spec # 取一个内圈故障样本验证 freqs, spec envelope_spectrum(segments[0], fs) peak_idx np.argmax(spec[50:300]) np.searchsorted(freqs, 50) print(f包络谱峰: {freqs[peak_idx]:.2f} Hz) print(f理论 BPFI: {bpfi:.2f} Hz)这段代码的逻辑希尔伯特变换把实信号变成解析信号取模得到包络包络的频谱在故障频率处会有明显峰值。np.mean(spec, axis1)是把每帧频谱平均等效于 Welch 平均让峰值更稳定。参数说明nperseg2048对应 2048 点时域窗的 FFT 长度频率分辨率约 5.86 Hz足够分辨 107 和 162 Hz 这两个特征频率noverlap1024保持 50% 重叠和前面的样本切分策略一致。峰值在理论 BPFI 附近一个频率分辨率内说明该样本的内圈特征保留完好如果全局最高峰落在转频 30 Hz 且包络谱很平就要回头检查是不是把FE通道当成了DE。我自己的教训是最早整理 CWRU 时用全量数据求归一化参数样本还按随机方式划分测试准确率 99%以为大功告成。后来把模型拿到现场采集的轴承数据上准确率直接腰斩。回头才意识到泄漏问题。现在每做一批数据集都会强制跑一遍包络谱抽查和文件粒度划分检查这两步比任何模型调参都值钱。希望这一步检查也能帮你少走弯路把数据集整理这一步落到实处。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →