3. 特征工程与可视化

任务目标

本案例将使用Edge Impulse完成一次加速度计数据的特征工程闭环:通过其内置DSP模块生成时域与频域特征,并在"Feature Explorer"中可视化特征分布,以验证不同类别(如静止、走动、抖动)在特征空间中的可分性。

环境与前置条件

  • Edge Impulse开发者账号(免费版即可)
  • 已创建项目并上传包含3种类别标签的加速度计CSV数据(采样率50Hz,每段2秒,共100段以上)
  • 数据格式:timestamp,accX,accY,accZ,label,标签取值为idle、walk、shake

实现步骤与关键代码

在Edge Impulse Studio中,特征工程通过图形化DSP配置完成,无需编写训练代码。核心操作如下:

  1. 进入Create Impulse页面,添加Processing Block,选择Spectral Analysis(频谱分析)作为特征生成器。
  2. 设置窗口参数:Window size = 100(对应2秒@50Hz),Window increase = 50(50%重叠)。
  3. 在Spectral features中启用:RMS(时域均方根)、Zero crossings(过零率)、Spectral power(频域功率,取1-10Hz与10-25Hz两个频段)。
  4. 点击Save parameters,然后进入Generate features页面,点击Generate features按钮。

生成完成后,系统自动将原始信号转换为特征向量。以下为等效的Python参考代码,用于理解Edge Impulse内部执行的特征提取逻辑(实际部署时由Edge Impulse自动生成C++代码):

import numpy as np
from scipy import signal

def extract_features(window_data, fs=50):
    """window_data: shape (100, 3) 对应 accX, accY, accZ"""
    features = []
    for axis in range(3):
        x = window_data[:, axis]
        # 时域特征
        rms = np.sqrt(np.mean(x**2))
        zero_cross = np.sum(np.diff(np.sign(x)) != 0) / len(x)
        # 频域特征(使用FFT)
        freqs, psd = signal.periodogram(x, fs)
        band1 = np.trapz(psd[(freqs >= 1) & (freqs <= 10)])
        band2 = np.trapz(psd[(freqs > 10) & (freqs <= 25)])
        features.extend([rms, zero_cross, band1, band2])
    return np.array(features)  # 每轴4个特征,共12维

# 使用示例(假设已有窗口数据)
# sample_window = np.random.randn(100, 3)
# feat = extract_features(sample_window)
# print(feat.shape)  # (12,)

可视化与验证

特征生成后,Edge Impulse自动执行PCA降维并将结果投射到Feature Explorer(特征探索器)二维散点图中。验证流程如下:

  1. 点击左侧Feature Explorer标签页。
  2. 观察散点图颜色分布:idle(蓝色)、walk(绿色)、shake(红色)三类样本应各自聚集成簇。
  3. 若类别间存在明显重叠,返回Spectral features调整频段划分或增加Spectral skewness、Spectral kurtosis等特征。

通过判定标准:三类样本在散点图中形成至少2个可区分的簇,且同类样本的簇内距离明显小于簇间距离。若三类完全混杂,则需检查原始数据标签是否准确或增加特征维度。

PC1(主成分1) PC2(主成分2) idle(静止) walk(走动) shake(抖动) ▲ 理想特征分布示意

常见问题

  • 特征生成失败:检查CSV时间戳是否严格等间隔,缺失值会导致FFT计算异常。
  • 类别完全重叠:原始信号差异过小,建议增加Spectral flatness或改用Raw Data处理块配合分类器自动学习特征。
  • 验证集准确率低:在Create Impulse中增大Window size至150(3秒),以捕获更完整的运动周期。