diff --git a/balanceClasses.m b/balanceClasses.m index c5574e4..8ec0c8c 100644 --- a/balanceClasses.m +++ b/balanceClasses.m @@ -1,11 +1,20 @@ -function [trainClasses,trainData]=balanceClasses(trainClasses,trainData,noClasses,eps) - while sum(abs(diff(histcounts(trainClasses,noClasses))))> 0+eps - mostFrequent=find(trainClasses==mode(trainClasses)); - - r=floor(size(mostFrequent,2)*rand(1)+1); - delIndex=mostFrequent(r); - trainClasses=trainClasses([1:delIndex-1,delIndex+1:end]); - trainData=trainData([1:delIndex-1,delIndex+1:end],:); +function [trainClasses,trainData]=balanceClasses(trainClasses,trainData,maxPerClass,noClasses) + if maxPerClass > min(histcounts(trainClasses,noClasses)) + maxPerClass=min(histcounts(trainClasses)); + warning('not enough Data per Class; set maxPerClass to %i', maxPerClass); end - assert(size(trainClasses,2)>0) + i=1; + delPerClass=histcounts(trainClasses,noClasses)-maxPerClass; + delIndex=zeros(sum(delPerClass),1); + while sum(delPerClass)>0 + r=fix(size(trainClasses,1)*rand(1)+1); + if delPerClass(trainClasses(r)+1)>0 && all(delIndex~=r) + delIndex(i)=r; + i=i+1; + delPerClass(trainClasses(r)+1)=delPerClass(trainClasses(r)+1)-1; + end + end + trainClasses(delIndex)=[]; + trainData(delIndex,:)=[]; + assert(size(trainClasses,1)>0) end \ No newline at end of file diff --git a/classifyAccordingToEMG.m b/classifyAccordingToEMG.m index 8805818..3d37e5c 100644 --- a/classifyAccordingToEMG.m +++ b/classifyAccordingToEMG.m @@ -11,7 +11,7 @@ classification(j)=-1; %code for pause end for j=max(fix(i-0.5/shift),1):i % half a second before executed movement there should be activity (esp. EEG) - classification(j)=-1; + classification(j)=class; end oldclass=class; end diff --git a/generateTrainingData.m b/generateTrainingData.m index bf0e6e2..fa16f55 100644 --- a/generateTrainingData.m +++ b/generateTrainingData.m @@ -1,21 +1,21 @@ -function [trainingDataEEG,trainingDataEMG] = generateTrainingData(signal,NFFT,window,shift,params) +function [trainingDataEEG,trainingDataEMG] = generateTrainingData(signal,NFFT,windowEMG,windowEEG,shift,params,pburgOrder) frequency=params.SamplingRate.NumericValue; - signalWindow=frequency*window; - shiftProp=window/shift; - tempEEG=zeros([32,fix(floor(size(signal,1)/signalWindow)-1)*shiftProp+1,NFFT/2+1]); - tempEMG=zeros(fix([size(signal,2)-3-32,fix(floor(size(signal,1)/signalWindow)-1)*shiftProp+1])); + signalWindowEMG=frequency*windowEMG; + signalWindowEEG=frequency*windowEEG; + tempEEG=zeros([32,fix(floor(size(signal,1)/signalWindowEEG-1)*windowEEG/shift+1),NFFT/2+1]); + tempEMG=zeros(fix([size(signal,2)-3-32,fix(size(signal,1)/signalWindowEMG-1)*windowEMG/shift+1])); %Filter around 50Hz and below 2 Hz [A,B]= butter(2,[48 52]/(frequency/2),'stop'); [C,D]= butter(2,2/(frequency/2),'high'); parfor i=1:32 %filter single channel, w/o HEOG, Synchro and 0s - tempEEG(i,:,:)=shiftingPwelch(filter(C,D,filter(A,B,signal(:,i))),frequency,window,shift,NFFT); - end + tempEEG(i,:,:)=shiftingPburg(filter(C,D,filter(A,B,signal(:,i))),frequency,windowEEG,shift,NFFT,pburgOrder); + end % TODO: 8-30Hz, pburg bei kurzen Fenstern (Ordnung: Je nach SamplingRate, bei 2500: 32-50, Alpha, Beta peaks sollten sichtbar sein) trainingDataEEG=permute(tempEEG,[2 1 3]); parfor i=33:size(signal,2)-3 - tempEMG(i-32,:,:)=waveformLength(filter(C,D,filter(A,B,signal(:,i))),frequency,window,shift); + tempEMG(i-32,:,:)=waveformLength(filter(C,D,filter(A,B,signal(:,i))),frequency,windowEMG,shift); end trainingDataEMG=permute(tempEMG,[2 1 3]); end \ No newline at end of file diff --git a/kfoldCV.m b/kfoldCV.m index 8f5c5be..7194ee3 100644 --- a/kfoldCV.m +++ b/kfoldCV.m @@ -1,4 +1,4 @@ -function [model,maxC] = kfoldCV(classification,trainingData,k,cExpMax) +function [model,maxC] = kfoldCV(classification,trainingData,k,cExpMax,maxDataPerClass) noClasses=size(unique(classification),1); cvAccurancy=zeros(2*cExpMax+1,1); parfor cExp=1:2*cExpMax+1 @@ -13,7 +13,7 @@ trainClasses=classification(mod(randomMapping,k)+1~=i); testClasses=classification(mod(randomMapping,k)+1==i); %fprintf('i=%i, k=%i, c=%i\n',i,k,c) - [trainClasses,trainData]=balanceClasses(trainClasses,trainData,noClasses,0.00001); + [trainClasses,trainData]=balanceClasses(trainClasses,trainData,maxDataPerClass,noClasses); model=svmtrain(trainClasses,trainData(:,:),sprintf('-t 0 -c %f -q',c)); [~, accurancy(i,:), ~]=svmpredict(testClasses, testData(:,:), model,'-q'); end @@ -22,7 +22,7 @@ end [~,maxC]=max(cvAccurancy); bestC=2^(maxC-cExpMax-1); - [balancedClasses, balanceData]=balanceClasses(classification,trainingData,noClasses,0.00001); + [balancedClasses, balanceData]=balanceClasses(classification,trainingData,maxDataPerClass,noClasses); model=svmtrain(balancedClasses, balanceData(:,:),sprintf('-t 0 -c %f -q',bestC)); end \ No newline at end of file diff --git a/read.m b/read.m index 965c5ea..af975f3 100644 --- a/read.m +++ b/read.m @@ -4,12 +4,16 @@ disp('start') disp(datestr(datetime('now'))) NFFT=2048; -window=0.2; +windowEMG=0.2; +windowEEG=1; shift=0.2; k=10; maxExpC=5; maxFile=5; threshold=7500; +pburgOrder=32; + +%EEG: window: 1, shift 0.2 trainingDataEEGcell=cell(maxFile,1); trainingDataEMGcell=cell(maxFile,1); @@ -17,7 +21,7 @@ for i=1:maxFile [sig, stat, params] = load_bcidat(sprintf('/home/jph/Uni/masterarbeit/Block1_ReachingMovements/AO/AO_B1001/AO_B1S001R0%i.dat',i)); - [trainingDataEEGcell{i},trainingDataEMGcell{i}]=generateTrainingData(sig,NFFT,window,shift,params); + [trainingDataEEGcell{i},trainingDataEMGcell{i}]=generateTrainingData(sig,NFFT,windowEMG,windowEEG,shift,params,pburgOrder); classesCell{i}=stat.StimulusCode; fprintf('%ith file processed\n',i) end @@ -44,7 +48,7 @@ classification=smoothClassification(smoothClassification~=-1); clear smoothClassification i -save /home/jph/Uni/masterarbeit/data/AO1200msWindow1sPause.mat +save /home/jph/Uni/masterarbeit/data/AO1200msWindow05sPause05sClass.mat disp('end') diff --git a/readme.m b/readme.m index 9bb3767..babc2a6 100644 --- a/readme.m +++ b/readme.m @@ -76,3 +76,6 @@ % threshold anhand von historgam/plot (bimodal?) % für confusion: caxis, normierung für predicted + + +% Balancing bis nur noch n pro Klasse übrig sind diff --git a/svm.m b/svm.m index e56e459..de3f6d0 100644 --- a/svm.m +++ b/svm.m @@ -2,13 +2,13 @@ clear all clc -load('/home/jph/Uni/masterarbeit/data/AO1200msWindow1sPause.mat'); +load('/home/jph/Uni/masterarbeit/data/AO1200msEMGWindow1sEEGWindow200msShift05sPause05sClass.mat'); -%k=2; -%maxExpC=0; % c\in {2^i|i=-maxExpC:1:maxExpC} +k=2; +maxExpC=0; % c\in {2^i|i=-maxExpC:1:maxExpC} %choose to estimate based on EEG or EMG -trainingData=trainingDataEMG; +trainingData=trainingDataEEG; clear trainingDataEEG; clear trainingDataEMG; @@ -25,7 +25,7 @@ remainingClasses=classification(mod(randMap,k)~=i-1); disp(datestr(datetime('now'))) fprintf('create %ith model\n',i) - [model,maxC(i)]=kfoldCV(remainingClasses,remaining,k,maxExpC); + [model,maxC(i)]=kfoldCV(remainingClasses,remaining,k,maxExpC,100); disp(datestr(datetime('now'))) [predictions,accurancy(i,:),pvalues]=svmpredict(leaveClasses,leaveOut(:,:),model);