4. 特征工程
任务目标
本案例以一段加速度计原始信号为输入,通过Python实现特征工程,提取时域统计特征(均值、标准差、均方根、峰值、峰峰值、过零率)与频域特征(主频幅值、频谱质心),输出结构化特征向量,为后续边缘AI分类模型提供输入。
环境依赖
仅需Python 3.8+与NumPy,无需其他第三方库。若需可视化可安装Matplotlib(本案例不强制)。
关键完整代码
import numpy as np
def extract_time_features(signal, fs):
"""提取时域统计特征"""
n = len(signal)
mean = np.mean(signal)
std = np.std(signal)
rms = np.sqrt(np.mean(signal**2))
peak = np.max(np.abs(signal))
peak_to_peak = np.max(signal) - np.min(signal)
# 过零率:信号穿越零点的次数 / 样本数
zero_crossings = np.sum(np.diff(np.signbit(signal)) != 0)
zcr = zero_crossings / n
return {
'mean': mean,
'std': std,
'rms': rms,
'peak': peak,
'peak_to_peak': peak_to_peak,
'zcr': zcr
}
def extract_freq_features(signal, fs):
"""提取频域特征:主频幅值、频谱质心"""
n = len(signal)
# 去除直流分量后加窗,减少频谱泄漏
windowed = signal - np.mean(signal)
windowed = windowed * np.hanning(n)
spectrum = np.fft.rfft(windowed, n)
freqs = np.fft.rfftfreq(n, d=1/fs)
magnitudes = np.abs(spectrum)
# 忽略直流分量(freq=0)
nonzero = freqs > 0
freqs_nz = freqs[nonzero]
mags_nz = magnitudes[nonzero]
if len(mags_nz) == 0:
return {'dominant_freq': 0.0, 'dominant_mag': 0.0, 'spectral_centroid': 0.0}
# 主频及其幅值
idx = np.argmax(mags_nz)
dominant_freq = freqs_nz[idx]
dominant_mag = mags_nz[idx]
# 频谱质心(幅值加权平均频率)
centroid = np.sum(freqs_nz * mags_nz) / np.sum(mags_nz)
return {
'dominant_freq': dominant_freq,
'dominant_mag': dominant_mag,
'spectral_centroid': centroid
}
def extract_all_features(signal, fs):
"""组合时域与频域特征,返回扁平字典"""
features = {}
features.update(extract_time_features(signal, fs))
features.update(extract_freq_features(signal, fs))
return features
# ===== 最小可运行示例 =====
if __name__ == '__main__':
# 生成模拟信号:2Hz正弦 + 0.5Hz低频漂移 + 噪声
fs = 100 # 采样率100Hz
t = np.arange(0, 2, 1/fs) # 2秒数据
np.random.seed(42)
signal = 1.5*np.sin(2*np.pi*2*t) + 0.3*np.sin(2*np.pi*0.5*t) + 0.1*np.random.randn(len(t))
feats = extract_all_features(signal, fs)
for k, v in feats.items():
print(f"{k}: {v:.4f}")
运行方式
python feature_engineering.py
验证方法与判定标准
运行后观察输出特征值,验证逻辑如下:
- 主频验证:信号主成分为2Hz正弦,
dominant_freq应接近2.0Hz(因加窗与噪声影响,允许±0.2Hz偏差); - 均值验证:信号无直流偏置,
mean应接近0(允许±0.05偏差); - RMS验证:2Hz分量幅值1.5,其RMS理论值为1.5/√2≈1.061,叠加噪声后
rms应接近1.0~1.2范围; - 过零率验证:2Hz信号每秒穿越零点4次,2秒共约8次,
zcr应接近8/200=0.04(噪声会使其略增,允许±0.02偏差); - 频谱质心验证:能量集中在2Hz附近,
spectral_centroid应落在1.5~3.0Hz区间。
若上述数值均在合理范围内,说明特征提取逻辑正确。将signal替换为实际传感器采集数据(一维NumPy数组)即可直接复用extract_all_features函数。
常见问题
- 输入信号含直流偏置:频域特征提取前已自动去除均值,但时域
mean特征会保留该偏置,属预期行为; - 采样率不匹配:
fs必须与实际采样率一致,否则dominant_freq和spectral_centroid会系统性偏移; - 信号长度过短:建议至少包含5个以上完整周期,否则频域分辨率不足,主频估计误差增大。