脑电信号预处理--去趋势化(Detrended fluctuation analysis)
更多技术干货第一时间送达
由于脑电信号的不稳定性和不规则性,因此对脑电信号的处理也比较复杂,难以直接从中分析出内在联系。通常情况下会对信号做一定的预处理,通过这种粗糙的处理,可以得到具有一定规律的信号,便于后续的研究。
下面介绍一种方法,去趋势化(Detrended Fluctuation Analysis),简称为DFA方法。这种方法在各个领域都有所适用,是对非稳态信号处理的一种常用方法,多用于气象信号,场信号等长程相关性的分析,用来确定非稳态信号中长程的幂函数相关性,能够定量的分析信号序列的关联性质,通过计算相关性指数,确定信号的不同属性。
对于这种方法可以简单理解为,信号本身具有内在的某种联系,而由于采集到的信号存在外部的噪声使得信号内部的联系函数之上叠加了多项式趋势信号,使得信号内部联系无法明确找到,DFA方法通过滤去序列中的各阶趋势成分,有效避免由于噪声和信号的不稳定而表现出来的伪关联的干扰。
DFA方法处理信号是一种长程相关性的分析方法,那么什么是长程相关性?
对长程相关性可以理解为在一组监测到的信号内部处处存在关联,彼此都有相互的影响,同时从整体和局部的角度来看,信号每处局部的趋势和整体的趋势存在一定的相似性,称为自相似性(个人理解可能与统计学中幂函数分布所具有的记忆性类似)。
那么如何判断一组信号是否满足长程相关性呢?
长程相关分析主要的方法便是DFA方法和重标极差分析方法(R/S分析),下面我们开始进入正题:
去趋势化的原理便是通过对原数据的点状图图像减去一条拟合直线从而消去数据呈现出的趋势变化,这种方法可以呈现出数据的特征。
具体实现的方法如下:
利用最小二乘法得到图像趋势的拟合曲线,因为是点状图所构成的,因此用相应点的纵坐标值减去所得拟合曲线对应横坐标下的纵坐标值,即为去趋势化后的图像。
在matlab中有相应的函数detrend来对数据进行直接处理,下面给出matlab中的一个实例:
Matlab中Dtrend函数中文介绍
detrend函数功能:去除多项式趋势
语法:
y = detrend(x)
y = detrend(x,n)
y = detrend(x,n,bp)
y = detrend(___,nanflag)
y = detrend(___,Name,Value)
y = detrend(x) 从 x 的数据中去除最佳直线拟合线。
如果 x 是向量,则 detrend 从 x 的元素中减去趋势。
如果 x 是矩阵,则 detrend 分别对每列进行运算,从对应的列中减去每个趋势。
示例:连续线性趋势
创建一个数据向量,并去除连续线性趋势。绘制原始数据、去趋势后的数据和线性趋势。
t = 0:20;
x = 3*sin(t) + t;
y = detrend(x);
plot(t,x,t,y,t,x-y,':k')
legend('Input Data','Detrended Data','Trend','Location','northwest')
y = detrend(x,n) 去除 n 次多项式趋势。
例如,当 n = 0 时,detrend 从 x 中删除均值。
当 n = 1 时,detrend 去除线性趋势,这等效于上述语法。
当 n = 2 时,detrend 去除二次趋势。
示例:连续二次趋势
创建一个数据向量,并使用 0 处的断点去除分段线性趋势。指定所得到的输出可以是不连续的。绘制原始数据、去趋势后的数据和趋势。
t = 0:20;
x = 20*sin(t) + t.^2;
y = detrend(x,2);
plot(t,x,t,y,t,x-y,':k')
legend('Input Data','Detrended Data','Trend','Location','northwest')
y = detrend(x,n,bp) 去除由断点 bp 定义段的连续分段趋势。
y = detrend(___,nanflag) 指定在使用上述任一语法时如何处理 NaN 值。
例如,detrend(x,'omitnan') 在计算趋势之前删除 NaN 值,而 detrend(x,'includenan') 包括这些值(默认)。
y = detrend(___,Name,Value) 使用一个或多个名称-值对组指定其他参数。例如,detrend(x,1,bp,'Continuous',false) 指定拟合趋势可以有不连续趋势。
示例:不连续线性趋势
创建一个数据向量,并使用 0 处的断点去除分段线性趋势。指定所得到的输出可以是不连续的。绘制原始数据、去趋势后的数据和趋势。
t = -10:10;
x = t.^3 + 6*t.^2 + 4*t + 3;
bp = 0;
y = detrend(x,1,bp,'SamplePoints',t,'Continuous',false);
plot(t,x,t,y,t,x-y,':k')
legend('Input Data','Detrended Data','Trend','Location','northwest')
上面是matlab官网上对函数的介绍,给出了函数的参数说明,以供参考。
这里就直接给出对脑电信号做去趋势化处理的代码示例:
load('data_set_IVa_aw.mat'); %加载原始数据
data=cnt;
data=1*double(data);
fc = 100; %采样频率100Hz
N = 565676; %采样点数282838
n = 0:N-1;
f = n*fc/N; %频率序列
figure, %以第一个通道为例
plot(f(1:N/2),data(:,1),'b'); %未处理前标为蓝色
detrend_data=detrend(data);
hold on,
plot(f(1:N/2),detrend_data(:,1),'r'); %处理后标为红色
运行结果:
可以看到,由于脑电信号的趋势性并不是特别明显,因此去趋势化处理后的图像并不能将特征直接提取出来,因而需要利用其他方法做进一步处理。
作者博客地址:
https://blog.csdn.net/weixin_43361652/article/details/103180421
参考:
https://ww2.mathworks.cn/help/matlab/ref/detrend.html?action=changeCountry&s_tid=gn_loc_drop
https://www.mathworks.com/help/matlab/data_analysis/detrending-data.html