///Meblog///

About Meblog

cwru数据集清洗与处理

📅 2026-1-27

最近开始做大创的项目,导师给我们定了一个故障检测方向的课题,没什么技术含量,也就是了解一下做科研大概是什么样子吧。

关于故障检测的传感数据,正在学习如何清洗和切分CWRU的数据集

直接下载下来的数据和实际生产中接收到的机械传感数据并没有进行加工和处理

如果直接拿来用,往往会遇到维度对不上、样本太少或者幅值忽大忽小的问题。

技术路线

编写这个程序时,大致是这样一条技术路线:

如何实现功能

搞定不统一的文件键名

处理 CWRU 数据集时,首先会碰到一个很尴尬的情况:变量名太不统一了。

通过利用 Python 的列表推导式来实现“模糊匹配”,只要键名里包含 DE_time(驱动端时间序列)这个关键词,就把它抓出来。

import scipy.io as sio

def load_and_normalize(file_path):
    data_dict = sio.loadmat(file_path)
    
    # 动态查找键名:只要键名中包含 'DE_time',即被视为目标数据
    # [0] 表示取匹配到的第一个键,这样就避开了前缀不一致的问题
    de_key = [k for k in data_dict.keys() if 'DE_time' in k][0]
    
    # 提取数据并展平
    raw_signal = data_dict[de_key].flatten()
   

消除不同工况下的幅值差异

在不同工况下,传感器采集到的信号幅值可能差异很大,这会影响模型的训练效果。

因此通过对数据的归一化可以减少模型的训练难度。

使用 Z-Score 标准化(零均值归一化)。

# 公式:(x - μ) / σ

通过将所有信号都转换成均值为 0、标准差为 1 的分布,让模型专注于信号的形状而不是高度。


normalized_signal = (raw_signal - np.mean(raw_signal)) / np.std(raw_signal)
return normalized_signal

划定单个样本的数据长度

我们需要定义一个“视窗”(Window),就像拿一个框去套信号,框里是多少,样本就是多长。

WINDOW_SIZE = 1024 # 模型看到的单一特定样本长度

用重叠采样来“增广”数据

通过设置一个小于窗口大小的步长(Stride)实现样本的重叠。

重叠采样,不仅让样本量直接翻倍,还能保留信号在截断处的过渡特征。在数据集体量较小时缓解训练模型的过拟合

STEP_SIZE = 512 # 步长 < 窗口大小,产生重叠

def slice_signal(signal, label, window_size, stride):
    X, y = [], []
    # range(开始, 结束, 步长)
    for i in range(0, len(signal) - window_size, stride):
        sample = signal[i : i + window_size]
        X.append(sample)
        y.append(label)
    return X, y

将所有的数据整合到一起

建立一个映射字典,循环处理每个文件,把结果都扔到一个大的列表里,最后统一转成 NumPy 数组。

FILE_MAP = {
    '97.mat': 0,  # label 0: Normal
    '105.mat': 1, # label 1: Inner Race
    # ... 其他文件
}

# 循环逻辑
for file_name, label in FILE_MAP.items():
    signal = load_and_normalize(f"{data_folder}/{file_name}")
    X_samples, y_labels = slice_signal(signal, label, WINDOW_SIZE, STEP_SIZE)
    all_X.extend(X_samples)
    all_y.extend(y_labels)

X = np.array(all_X)
y = np.array(all_y)

打上CNN训练需要的维度

PyTorch 的 Conv1d 层期望的输入形状是 (Batch, Channel, Length)。可以用 np.expand_dims 在中间插入通道维度。

import numpy as np
# 在 axis=1 的位置插入维度
# 变换前:(N, 1024) -> 变换后:(N, 1, 1024)
X = np.expand_dims(X, axis=1)

将数据集标签进行独热编码

标签本身并没有大小顺序属性

通过独热编码编码把整数标签转换成正交向量,使其更符合分类任务的数学表示。

独热编码好像在上一篇简单线性回归模型里面也有写到?

终于不是全部依赖ai而是活学活用嘛

import torch
import torch.nn.functional as F

y_tensor = torch.tensor(y, dtype=torch.long)
# num_classes=4 对应四种故障类型
y_onehot = F.one_hot(y_tensor, num_classes=4)

数据的一致性

在使用 train_test_split 时使用 stratify 参数,它能保证切分后的训练集和测试集里,各种故障类别的比例一致。

from sklearn.model_selection import train_test_split

# stratify=y 确保比例一致
X_train, X_temp, y_train, y_temp = train_test_split(
    X_tensor, y_onehot, test_size=0.3, stratify=y
)

封装数据

写一个简单的 Dataset 类,然后传给 DataLoader 就能实现按批次读取和打乱顺序。

对训练数据打乱顺序可以有效增强最终训练模型的泛化性

class VibrationDataset(Dataset):
    def __init__(self, data, labels):
        self.data = data
        self.labels = labels
    def __getitem__(self, idx):
        return self.data[idx], self.labels[idx]
    def __len__(self):
        return len(self.data)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

检查代码

把碎片步骤串起来后,别忘了检查输出的张量形状,确保流水线搭建无误。

images, labels = next(iter(train_loader))
print(f"输入张量形状: {images.shape}") # 应为 (64, 1, 1024)
print(f"标签张量形状: {labels.shape}") # 应为 (64, 4)

可视化检查

抽取第一个样本,用matplotlib可视化检查一下

# 可视化检查
sample_signal = images[0].numpy().flatten()  # 形状为(1024,)
plt.figure(figsize=(10, 4))
plt.plot(sample_signal)
plt.title(f"Dataloader Sample Signal (Label: {labels[0].argmax()})")
plt.xlabel("Time Points")
plt.ylabel("Normalized Amplitude")
plt.show()

最终的结果大致如下

可视化检查

ai评价

写完程序之后发给ai问有什么有点什么缺点

ai说的话如下

缺点 ❌
硬编码问题:
文件夹路径、批大小、窗口大小等直接写死,不便配置,没有配置文件或参数类,缺少异常处理:
文件不存在时无错误处理,找不到数据键时会直接崩溃,随机种子问题:
train_test_split有random_state=42,但DataLoader shuffle没有设置种子,不便复现
内存效率:一次性加载所有数据到内存,大数据集会溢出,应该使用生成器或分批加载
模块化不足:没有分离为模块(无if __name__ == '__main__'),不能作为库被其他代码导入使用
缺少保存机制:处理后的数据没有保存功能,重复运行会重新计算
验证代码占比过高:大量print语句用于调试,生产环境应该转为日志
没有错误日志:数据处理过程中如果样本数为0,无法察觉

ai提到说不应该用这么多的print来检查代码是否正常运行而是应该用“日志”的形式来检查

又是一个新的知识点,完全不知道,继续学习吧!

不过ai也不是一点好话都不说

    优点 ✅
结构清晰:逻辑流程从加载 → 切片 → 预处理 → 划分 → 加载器,分层明确
功能完整:包含数据加载、归一化、滑动窗口切片、one-hot编码、数据集划分、可视化验证
注释详细:中文注释帮助理解每个步骤
类设计规范:VibrationDataset继承Dataset,符合PyTorch约定
数据验证充分:检查GPU/CPU、验证归一化效果、可视化样本
数据标注完善:清晰的文件标签映射(4类故障)

总结一下

这一个清洗和切分的程序应该会用在为搭建1-CNN神经网络处理数据,想要搭建二维时频图的训练模型还要再进一步处理。

返回文章列表

Next

Home