特征工程基础:让传感器数据真正“说话”

说实话,很多做剩余寿命预测的朋友,一上来就急着调模型。我刚开始也是这样,觉得特征工程嘛,不就是标准化一下、算几个统计量?结果呢?模型效果差得离谱。后来我才明白——特征工程做不好,再牛的算法也是白搭

这一章,咱们就聊聊传感器数据的“预处理三件套”:标准化/归一化、滑动窗口特征提取、特征相关性分析。这些都是我实际项目中反复踩坑、又反复验证过的经验。

1. 标准化 vs 归一化:别搞混了

先问个问题:你拿到一组传感器数据,温度是80-120℃,振动是0.1-5.0 m/s²,压力是0.8-1.2 MPa。这三个量纲完全不同,直接扔进模型会怎样?

嗯,模型会“偏心”——它会更关注数值大的特征,比如温度。这显然不合理。

标准化(Z-score)归一化(Min-Max)就是来解决这个问题的。我个人的习惯是:

  • 归一化:把数据缩放到[0,1]区间。适合数据分布比较均匀、没有极端值的情况。公式很简单:X_norm = (X - X_min) / (X_max - X_min)
  • 标准化:把数据变成均值为0、标准差为1的分布。适合数据有异常值、或者后续要用PCA等算法时。公式:X_std = (X - μ) / σ

我的经验之谈:在工业设备健康监测中,传感器数据经常会有突发性尖峰(比如瞬间冲击)。这时候用归一化,最大值会被这个尖峰“拉偏”,导致正常数据被压缩得很厉害。我建议优先用标准化,它对异常值更鲁棒。

来看一段Python代码,很实用:

from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np

# 模拟传感器数据:温度、振动、压力
sensor_data = np.array([[85.0, 0.5, 0.9],
                        [92.0, 1.2, 1.0],
                        [78.0, 0.3, 0.8],
                        [105.0, 4.8, 1.1]])  # 注意振动有个尖峰

# 标准化
scaler_std = StandardScaler()
data_std = scaler_std.fit_transform(sensor_data)

# 归一化
scaler_mm = MinMaxScaler()
data_mm = scaler_mm.fit_transform(sensor_data)

print("标准化后:\n", data_std)
print("归一化后:\n", data_mm)

运行一下你会发现,那个4.8的振动尖峰在归一化后,把其他振动值都压到了0附近。而标准化后,分布就合理多了。

小技巧:如果你不确定用哪个,可以两个都试试,然后看哪个让模型收敛更快、效果更好。工业场景下,我80%的情况都用标准化。

2. 滑动窗口特征提取:从“点”到“段”的跃迁

单个时间点的传感器读数,信息量太有限了。你想想看,一个振动值突然升高,可能是故障前兆,也可能是传感器被碰了一下。怎么办?

我的做法是:用滑动窗口把连续一段时间的特征“打包”起来。这样就能捕捉到趋势和变化。

常用的窗口特征有:

  • 均值:反映这段时间的“平均水平”
  • 方差:反映数据的“波动程度”——波动越大,往往意味着异常
  • 斜率:反映数据的“变化趋势”——是上升还是下降?

我在项目中遇到过这样一个案例:一个轴承的振动信号,均值一直很平稳,但方差在缓慢增大。如果只看均值,你会觉得设备没问题。但方差暴露了真相——轴承正在劣化。这就是窗口特征的价值。

代码实现也不复杂:

import numpy as np
import pandas as pd

def extract_window_features(data, window_size=10):
    """
    滑动窗口特征提取
    data: 一维传感器数据
    window_size: 窗口大小
    """
    features = []
    for i in range(len(data) - window_size + 1):
        window = data[i:i+window_size]
        
        # 均值
        mean_val = np.mean(window)
        # 方差
        var_val = np.var(window)
        # 斜率(用线性回归的系数近似)
        x = np.arange(window_size)
        slope = np.polyfit(x, window, 1)[0]
        
        features.append([mean_val, var_val, slope])
    
    return np.array(features)

# 模拟一段振动数据
vibration = np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.1, 100)
# 在第50个点后加入劣化趋势
vibration[50:] += 0.02 * np.arange(50)

window_feats = extract_window_features(vibration, window_size=10)
print("窗口特征形状:", window_feats.shape)
print("前5个窗口的特征:\n", window_feats[:5])

