腦機介面例項二:腦電訊號CSP處理

iceberg7012發表於2020-12-05


前言

本文在例項一的基礎之上,選用BCI大賽08年資料集,基於CSP的特徵提取,運用AdaBoost演算法進行整合分類,以期實現運動想象中左、右手動作腦電訊號的分類。


一、例項說明

1.1 期望目標

  • 掌握資料集預處理的方法
  • 實際運用CSP演算法進行特徵提取
  • 對提取的特徵進行boosting分類(AdaBoost是其中一種)

1.2 資料解讀

  1. 實驗正規化

      資料集由9名受試者的腦電圖資料組成。BCI正規化由四個不同的運動想象任務組成,即左手(類別1)、右手(類別2)、雙腳(類別3)和舌頭(類別4)的運動想象。正規化記錄不同日期的兩天資料。(每天6圈,每圈48trails)。(共計576個trails,每個任務144trails)
      正式正規化之前,記錄5分鐘估計EOG值,分三塊:看螢幕上的十字(2分鐘)、閉眼(1分鐘)、眼動(1分鐘),注:由於技術問題被試A04T的眼動資料較短,僅包含眼動狀態。如下圖所示:
在這裡插入圖片描述
      被試者坐在電腦螢幕前面的舒適的扶手椅上,在試驗開始時(t=0s),黑屏上出現了一個十字。此外,還提出了一種短聲告警音。兩秒後(t=2s),以箭頭的形式指向左、右、下或上(對應於四個類中左手、右手、腳或舌頭的一個)的提示,出現在螢幕上1.25秒。這促使受試者完成所需的運動想象任務。不提供任何反饋。被試在t=6s時被要求執行運動想象任務,直到螢幕上的十字消失為止。隨後螢幕再次為黑色的短暫中斷,流程如下圖所示:(有效資料為2-6s,即運動想象任務記錄區間,亦為需提取資料的區間)
在這裡插入圖片描述

  1. 資料記錄

      250Hz取樣,並在0.5Hz和100Hz之間進行帶通濾波。除了22個腦電圖通道,3個單極EOG通道,以250Hz的頻率記錄和取樣(見下圖)。它們在0.5Hz和100Hz之間進行帶通濾波,放大器的靈敏度設定為1mV。EOG通道是為偽像處理方法的後續應用提供的,不得用於分類。
在這裡插入圖片描述

  1. 資料檔案描述

      事件型別描述如下 (event type 769/770 對應左右手的動作,以此為基準進行資料提取)
在這裡插入圖片描述

二、例項程式碼及結果分析

2.1 MATLAB程式碼

主函式(main):

clc;clear;

%% 讀取資料並對資料預處理

Subjects = 9;      %被試數
Fs = 250;          %取樣率
windowLength = 4;  %單次取樣時間
chanSelect = [8,10,12]; %通道選擇c3,c4,cz
totalFlt = [4 40]; %總的濾波頻段選擇

load rawdata1.mat
[Data_train,label_train] = preProccess(Fs,windowLength,EEG,chanSelect,totalFlt); %preProccess執行資料提取、分段、濾波處理

load rawdata2.mat
[Data_test,label_test] = preProccess(Fs,windowLength,EEG,chanSelect,totalFlt);

%% CSP特徵提取

EEGSignals.x = Data_train;
EEGSignals.y = label_train;
Y = label_train;

classLabels = unique(EEGSignals.y); 
CSPMatrix = learnCSP(EEGSignals,classLabels);
nbFilterPairs = 1;
X = extractCSP(EEGSignals, CSPMatrix, nbFilterPairs); 

EEGSignals_test.x=Data_test;
EEGSignals_test.y=label_test;
T = extractCSP(EEGSignals_test, CSPMatrix, nbFilterPairs); 

save dataCSP.mat X Y T


color_L = [0 102 255] ./ 255;
color_R = [255, 0, 102] ./ 255;

pos = find(Y==1);
plot(X(pos,1),X(pos,2),'x','Color',color_L,'LineWidth',2);

hold on
pos = find(Y==2);
plot(X(pos,1),X(pos,2),'o','Color',color_R,'LineWidth',2);

legend('Left Hand','Right Hand')
xlabel('C3','fontweight','bold')
ylabel('C4','fontweight','bold')
CSP演算法:

function CSPMatrix = learnCSP(EEGSignals,classLabels)
%
%Input:
%EEGSignals: the training EEG signals, composed of 2 classes. These signals
%are a structure such that:
%   EEGSignals.x: the EEG signals as a [Ns * Nc * Nt] Matrix where
%       Ns: number of EEG samples per trial
%       Nc: number of channels (EEG electrodes)
%       nT: number of trials
%   EEGSignals.y: a [1 * Nt] vector containing the class labels for each trial
%   EEGSignals.s: the sampling frequency (in Hz)
%
%Output:
%CSPMatrix: the learnt CSP filters (a [Nc*Nc] matrix with the filters as rows)
%
%See also: extractCSPFeatures

