CWRU轴承数据集预处理实战:1000点采样与4类1400样本均衡化代码详解
CWRU轴承数据集预处理实战1000点采样与4类1400样本均衡化代码详解工业设备故障诊断领域中轴承作为旋转机械的核心部件其健康状态直接影响整个系统的运行安全。凯斯西储大学CWRU轴承数据集作为行业公认的基准数据源为研究者提供了丰富的故障振动信号样本。本文将深入解析该数据集预处理的关键技术环节重点解决两个核心问题如何从原始振动信号中提取有效片段1000点/段以及如何构建类别均衡的训练集每类1400样本。通过完整的Python代码实现和参数选择逻辑分析帮助初学者快速掌握工业级数据工程的标准化流程。1. CWRU数据集核心特性解析CWRU数据集通过电火花加工在轴承上制造了单点故障使用加速度计采集了驱动端DE、风扇端FE和基座BA三个位置的振动信号。原始数据以Matlab格式存储采样频率为12kHz包含四种健康状态正常状态Normal无缺陷轴承的振动信号内圈故障Inner Race Fault直径0.18/0.36/0.53mm的三种损伤外圈故障Outer Race Fault直径0.18/0.36/0.53mm的三种损伤滚动体故障Ball Fault直径0.18/0.36/0.53mm的三种损伤数据集的关键技术指标如下表所示参数数值说明采样频率12 kHz每秒采集12000个数据点负载条件0/1/2/3 HP四种电机负载工况故障直径0.18/0.36/0.53mm三种故障严重程度原始数据长度约480,000点每个.mat文件约40秒时长提示实际工程中建议优先使用驱动端DE数据因其信号特征最明显。基座BA数据受机械结构衰减影响较大通常作为辅助参考。2. 数据加载与可视化探索使用scipy.io加载Matlab格式数据是预处理的第一步。以下代码演示了如何提取关键振动信号并绘制时域波形import numpy as np import matplotlib.pyplot as plt from scipy.io import loadmat def load_cwru_file(filepath): 加载单个CWRU数据文件 data loadmat(filepath) de_signal data[DE].ravel() # 驱动端振动信号 time np.arange(len(de_signal)) / 12000 # 构造时间轴(采样率12kHz) return de_signal, time # 示例加载正常状态数据 normal_signal, time load_cwru_file(Normal_0.mat) # 绘制前1000点波形 plt.figure(figsize(10,4)) plt.plot(time[:1000], normal_signal[:1000]) plt.xlabel(Time (s)) plt.ylabel(Amplitude (g)) plt.title(Normal Bearing Time Domain Signal (First 1000 points)) plt.grid() plt.show()通过可视化可观察到振动信号的周期性特征。正常轴承信号呈现较为规则的高频振荡而故障信号会出现明显的冲击成分。下图对比展示了正常与内圈故障信号的典型特征差异关键观察点故障信号的冲击间隔与轴承几何参数相关信号幅值会随故障严重程度增加而增大不同故障类型的冲击波形具有独特模式3. 分段采样策略实现原始振动信号长达数十万点直接输入模型会导致计算量剧增。我们采用固定长度滑动窗口进行分段采样具体实现需考虑以下参数窗口长度1000点约0.083秒时长滑动步长500点50%重叠归一化方式逐段Z-score标准化def segment_signal(signal, window_size1000, step500): 滑动窗口分段采样 segments [] num_segments (len(signal) - window_size) // step 1 for i in range(num_segments): start i * step end start window_size segment signal[start:end] # 标准化处理 segment (segment - np.mean(segment)) / np.std(segment) segments.append(segment) return np.array(segments) # 对四类数据分别采样 normal_segments segment_signal(normal_signal) inner_segments segment_signal(load_cwru_file(InnerRace_0.18.mat)[0]) outer_segments segment_signal(load_cwru_file(OuterRace_0.18.mat)[0]) ball_segments segment_signal(load_cwru_file(Ball_0.18.mat)[0])采样参数选择依据1000点窗口覆盖至少5个轴承旋转周期根据1200RPM计算50%重叠平衡数据量增加与样本相关性Z-score标准化消除不同工况下的幅值差异4. 类别均衡化处理技术原始数据中各类样本数量不均衡正常样本1696个故障类约1450个需进行均衡化处理。我们采用随机欠采样策略从每类中抽取1400个样本def balance_samples(*class_arrays, samples_per_class1400): 均衡化多类样本数量 balanced_arrays [] for arr in class_arrays: if len(arr) samples_per_class: idx np.random.choice(len(arr), samples_per_class, replaceFalse) balanced arr[idx] else: # 若样本不足则重复采样 idx np.random.choice(len(arr), samples_per_class, replaceTrue) balanced arr[idx] balanced_arrays.append(balanced) return np.concatenate(balanced_arrays), np.concatenate([ np.full(samples_per_class, i) for i in range(len(class_arrays)) ]) # 构造均衡数据集 X, y balance_samples( normal_segments, inner_segments, outer_segments, ball_segments ) print(f最终数据集形状{X.shape}) # (5600, 1000) print(类别分布, np.bincount(y)) # [1400 1400 1400 1400]注意对于样本量不足的类别如某些严重故障可采用数据增强技术添加噪声、时移等替代简单的重复采样。5. 完整预处理流程封装将上述步骤整合为可复用的预处理管道并添加数据保存功能import os from glob import glob def cwru_preprocessing(data_dir, output_dir, window_size1000, step500, samples_per_class1400): CWRU数据集完整预处理流程 # 创建输出目录 os.makedirs(output_dir, exist_okTrue) # 按类别加载数据 class_files { 0: glob(os.path.join(data_dir, Normal_*.mat)), 1: glob(os.path.join(data_dir, InnerRace_*.mat)), 2: glob(os.path.join(data_dir, OuterRace_*.mat)), 3: glob(os.path.join(data_dir, Ball_*.mat)) } # 分段采样所有数据 class_segments [] for label, files in class_files.items(): print(fProcessing class {label} with {len(files)} files...) all_segments [] for file in files: signal, _ load_cwru_file(file) segments segment_signal(signal, window_size, step) all_segments.append(segments) class_segments.append(np.concatenate(all_segments)) # 均衡化处理 X, y balance_samples(*class_segments, samples_per_classsamples_per_class) # 保存为Numpy格式 np.save(os.path.join(output_dir, train_data.npy), X) np.save(os.path.join(output_dir, labels.npy), y) print(f数据已保存至 {output_dir}) # 示例调用 cwru_preprocessing(原始数据目录, 预处理输出)该脚本会自动完成以下工作扫描指定目录下的.mat文件并按类别分组对每个文件进行滑动窗口分段采样统一各类样本数量为1400个保存处理后的数据和标签到指定目录6. 预处理结果验证为确保预处理质量我们需要验证数据分布是否合理故障特征是否保留完整模型输入格式是否正确特征保留验证计算各类信号的FFT频谱并对比from scipy.fft import fft def plot_class_spectrum(X, y, class_id, samples5): 绘制指定类别的频谱特征 class_data X[y class_id] plt.figure(figsize(12,6)) for i in range(samples): signal class_data[i] spectrum np.abs(fft(signal)[:500]) # 取前500个频点 plt.subplot(2, 3, i1) plt.plot(spectrum) plt.title(fSample {i1}) plt.xlabel(Frequency) plt.ylabel(Magnitude) plt.suptitle(fFrequency Spectrum - Class {class_id}) plt.tight_layout() plt.show() # 验证四类数据的频谱特征 for class_id in range(4): plot_class_spectrum(X, y, class_id)模型输入验证检查数据形状和类型print(输入数据形状:, X.shape) # 应为(5600, 1000) print(标签形状:, y.shape) # 应为(5600,) print(数据类型:, X.dtype) # 应为float32/float64 print(数值范围:, np.min(X), np.max(X)) # 标准化后应在-3~3之间7. 高级预处理技巧针对实际工程需求可进一步优化预处理流程时频特征融合结合短时傅里叶变换提取时频图from librosa import stft def create_time_freq_features(signal, n_fft64): 生成时频特征矩阵 D np.abs(stft(signal, n_fftn_fft)) return D.reshape(-1) # 展平为特征向量 # 示例转换第一个样本 tf_feature create_time_freq_features(X[0]) print(时频特征维度:, tf_feature.shape)数据增强技术提升小样本类别的多样性def augment_signal(signal, noise_level0.05): 添加高斯噪声增强 noise np.random.normal(0, noise_level, len(signal)) return signal noise # 示例增强效果对比 original X[0] augmented augment_signal(original) plt.figure(figsize(10,4)) plt.subplot(1,2,1) plt.plot(original) plt.title(Original) plt.subplot(1,2,2) plt.plot(augmented) plt.title(Augmented) plt.show()关键参数调优建议参数推荐值调整方向窗口长度500-2000点根据故障特征周期调整滑动步长窗口长度的30-70%平衡数据量与计算成本样本数量1000-2000/类避免过拟合与欠采样实际项目中这些参数需要结合具体设备型号和故障特征进行优化。例如对于低速轴承600RPM需要增大窗口长度以捕获完整冲击波形。