CWRU轴承数据预处理实战:1000采样长度构建4分类任务的3个关键步骤 CWRU轴承数据预处理实战1000采样长度构建4分类任务的3个关键步骤工业设备故障诊断领域中滚动轴承的健康状态监测一直是工程师们关注的焦点。凯斯西储大学CWRU轴承数据集作为该领域的基准数据为研究者提供了丰富的振动信号样本。本文将深入探讨如何通过三个关键步骤将原始振动信号转化为适合深度学习模型处理的标准化输入。1. 数据加载与初步探索任何数据分析项目的第一步都是理解数据本身。CWRU数据集采用Matlab格式存储包含驱动端DE、风扇端FE和基础BA三个位置的加速度计数据。让我们先看看如何正确加载这些数据import scipy.io as sio import numpy as np def load_matfile(filepath): 加载CWRU的.mat格式数据文件 mat_data sio.loadmat(filepath) de_data mat_data[DE].flatten() # 驱动端振动信号 fe_data mat_data[FE].flatten() # 风扇端振动信号 time_series mat_data[time].flatten() # 时间序列 rpm mat_data[RPM][0][0] # 转速信息 return de_data, fe_data, time_series, rpm数据加载后我们需要进行初步的可视化分析。振动信号通常表现出周期性特征通过观察波形可以初步判断轴承状态import matplotlib.pyplot as plt def plot_vibration_signal(signal, title): plt.figure(figsize(12, 4)) plt.plot(signal[:2000]) # 展示前2000个采样点 plt.title(title) plt.xlabel(采样点) plt.ylabel(振幅) plt.grid() plt.show() # 示例绘制正常状态和内圈故障信号的对比 normal_signal load_matfile(normal.mat)[0] fault_signal load_matfile(inner_race_fault.mat)[0] plot_vibration_signal(normal_signal, 正常轴承振动信号) plot_vibration_signal(fault_signal, 内圈故障振动信号)通过对比不同状态的信号波形我们可以观察到故障信号通常具有更明显的冲击特征。下表展示了CWRU数据集中四种典型状态的波形特征状态类型波形特征典型周期幅值范围正常平稳随机振动无固定周期±0.5g内圈故障周期性冲击100-150采样点±2.0g外圈故障周期性冲击80-120采样点±1.8g滚动体故障非严格周期冲击150-200采样点±1.5g提示在实际工程中建议先对数据进行标准化处理如Z-score标准化以避免不同传感器量纲带来的影响。2. 采样窗口选择与特征提取采样窗口长度的选择是数据预处理中最关键的决策之一。CWRU数据集中振动信号的典型周期约为100-200个采样点。选择1000作为窗口长度主要基于以下考虑覆盖完整故障周期确保窗口能包含至少5-10个完整的故障冲击周期计算效率平衡过长的窗口会增加计算负担过短则可能丢失关键特征模型输入要求适合大多数CNN网络的输入尺寸实现固定长度采样的Python代码如下def segment_signal(signal, window_size1000, step500): 将长信号分割为固定长度的样本段 segments [] for start in range(0, len(signal)-window_size, step): segment signal[start:startwindow_size] segments.append(segment) return np.array(segments) # 对四类信号进行采样 normal_segments segment_signal(normal_signal) inner_segments segment_signal(load_matfile(inner_race_fault.mat)[0]) outer_segments segment_signal(load_matfile(outer_race_fault.mat)[0]) ball_segments segment_signal(load_matfile(ball_fault.mat)[0])特征提取是提升模型性能的关键。除了原始振动信号外我们可以计算时域和频域特征from scipy import stats from scipy.fft import fft def extract_features(segment): 提取时域和频域特征 features {} # 时域特征 features[mean] np.mean(segment) features[std] np.std(segment) features[skewness] stats.skew(segment) features[kurtosis] stats.kurtosis(segment) # 频域特征 fft_vals np.abs(fft(segment))[:500] # 取前500个频点 features[freq_mean] np.mean(fft_vals) features[freq_std] np.std(fft_vals) features[dominant_freq] np.argmax(fft_vals) return features下表对比了不同故障类型的典型特征值范围特征指标正常范围内圈故障范围外圈故障范围滚动体故障范围峰度3-515-3010-208-15标准差0.1-0.30.5-1.20.4-1.00.3-0.8主频成分随机分布转速相关频率固定频率点多个谐波频率3. 标签构建与数据平衡四分类任务的标签构建需要考虑类别平衡问题。CWRU数据集中各类样本数量不均直接使用可能导致模型偏差。以下是处理方案def create_balanced_dataset(segments_list, labels_list, samples_per_class1400): 创建平衡的数据集 balanced_data [] balanced_labels [] for segments, label in zip(segments_list, labels_list): # 随机选择指定数量的样本 indices np.random.choice(len(segments), samples_per_class, replacelen(segments)samples_per_class) balanced_data.extend(segments[indices]) balanced_labels.extend([label]*samples_per_class) # 打乱顺序 shuffle_idx np.random.permutation(len(balanced_data)) return np.array(balanced_data)[shuffle_idx], np.array(balanced_labels)[shuffle_idx] # 定义标签 labels [0, 1, 2, 3] # 0:正常, 1:内圈故障, 2:外圈故障, 3:滚动体故障 segments_list [normal_segments, inner_segments, outer_segments, ball_segments] # 创建平衡数据集 X, y create_balanced_dataset(segments_list, labels)数据增强是解决样本不足的有效手段。对于振动信号我们可以采用以下增强方法def augment_signal(segment, noise_level0.05): 通过添加噪声和时移进行数据增强 # 添加高斯噪声 noise np.random.normal(0, noise_level*np.std(segment), len(segment)) augmented segment noise # 随机时移 shift np.random.randint(-50, 50) augmented np.roll(augmented, shift) return augmented # 示例对单个样本进行增强 original X[0] augmented augment_signal(original)注意增强后的数据应保持原始信号的物理特性避免过度扭曲导致模型学习到虚假特征。4. 数据保存与模型输入准备完成上述步骤后我们需要将处理好的数据保存为模型可直接读取的格式def save_processed_data(X, y, save_dirprocessed_data): 保存处理后的数据和标签 import os if not os.path.exists(save_dir): os.makedirs(save_dir) np.save(os.path.join(save_dir, X.npy), X) np.save(os.path.join(save_dir, y.npy), y) print(f数据已保存至{save_dir}目录) # 保存数据 save_processed_data(X, y)对于深度学习模型我们通常需要将数据分为训练集和测试集from sklearn.model_selection import train_test_split def create_train_test_split(X, y, test_size0.3): 创建训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_sizetest_size, stratifyy, random_state42) # 为CNN模型添加通道维度 X_train X_train[..., np.newaxis] X_test X_test[..., np.newaxis] return X_train, X_test, y_train, y_test # 创建数据集 X_train, X_test, y_train, y_test create_train_test_split(X, y)最终得到的数据规格应满足以下要求输入形状(样本数, 1000, 1)输出形状(样本数,)类别分布每个类别在训练集和测试集中比例相同通过这三个关键步骤我们成功将原始的振动信号转化为适合深度学习模型处理的结构化数据。在实际项目中这种标准化的预处理流程可以显著提高模型的训练效率和最终性能。