4、时序数据基础:时间序列的概念、滑动窗口、采样率与时间分辨率、序列的平稳性与非平稳性
各位同学,咱们今天聊聊时序数据。说实话,搞脑电信号处理,绕不开的就是时间序列。你想想看,脑电信号本质上就是电压随时间变化的曲线,这不就是最典型的时间序列吗?
我刚开始接触EEG的时候,总觉得这玩意儿跟普通数据没啥区别。后来踩了不少坑才明白——时间序列有它自己的脾气,你得顺着它来。
4.1 时间序列到底是什么?
简单说,时间序列就是按时间顺序排列的数据点。比如你每隔1毫秒采一次脑电电压值,连续采10秒,你就得到了一串长度为10000的序列。
用数学语言表达:X = {x₁, x₂, x₃, ..., xₜ},其中t表示时间索引。
这里有个关键点——顺序不能乱。普通数据集你随便打乱顺序,模型照样能学。但时间序列一旦打乱,信息就全毁了。为什么?因为时间序列里藏着时间依赖关系,前一个时刻的值会影响后一个时刻的值。
核心要点:时间序列的三个基本特征——
- 有序性:数据点按时间排列,顺序不可交换
- 依赖性:当前值往往与历史值相关
- 连续性:相邻时间点的值通常变化不大
我在项目中遇到过一件事。有个同学把脑电数据随机打乱了做训练,结果模型准确率直接掉到50%以下。他跑来问我怎么回事,我说你这不是在学时间序列,你是在学噪声。嗯,从那以后他再也不敢乱打乱时序数据了。
4.2 滑动窗口——处理长序列的利器
实际中,脑电数据动不动就是几十分钟甚至几小时。你不可能把整段数据一次性塞进模型——显存不够,计算量也太大。
怎么办?用滑动窗口。
说白了,就是用一个固定大小的窗口,在时间轴上一步步滑动,每次取窗口内的数据作为一个样本。
我的习惯:窗口大小一般设为1-3秒。太短了信息不够,太长了计算负担重。对于脑电信号,1秒的窗口通常能包含足够的节律信息。
举个例子,假设采样率是250Hz,窗口大小设为1秒(250个点),步长设为0.5秒(125个点):
# 滑动窗口示例
import numpy as np
def sliding_window(data, window_size, step_size):
"""
data: 原始时间序列,形状为 (n_samples,)
window_size: 窗口大小(点数)
step_size: 步长(点数)
"""
windows = []
for start in range(0, len(data) - window_size + 1, step_size):
end = start + window_size
windows.append(data[start:end])
return np.array(windows)
# 假设采样率250Hz,1秒窗口,0.5秒步长
data = np.random.randn(10000) # 40秒数据
windows = sliding_window(data, window_size=250, step_size=125)
print(f"原始数据长度: {len(data)}")
print(f"滑动窗口后样本数: {len(windows)}")
print(f"每个样本长度: {len(windows[0])}")
输出结果:
原始数据长度: 10000
滑动窗口后样本数: 79
每个样本长度: 250
你看,40秒的数据被切成了79个样本,每个样本1秒。这样模型就能逐个处理了。
注意:步长决定了样本之间的重叠程度。步长越小,重叠越多,样本数越多,但信息冗余也越大。我曾经为了增加训练数据量,把步长设得很小,结果模型过拟合了——因为相邻样本太相似了。
4.3 采样率与时间分辨率
采样率,就是每秒钟采集多少个数据点。单位是Hz(赫兹)。
比如250Hz的采样率,意味着每秒钟采250个点,每个点间隔4毫秒。
时间分辨率,就是你能分辨的最小时间间隔。采样率越高,时间分辨率越高,你能捕捉到的信号细节就越多。
| 采样率 | 采样间隔 | 可分析的最高频率 | 典型应用场景 |
|---|---|---|---|
| 128 Hz | 7.8 ms | 64 Hz | 睡眠脑电、低频研究 |
| 250 Hz | 4.0 ms | 125 Hz | 常规脑电、ERP研究 |
| 500 Hz | 2.0 ms | 250 Hz | 高频振荡、肌电干扰分析 |
| 1000 Hz | 1.0 ms | 500 Hz | 精细时间分析、诱发电位 |
这里有个重要的定理——奈奎斯特采样定理:采样率必须至少是信号最高频率的两倍,才能无失真地重建信号。
举个例子,如果你想分析40Hz的gamma节律,采样率至少要80Hz。实际中我一般留点余量,用250Hz以上。
我记得有一次,一个同学用128Hz的采样率去分析60Hz的噪声成分,结果发现根本分析不出来。我告诉他,你的采样率连奈奎斯特条件都没满足,怎么可能看到60Hz?
4.4 平稳性与非平稳性
这是时间序列分析里最绕的一个概念。我尽量说清楚。
平稳序列:统计特性(均值、方差、自相关)不随时间变化。
非平稳序列:统计特性随时间变化。
脑电信号,说白了就是非平稳的。为什么?因为人的大脑状态一直在变——你眨眼了、你走神了、你听到一个声音了,这些都会改变脑电的统计特性。
判断方法:
- 看均值:如果均值随时间明显漂移,就是非平稳
- 看方差:如果方差随时间变化,也是非平稳
- 看自相关:如果自相关结构变化,还是非平稳
为什么要在意平稳性?因为很多经典的时间序列分析方法(比如ARIMA模型)都假设数据是平稳的。如果你拿非平稳数据硬套,结果会一塌糊涂。
不过,对于深度学习来说,情况有点不同。RNN、LSTM这些模型,天生就能处理非平稳序列——它们有记忆机制,能自适应地学习时间依赖关系的变化。
我曾经做过一个实验:用LSTM处理平稳化前后的脑电数据,发现准确率差别不大。这说明深度学习对非平稳性有一定的容忍度。但话说回来,如果你能把数据预处理得更平稳,模型训练通常会更快、更稳定。
实用技巧:
- 差分操作:
yₜ = xₜ - xₜ₋₁,可以去除趋势,让序列更平稳 - 归一化:对每个窗口单独做z-score归一化,可以消除幅值差异
- 分段处理:把长序列切成短段,每段内近似平稳
4.5 本章知识体系
下面这张图,是我自己画的,把本章的核心概念串起来了。你仔细看看,应该能对时序数据有个整体认识。
嗯,这张图把本章的核心概念都串起来了。你从中心的时间序列出发,往四个方向延伸——定义、滑动窗口、采样率、平稳性。每个分支下面还有更细的子概念。
我个人建议你把这图保存下来,以后做脑电分析的时候,遇到问题先回来看看这张图,思路会清晰很多。
好了,时序数据的基础就讲到这里。下一章我们会深入RNN的核心机制,看看它到底是怎么处理这些时间序列的。
公众号:蓝海资料掘金营,微信deep3321