最近在处理MI数据的时候发现滤波真的很重要啊,之前一直没把预处理当个事,这次发现还是很重要的!!!
有FIR滤波的时候准确率为百分之九十多。
注释掉FIR滤波后,准确率只有百分之三十多。。。还赶不上随机的结果。
数据和代码可下载:https://download.csdn.net/download/zhoudapeng01/12423358
import time
import mne
import pickle
from mne.decoding import CSP
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import ShuffleSplit, cross_val_score
from sklearn.pipeline import Pipeline
# 设置log输出等级
mne.set_log_level(False)
# BCICIV_2a_gdf中脑电信道的名称
channels_A = ['EEG-Fz', 'EEG-0', 'EEG-1', 'EEG-2', 'EEG-3', 'EEG-4', 'EEG-5', 'EEG-C3', 'EEG-6', 'EEG-Cz',
'EEG-7', 'EEG-C4', 'EEG-8', 'EEG-9', 'EEG-10', 'EEG-11', 'EEG-12', 'EEG-13', 'EEG-14', 'EEG-Pz',
'EEG-15', 'EEG-16']
# 定义CSP分类函数,用于分类左手右手的信号
def MI_EEG_CSP(fileName, components, channels):
# 加载挑选出的脑电数据,根据信号的质量经过了初步的筛选
with open(fileName, 'rb') as f:
epochs = pickle.load(f)
# 对数据进行滤波处理
epochs_train = epochs.filter(7., 30., fir_design='firwin', skip_by_annotation='edge')
# epochs_train = epochs
# 只处理其中的左右手部分(总共包括4类)
trainData = epochs_train['cueLeft', 'cueRight'].get_data(channels)
trainLabels = epochs_train['cueLeft', 'cueRight'].events[:, -1]
# 根据设计的交叉验证参数,分配相关的训练集和测试集数据
cv = ShuffleSplit(10, test_size=0.2, random_state=42)
# 创建线性分类器
lda = LinearDiscriminantAnalysis()
# 创建CSP提取特征,这里使用4个分量的CSP
csp = CSP(n_components=components, reg=None, log=False, norm_trace=False)
# 创建机器学习的Pipeline,也就是分类模型,使用这种方式可以把特征提取和分类统一整合到了clf中
clf = Pipeline([('CSP', csp), ('LDA', lda)])
# 获取交叉验证模型的得分
scores = cross_val_score(clf, trainData, trainLabels, cv=cv, n_jobs=4)
# 输出结果,准确率和不同样本的占比
class_balance = np.mean(trainLabels == trainLabels[0])
class_balance = max(class_balance, 1. - class_balance)
print("Classification accuracy: %f / Chance level: %f" % (np.mean(scores), class_balance))
if __name__ == '__main__':
# 程序开始时间
timeStart = time.time()
# 设置文件路径
fileFullPathA = r'F:\BaiduNetdiskDownload\BCICompetition\BCICIV_2a_gdf\Train\CueLRFT\trainData.pkl'
# 运行CSP算法
MI_EEG_CSP(fileFullPathA, components=4, channels=channels_A)
# 程序结束时间
timeEnd = time.time()
# 打印程序整体用时
print("用时:", timeEnd - timeStart)
有FIR滤波的时候准确率为68%左右。
没有FIR滤波的时候准确率仅为51%左右。
开始的时候发现滤波前后数据没有变化,一度认为是MNE库的bug,后来发现在MNE库中默认是不会对eog数据滤波的。在这里默认只处理eeg数据,前后对比可以发现eeg数据变化了,而eog数据并没有改变。
FIR滤波前:
FIR滤波后: