diff options
author | Timotej Lazar <timotej.lazar@fri.uni-lj.si> | 2017-06-20 18:54:59 +0200 |
---|---|---|
committer | Timotej Lazar <timotej.lazar@fri.uni-lj.si> | 2017-06-20 18:54:59 +0200 |
commit | 99bbb6cd39e9491fef3bdcbcf40235c21a479c5d (patch) | |
tree | 58b43d1e22d8daf8b38c5f6b4b354ea89e2e7637 /2017/free-will/scripts | |
parent | bea5b9ff3689787a4107ee6634be47413f3fc4d5 (diff) | |
parent | 5740ed3123e97d5c424340d613515d965087aefc (diff) |
Add '2017/free-will/' from commit '5740ed3123e97d5c424340d613515d965087aefc'
git-subtree-dir: 2017/free-will
git-subtree-mainline: bea5b9ff3689787a4107ee6634be47413f3fc4d5
git-subtree-split: 5740ed3123e97d5c424340d613515d965087aefc
Diffstat (limited to '2017/free-will/scripts')
-rw-r--r-- | 2017/free-will/scripts/python-learning.py | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/2017/free-will/scripts/python-learning.py b/2017/free-will/scripts/python-learning.py new file mode 100644 index 0000000..d144678 --- /dev/null +++ b/2017/free-will/scripts/python-learning.py @@ -0,0 +1,157 @@ +import numpy as np +import pandas +from math import ceil, floor +from sklearn.model_selection import train_test_split +from sklearn import svm +from sklearn.model_selection import KFold, StratifiedKFold, permutation_test_score +from sklearn import linear_model +from sklearn.svm import SVC +import pickle +import matplotlib.pyplot as plt +import numpy.fft as fft +from sklearn import datasets + +class MyOVBox(OVBox): + def __init__(self): + OVBox.__init__(self) + # Names of CSV files + self.signalFileName = "" + self.stimFileName = "" + # Name of Save File + self.saveFileName = "" + # other variables + self.windowSize = 0 # window size in ms + self.numOfPreviousWindowsAsOne = 0 # number of windows before actual stimulation to be marked as 1 + self.numOfWindowsBefore = 0 # number of windows before those marked as 1, to be marked as 0 + self.numOfWindowsAfter = 0 # number of windows after those marked as 1, to be marked as 0 + + + def filter_signal(self, sampleRate, numberOfSamplesWindow, stimulationTimes, splittedSignal): + """ returns tuple of filtered (signal chunks, classes) """ + splittedSignal_filtrd = [] + classes_filtrd = [] + + temp_classes = np.zeros(len(splittedSignal)) + + for stim in stimulationTimes: + index = int(floor(stim*sampleRate/numberOfSamplesWindow)) + temp_classes[index] = 1 + for i in range(1, self.numOfPreviousWindowsAsOne): + temp_classes[index-i] = 1 + + tmp_cls_winds = temp_classes[(index - self.numOfPreviousWindowsAsOne - self.numOfWindowsBefore):index+self.numOfWindowsAfter] + tmp_sig_winds = np.concatenate(splittedSignal[(index - self.numOfPreviousWindowsAsOne - self.numOfWindowsBefore):index+self.numOfWindowsAfter]) + + if len(tmp_sig_winds)/len(tmp_cls_winds)!=numberOfSamplesWindow: # if np.array_split does not split in equal windows + tmp_sig_winds = np.lib.pad(tmp_sig_winds, ((0, int(len(tmp_cls_winds)*numberOfSamplesWindow-len(tmp_sig_winds))),(0, 0)), 'edge') # pad with same values on end of array + + classes_filtrd.extend(tmp_cls_winds) + splittedSignal_filtrd.extend(np.array_split(tmp_sig_winds, len(tmp_cls_winds))) + + return (splittedSignal_filtrd, classes_filtrd) + + + def avg_k_fold(self, data, classes, k=4): + """ return average CA of k-fold cross validation """ + avg_val = 0 + + kf = KFold(n_splits=k) + for train, test in kf.split(data): + clf = svm.SVC(kernel='linear', C=1).fit(data[train], classes[train]) + cur_score = clf.score(data[test], classes[test]) + avg_val += cur_score + # print cur_score + return avg_val/k + + + def permutation_significance_classification_score(self, X, y, k_folds=4): + n_classes = np.unique(y).size + + svm = SVC(kernel='linear') + cv = StratifiedKFold(k_folds) + + score, permutation_scores, pvalue = permutation_test_score(svm, X, y, scoring="accuracy", cv=cv, n_permutations=200, n_jobs=1) + print("Classification score %s (pvalue : %s)" % (score, pvalue)) + + plt.hist(permutation_scores, 20, label='Permutation scores') + ylim = plt.ylim() + plt.plot(2 * [score], ylim, '--g', linewidth=3, + label='Classification Score' + ' (pvalue %s)' % pvalue) + plt.plot(2 * [1. / n_classes], ylim, '--k', linewidth=3, label='Luck') + + plt.ylim(ylim) + plt.legend() + plt.xlabel('Score') + plt.show() + + + def initialize(self): + # Names of CSV files + self.signalFileName = self.setting['InputCSVSignal'] + self.stimFileName = self.setting['InputCSVStimulations'] + # Name of Save File + self.saveFileName = self.setting['SaveFile'] + # other variables + self.windowSize = int(self.setting['WindowSize (ms)']) # in ms + self.numOfPreviousWindowsAsOne = int(self.setting['NumOfPrevWindows']) + self.numOfWindowsBefore = int(self.setting['NumOfWindowsBefore'])-1 + self.numOfWindowsAfter = int(self.setting['NumOfWindowsAfter'])+1 + self.k_folds = int(self.setting['K-folds']) + + print "Reading files..." + # read CSV files + signalArray = pandas.read_csv(self.signalFileName, delimiter=";", encoding="utf-8-sig") + stimsArray = pandas.read_csv(self.stimFileName, delimiter=";", encoding="utf-8-sig") + print "Files read!" + + # sort information from tables (pandas dataframe) + time = signalArray['Time (s)'] + electrodes = signalArray.iloc[:, 1:signalArray.shape[1]-1] + sampleRate = signalArray['Sampling Rate'][0] + stimulationTimes = stimsArray['Time (s)'] + + numberOfSamplesWindow = floor(self.windowSize / ((1/sampleRate)*1000)) # number of samples for approximately self.windowSize ms + + splittedSignal = np.array_split(electrodes, ceil(len(time)/numberOfSamplesWindow)) # split signal into chunks of specified length + + s_c = self.filter_signal(sampleRate, numberOfSamplesWindow, stimulationTimes, splittedSignal) # filter signal and return sparsed version of chunks and assign classes + splittedSignal_filtrd = s_c[0] + classes_filtrd = s_c[1] + + splittedSignal_filtrd_means = np.array(np.mean(splittedSignal_filtrd, axis=1)) # for each window calculate mean value + # additional attributes could be added besides splittedSignal_filtrd_means + classes_filtrd = np.array(classes_filtrd) + + # print average k-fold CA + print "Average " + str(self.k_folds) + "-folds value: " + str(self.avg_k_fold(splittedSignal_filtrd_means, classes_filtrd, k=self.k_folds)) + #self.permutation_significance_classification_score(splittedSignal_filtrd_means, classes_filtrd, k_folds=2) # k_folds=2, last long if k is bigger + + if self.saveFileName: + clf = svm.SVC(kernel='linear', C=1).fit(splittedSignal_filtrd_means, classes_filtrd) + clf.fit(splittedSignal_filtrd_means, classes_filtrd) + + print "Saving to pickle file: " + self.saveFileName + pickle.dump(clf, open(self.saveFileName, 'wb')) + print "Learned score: " + str(clf.score(splittedSignal_filtrd_means, classes_filtrd)) + + # send finish stimulation output (for OpenViBE) + self.finishBySendingStimulation(32774) # OVTK_StimulationId_TrialStop code + + + def finishBySendingStimulation(self, stimulationCode): + stimSetFinish = OVStimulationSet(self.getCurrentTime(), self.getCurrentTime()+1./self.getClock()) + stimSetFinish.append(OVStimulation(stimulationCode, self.getCurrentTime(), 0.)) + self.output[0].append(stimSetFinish) + + + def process(self): + + return + + def uninitialize(self): + # nop + + return + +box = MyOVBox() |