%check and initializations
nbChannels = size(EEGSignals.x,2);
nbTrials = size(EEGSignals.x,3);
nbClasses = length(classLabels);

if nbClasses ~= 2
    disp('ERROR! CSP can only be used for two classes');
    return;
end

covMatrices = cell(nbClasses,1); %the covariance matrices for each class

%% Computing the normalized covariance matrices for each trial
trialCov = zeros(nbChannels,nbChannels,nbTrials);
for t=1:nbTrials
    E = EEGSignals.x(:,:,t)';                       %note the transpose
    EE = E * E';
    trialCov(:,:,t) = EE ./ trace(EE);
end
clear E;
clear EE;

%computing the covariance matrix for each class
for c=1:nbClasses      
    covMatrices{c} = mean(trialCov(:,:,EEGSignals.y == classLabels(c)),3); %EEGSignals.y==classLabels(c) returns the indeces corresponding to the class labels  
end

%the total covariance matrix
covTotal = covMatrices{1} + covMatrices{2};

%whitening transform of total covariance matrix
[Ut Dt] = eig(covTotal); %caution: the eigenvalues are initially in increasing order
eigenvalues = diag(Dt);
[eigenvalues egIndex] = sort(eigenvalues, 'descend');
Ut = Ut(:,egIndex);
P = diag(sqrt(1./eigenvalues)) * Ut';

%transforming covariance matrix of first class using P
transformedCov1 =  P * covMatrices{1} * P';

%EVD of the transformed covariance matrix
[U1 D1] = eig(transformedCov1);
eigenvalues = diag(D1);
[eigenvalues egIndex] = sort(eigenvalues, 'descend');
U1 = U1(:, egIndex);
CSPMatrix = U1' * P;

2.2 執行結果及分析

  1. CSP特徵提取
    在這裡插入圖片描述
    在這裡插入圖片描述

圖一,由演算法程式碼進行預處理資料後得到的CSP特徵提取結果
圖二,由匯入eeglab進行預處理資料後得到的CSP特徵提取結果

        分析: 由上圖,我們可以看出,當前CSP演算法對資料進行了一定程度的特徵提取,但特徵之間並沒有達到理想的分離程度,部分資料集中糾纏在一起。產生此結果的可能原因:(1)資料提取、預處理階段存在不足;(2)該CSP演算法自身存在缺陷(如本例項將導聯關係限制在C3、C4、CZ三個通道,與其他通道導聯的相關性難以體現)。針對可能原因1,我j將資料匯入eeglab,用eeglab自身的預處理功能,對資料進行預處理操作,再應用CSP演算法進行特徵提取,但實驗結果同樣不理想。於是,猜想出現不理想結果可能更多的是原因2造成的,接下來,我將嘗試應用不同的方法,對特徵進行提取。

  1. AdaBoost整合分類
    在這裡插入圖片描述

        分析: 從CSP提取的特徵中,選擇144個資料點組成訓練集,進行30次迭代整合分類,由圖可以看出,隨著迭代次數的增加,訓練錯誤率在降低,即分類準確率在提高。儘管如此,分類的錯誤率仍超過30%,結果並不理想,也在側面說明,CSP演算法存在問題,有進一步改進的空間。

三、問題與反思

  • 資料預處理的實際應用能力較弱。例如,在對資料進行分段提取,標籤定義,以及應用IIR 濾波,ICA眼電訊號去除進行資料預處理的過程中,由於對陣列的理解不夠準確,時常報錯;
  • CSP特徵提取演算法掌握不足,實際應用中,對程式碼的理解尚淺薄,不能靈活應用和變通;
  • 反思:理論知識結合到實際應用中的能力有待加強,接下來,會嘗試採用不同的演算法實現腦電訊號的分類任務,進一步在實踐中,加深對演算法的理解、掌握。

四、下一階段計劃

  • 例項結果的分析表明,當前CSP演算法進行特徵提取的效果不夠理想,有進一步改進的空間,下一階段計劃將圍繞這個主題展開。
  • 任務一:嘗試採用不同的演算法,對特徵進行提取,以期得到更好的實驗結果。
  • 任務二:腦機介面理論知識儲備不足,嘗試系統性學習相關知識。
  • 任務三:加強相關演算法的學習與應用(分類演算法掌握尚淺)。

本文原始碼:
連結:https://pan.baidu.com/s/1TzEskR1vP4TMx64aTOHRBg (百度網盤)
提取碼:muda

相關文章