4.2 特征工程:把波形压成含义


4.2 特征工程:把波形压成含义

本节摘要:特征工程把原始波形压缩为携带意图的低维量,四类武器各有射程:时域统计便宜而稳健,频带功率是节律类范式的标配,时频表达捕捉功率随时间的起伏,空间滤波(尤其共空间模式)专治头皮信号的空间混合。本节逐类拆解其原理与适用场景,重点讲透共空间模式的直觉与实现。

预处理之后的信号仍是"原始"的:三十二个通道、每秒二百五十点、每个点一个浮点数——一秒数据就近万维。分类器吃不下也不必吃这么多维。特征工程的问题是:**哪几十个数字最能区分"想象左手"与"想象右手"?**这不是一个数学题,而是一个生理学题——答案藏在 2.4 节的体检单里:缪节律功率会凹,P300 峰会隆,伽马活性会变。特征就是把体检单上的条目变成数字。

时域特征:最便宜的起点

方差是最常用的时域特征——它等于信号的功率(去均值后),计算成本几乎为零。对运动想象,对侧运动区的缪带功率下降直接表现为滤波后方差变小,一个方差就是一个特征。稍复杂的时域指标还有 Hjorth 参数(活动度、移动性、复杂度三个量,从信号导数算出,近似频谱形状的压缩版)与峰值幅度、过零率。时域特征的优点是快到可以跑在微控制器上,缺点是不分频率——你不知道这方差来自贝塔带还是来自残余肌电。

频域特征:节律范式的主力

频带功率把信号按频段切开后分别求功率,是节律类特征的标准形态。经典实现是 Welch 方法:分窗求各窗周期图再平均,换到更平稳的估计。频带功率特征的可用性有一条 2.4 节的老原则背书:节律变化本身就是大脑表达意图的方式,频带功率因此是"顺着信号说话"的特征。事件相关去同步的量化也落在这一类:任务窗功率与基线窗功率之比取对数,负值即去同步深度。

时频表达是频域特征的升级版:短时傅里叶变换把时间轴切成小窗逐窗求频谱,小波变换则用可变窗宽换取"低频看得宽、高频看得细"。当特征需要"何时发生"(如运动想象去同步在提示后约零点五秒最深),时频表达就不可替代。代价是维度爆炸——一个窗的时频图就是几百维,通常只在特定时频块上取值。

图 4-1:共空间模式如何把两类信号分开

图 4-1:共空间模式如何把两类信号分开

空间滤波特征:专治头皮的糊

共空间模式(CSP)值得单独一节。它解决的问题很具体:左右手想象的差异信号在头皮上微弱且互相混叠,直接拿各通道功率做特征,信噪比不够。CSP 的做法是从数据里学一组空间滤波器——每个滤波器是全通道的一个加权组合——使得信号投影到第一个滤波器上时,一类的方差最大、另一类最小;再补一组对偶滤波器让次序反过来。用滤波后的方差(取对数)做特征,通常前两到三对就把两类分得干干净净。

它的局限性同样有名:对训练数据量敏感,样本不足时学到的滤波器泛化差;对被试个体差异敏感,换人必须重学;对频带选择敏感,实践中常配合"滤波器组"策略——按多个子带分别学 CSP 再拼合特征。一个朴素的建议:样本少于每类几十个试次时,先用正则化的 CSP 或干脆退回拉普拉斯加频带功率,等数据攒够了再上。

import numpy as np def band_power(x, fs, lo, hi): """Welch 频带功率:x 形状为 试次 x 通道 x 时间""" from scipy.signal import welch freqs, psd = welch(x, fs=fs, nperseg=fs, axis=-1) mask = (freqs >= lo) & (freqs < hi) return psd[..., mask].mean(axis=-1) # 输出 试次 x 通道 def erd_index(task_pow, base_pow): """去同步深度:任务窗与基线窗功率比取常用对数""" return np.log10(task_pow / base_pow) def csp_filters(X1, X2, k=2): """共空间模式的简化实现:协方差白化加广义特征分解""" C1 = np.cov(X1.reshape(-1, X1.shape[-1])) C2 = np.cov(X2.reshape(-1, X2.shape[-1])) W = np.linalg.eigh(C1 + C2 + 1e-6 * np.eye(C1.shape[0]))[1] Z = W.T @ np.linalg.inv(np.linalg.cholesky(C1 + C2 + 1e-6 * np.eye(C1.shape[0]))).T from scipy.linalg import eigh _, U = eigh(Z @ C1 @ Z.T, Z @ (C1 + C2) @ Z.T) return np.concatenate([U[:, :k], U[:, -k:]], axis=1) # 前 k 与后 k 个滤波器 # 用法示意:X1 与 X2 分别为两类(如想象左手与右手)的训练数据 # filters = csp_filters(X1, X2, k=2) # feat1 = np.log(band_power(np.einsum("oc,ndt->nodt", filters, X1)[..., 0, :], fs, 8, 30))

代码块里的三行注释给出了完整用法。实际项目中不必手写 CSP——主流脑电工具库都有久经考验的实现——但手写一遍的价值在于看清它的骨架:CSP 不是魔法,它就是一次广义特征分解,所有局限性都能从这个骨架里推出来。

事件相关电位特征:另一条路线

P300 类范式的特征完全不同:不看功率看波形。典型的做法是滤波后按刺激对齐分段、基线校正,然后取一百至五百毫秒窗内若干时间点的幅值作为特征,或直接把整段下采样后喂给分类器。这类特征对时间对齐极其敏感——采样时钟抖动几毫秒,P300 峰就错位。第五章 5.5 节的拼字复盘里,特征段的选择会成为一个真实的调参现场。

本节要点回顾

  • 四类特征四类射程:时域最便宜,频带功率顺节律,时频保时间信息,空间滤波解混合;
  • ERD 的量化是任务窗与基线窗的功率比对数,负值即去同步;
  • CSP 的骨架是一次广义特征分解,有效因信息集中在少数源,脆弱因训练量不足;
  • P300 走波形路线:幅值特征对时间对齐敏感,与节律范式的功率路线完全不同;
  • 特征选择的原则:顺着 2.4 节的生理体检单取值,而不是把所有特征一股脑塞给模型。

特征就位。下一节让模型上场:从线性判别到深度网络,谁适合哪个范式,以及脑机接口评估里那个最容易踩的坑。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U