注意:窗口大小怎么选?太小了,特征不稳定;太大了,会丢失局部变化。我一般从设备物理特性出发——比如轴承的旋转周期是0.1秒,那窗口至少覆盖2-3个周期。实在拿不准,就多试几个窗口大小,用交叉验证来选。

3. 特征相关性分析:别让“冗余特征”拖后腿

特征提取完了,你可能得到几十个甚至上百个特征。但问题来了——很多特征之间是高度相关的。比如温度和热膨胀系数,几乎线性相关。把这些都扔进模型,不仅增加计算量,还会导致过拟合。

我常用的方法是皮尔逊相关系数。它的值在-1到1之间:

  • 接近1:强正相关(一个增大,另一个也增大)
  • 接近-1:强负相关(一个增大,另一个减小)
  • 接近0:基本不相关

来看一个实际例子:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# 模拟特征数据
np.random.seed(42)
n_samples = 100
features = pd.DataFrame({
    '温度': np.random.normal(85, 5, n_samples),
    '振动均值': np.random.normal(1.2, 0.3, n_samples),
    '振动方差': np.random.normal(0.5, 0.1, n_samples),
    '压力': np.random.normal(1.0, 0.1, n_samples),
    '转速': np.random.normal(3000, 100, n_samples),
})

# 人为制造相关性:温度和压力正相关
features['压力'] = features['温度'] * 0.01 + np.random.normal(0, 0.05, n_samples)

# 计算相关系数矩阵
corr_matrix = features.corr()
print("相关系数矩阵:\n", corr_matrix)

# 找出高度相关的特征对(|相关系数| > 0.8)
high_corr_pairs = []
for i in range(len(corr_matrix.columns)):
    for j in range(i+1, len(corr_matrix.columns)):
        if abs(corr_matrix.iloc[i, j]) > 0.8:
            high_corr_pairs.append((corr_matrix.columns[i], 
                                    corr_matrix.columns[j],
                                    corr_matrix.iloc[i, j]))
print("\n高度相关的特征对:")
for pair in high_corr_pairs:
    print(f"{pair[0]} 与 {pair[1]}: {pair[2]:.3f}")

运行后你会发现,温度和压力的相关系数可能高达0.9以上。这时候,我建议只保留其中一个,或者用PCA降维把它们合并。

避坑指南:我曾经犯过一个错误——把所有相关性大于0.8的特征都删掉了。结果模型效果反而变差了。为什么?因为有些特征虽然相关,但它们各自携带了不同的“信息维度”。比如温度和压力相关,但温度变化快、压力变化慢,两者结合能反映不同的物理过程。所以,相关性分析是参考,不是铁律。删不删,还得结合业务理解。

4. 知识体系总览

说了这么多,咱们用一张图来梳理一下本章的核心逻辑:

特征工程核心流程 原始传感器数据 标准化/归一化 消除量纲影响 滑动窗口特征提取 均值 | 方差 | 斜率 捕捉趋势与波动 特征相关性分析 剔除冗余,保留有效信息 特征筛选与优化 保留强相关、弱冗余特征 高质量特征集 输入模型进行预测 核心原则:先消除量纲 → 再提取时序特征 → 最后筛选冗余特征 每一步都需结合业务理解,不可机械套用

这张图清晰地展示了特征工程的三个核心步骤,以及它们之间的反馈关系。记住:这不是一个单向流水线,而是一个迭代优化的过程。你做完相关性分析后,可能发现某些窗口特征提取得不好,需要回去调整窗口大小——这很正常。

5. 写在最后

特征工程这件事,说白了就是“让数据自己说话”。标准化是让数据“说同一种语言”,滑动窗口是让数据“说完整的故事”,相关性分析是让数据“不说废话”。

我见过太多人把时间花在调模型参数上,却忽略了特征工程。结果呢?模型精度死活上不去。其实很多时候,好的特征工程比好的模型更重要。你想想看,如果输入的都是垃圾,再牛的算法也输出不了黄金。

下一章,咱们会把这些特征工程技巧应用到实际的剩余寿命预测案例中。到时候你会发现,前面这些“基础工作”有多值钱。


公众号:蓝海资料掘金营,微信deep3321