def test_distance_generic_kullback(): """Test logeuclid distance for generic function""" A = 2*np.eye(3) B = 2*np.eye(3) assert_equal(distance(A,B,metric='kullback'),distance_kullback(A,B)) assert_equal(distance(A,B,metric='kullback_right'),distance_kullback_right(A,B)) assert_equal(distance(A,B,metric='kullback_sym'),distance_kullback_sym(A,B))
def test_distance_generic_kullback(): """Test logeuclid distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert_equal(distance(A, B, metric='kullback'), distance_kullback(A, B)) assert_equal(distance(A, B, metric='kullback_right'), distance_kullback_right(A, B)) assert_equal(distance(A, B, metric='kullback_sym'), distance_kullback_sym(A, B))
def predict_distances_own(covtest): covmeans = mean_cov_n Nc = len(covmeans) dist = [distance(covtest, covmeans[m], 'riemann') for m in range(Nc)] dist = np.concatenate(dist, axis=1) return dist
def compute_distances(subjects, rank=65, mode='common', metric='riemann', picks='mag', reg=1e-6): print('computing projections') X, y = { 'common': project_common_space, 'own': project_own_space }[mode](subjects, rank, picks=picks) n_subj, n_freqs, p, _ = X.shape if reg: for i in range(n_subj): for f in range(n_freqs): X[i, f] += reg * np.eye(p) print('computing distances') n_subjects, n_freqs, p, _ = X.shape D = np.zeros((n_freqs, n_subjects, n_subjects)) for freq in range(n_freqs): for i in range(n_subjects): print('\rFreq {}, done {}/{}'.format(freq, i + 1, n_subjects), end="", flush=True) for j in range(i + 1): A = X[i, freq] B = X[j, freq] dist = distance(A, B, metric) D[freq, i, j] = dist D[freq, j, i] = dist return D, y
def fit(self, X, y, centroids=None, T=0, NT=1, sample_weight=None): """Fit (estimates) the centroids and the parameters of the R_TNT distribution. Parameters ---------- X : ndarray, shape (n_trials, n_channels, n_channels) ndarray of SPD matrices. y : ndarray shape (n_trials, 1) labels corresponding to each trial. T,NT : name of the label TARGET and the label NONTARGET given in y sample_weight : None | ndarray shape (n_trials, 1) the weights of each sample. if None, each sample is treated with equal weights. Returns ------- self : Bayes_R_TNT instance The Bayes_R_TNT instance. """ self.classes = [T, NT] # self.centroids = [] if sample_weight is None: sample_weight = np.ones(X.shape[0]) # for l in self.classes: # self.centroids.append( # mean_covariance(X[y == l], metric=self.metric_mean, # sample_weight=sample_weight[y == l])) if centroids == None: self.centroids = [ mean_covariance(X[y == l], metric=self.metric_mean, sample_weight=sample_weight[y == l]) for l in self.classes ] else: self.centroids = centroids distance_list = [ np.array([distance(x, self.centroids[l]) for i, x in enumerate(X)]) for l in self.classes ] self.distribution = [[ np.log(distance_list[0][index] / distance_list[1][index]) for index, value in enumerate(X) if y[index] == l ] for l in self.classes] self.distribution_mean = [ np.mean(self.distribution[l]) for l in self.classes ] self.distribution_sigma = [ np.var(self.distribution[l]) for l in self.classes ] if self.distribution_mean[0] >= self.distribution_mean[1]: print( 'Target R_TNT Distribution mean should be smaller as Non Target R_TNT Distribution mean. Check the labels.' ) return self
def predict_distances_own(covtest, covmeans): # # # Predicts the Riemannian distances between two covariance matrices # # # # Returns: the Riemannian distance between the inputs Nc = len(covmeans) dist = [distance(covtest, covmeans[m], 'riemann') for m in range(Nc)] dist = np.concatenate(dist, axis=1) return dist
def test_from_cross_template_P300(template_path, subject_path, test_chnames, flashmode='RoCo', nb_targets=180, visu=False): T = 0 NT = 1 ERP = np.load(template_path + 'ERP_Array.npy') Centroids_List = np.load(template_path + 'Centroids_List.npy') mu_TNT = np.load(template_path + 'rTNT_mu.npy') sigma_TNT = np.load(template_path + 'rTNT_var.npy') data, labels, event = get_data_from_csv_EIV( myfilename=subject_path + '-signals.csv', markersfile=subject_path + 'markers.csv', chnames=test_chnames) erp = ERPCovariances() erp.P = ERP erp.estimator = 'cov' X = erp.transform(data) train_NaiveBayes = R_TNT_NaiveBayes(targets=[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' ], mu_TNT=mu_TNT, sigma_TNT=sigma_TNT, class_prior=None) dist = [ np.array([distance(x, Centroids_List[l]) for i, x in enumerate(X)]) for l in [T, NT] ] r_TNT = np.array(np.log(dist[0] / dist[1])) mean, var = test_loop_P300(r_TNT_test=r_TNT, y_test=labels, e_test=event, train_NaiveBayes=train_NaiveBayes, T=0, NT=1, flashmode=flashmode, visu=visu, nb_targets=nb_targets) return mean, var
def apply_ts_fgda(X_test, train_fgda, centroids_train_fgda, T=0, NT=1): classes = [T, NT] ts_test = train_fgda._ts.transform(X=X_test) X_test_fgda = train_fgda.transform(X=X_test) dist = [distance(X_test_fgda, centroids_train_fgda[l]) for l in classes] r_TNT_fgda = np.log(dist[0] / dist[1]) r_TNT_fgda = np.array(r_TNT_fgda) return X_test_fgda, r_TNT_fgda, ts_test
def _predict_distances(self, covtest): """Helper to predict the distance. equivalent to transform.""" Nc = len(self.covmeans_) if self.n_jobs == 1: dist = [distance(covtest, self.covmeans_[m], self.metric_dist) for m in range(Nc)] else: dist = Parallel(n_jobs=self.n_jobs)(delayed(distance)( covtest, self.covmeans_[m], self.metric_dist) for m in range(Nc)) dist = np.concatenate(dist, axis=1) return dist
def predict_R_TNT(X, centroids_list): """Helper to predict the r_TNT for a new set of trials. Parameters ---------- X : ndarray, shape (n_trials, n_channels, n_channels) """ T = 0 NT = 1 dist = [distance(X, centroids_list[m]) for m in [T, NT]] r_TNT = np.log(dist[0] / dist[1]) r_TNT = np.array(r_TNT) return r_TNT
def find_soulmate_iter(population_signals, stranger_signals): dist_dict = {} stranger_covariance = covariances(X=stranger_signals) stranger_reference = mean_covariance(covmats=stranger_covariance, metric='riemann') for subject, subject_signal in population_signals.iteritems(): subject_covariance = covariances(X=subject_signal) subject_reference = mean_covariance(covmats=subject_covariance, metric='riemann') dist_dict[subject] = distance(stranger_reference, subject_reference) sorted_dist_dict = sorted(dist_dict.items(), key=operator.itemgetter(1)) return dict(sorted_dist_dict)
def check_distance(subjects, rank=65, picks="all", mode="common", reg=True): C, _ = project_covariances(np.arange(640), rank, picks, mode) X, _ = project_tangent_space(np.arange(640), rank, picks, mode, reg) C = C[subjects] X = X[subjects] n_s, n_f, p, _ = C.shape D = np.zeros((n_s, n_s, n_f)) D2 = np.zeros((n_s, n_s, n_f)) for i in range(n_f): for j in range(n_s): for k in range(j + 1): d = distance(C[j, i], C[k, i]) D[j, k, i] = d D[k, j, i] = d d2 = np.linalg.norm(X[j, i] - X[k, i]) D2[j, k, i] = d2 D2[k, j, i] = d2 return D, D2
def create_rTNT(self, signals, markers, delta, ERP, centroids_list): """ Segment the signals in epochs of length delta after a marker. """ T = 0 NT = 1 if self.bandpass is not None: lowf, hif = self.bandpass signals = self.apply_bandpass_filter(signals, lowf, hif) s = signals.set_index('Time(s)')[self.chnames] Nt = int(delta * signals['SamplingRate'][0]) Nc = len(self.chnames) if ERP.shape[0] != Nc: raise ValueError('ERP channels number does not fit data') if ERP.shape[1] != Nt: raise ValueError('ERP times number does not fit data ') all_rTNT = [] all_labels = [] # for t in markers[markers['Identifier'] in [self.target, self.nontarget]]['Time(s)']: for i, t in enumerate(markers['Time(s)']): if markers['Identifier'][i] in self.target + self.nontarget: tmp = np.asarray(s.loc[t:t + delta]).T if tmp.shape[1] >= Nt: trial_cov = np.cov( np.concatenate([ERP, tmp[:, :Nt]], axis=0)) dist = [ distance(trial_cov, centroids_list[m]) for m in [T, NT] ] all_rTNT.append(np.log(dist[0] / dist[1])) if markers['Identifier'][i] in self.target: all_labels.append(0) if markers['Identifier'][i] in self.nontarget: all_labels.append(1) self.rTNT = np.array(all_rTNT) self.labels = np.array(all_labels)
def test_distance_generic_custom(): """Test custom distance for generic function""" A = 2*np.eye(3) B = 2*np.eye(3) assert_equal(distance(A, B, metric=distance_logeuclid), distance_logeuclid(A, B))
def test_distance_generic_logeuclid(): """Test logeuclid distance for generic function""" A = 2*np.eye(3) B = 2*np.eye(3) assert_equal(distance(A, B, metric='logeuclid'), distance_logeuclid(A, B))
def test_distance_generic_riemann(): """Test riemannian distance for generic function""" A = 2*np.eye(3) B = 2*np.eye(3) assert_equal(distance(A, B, metric='riemann'), distance_riemann(A, B))
def test_distance_wrapper(dist, dfunc, get_covmats): n_trials, n_channels = 2, 5 covmats = get_covmats(n_trials, n_channels) A, B = covmats[0], covmats[1] assert distance(A, B, metric=dist) == dfunc(A, B)
def test_distance_generic_logeuclid(): """Test logeuclid distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert_equal(distance(A, B, metric='logeuclid'), distance_logeuclid(A, B))
def test_distance_generic_riemann(): """Test riemannian distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert_equal(distance(A, B, metric='riemann'), distance_riemann(A, B))
def make_rTNT_EIV(myfilename, chnames, ERP, centroids_List, bandpass=(1.0, 20.0), filtre_order=2, delta=0.6, target=[2], nontarget=[1]): """ Segment the signals in epochs of length delta after a marker. """ T = 0 NT = 1 myfile = pa.read_csv(myfilename, sep=',') if chnames is None: chnames = list( set(list(myfile.keys())) - set(['EVT', 'SamplingRate', 'Time', 'Target', 'NumTargetColumn'])) SamplingRate = myfile['SamplingRate'][0] if bandpass is not None: lowf, hif = bandpass signals = apply_bandpass_filter(myfile, lowf, hif, sampling_rate=SamplingRate, filtre_order=filtre_order, chnames=chnames) s = signals.set_index('Time')[chnames] # N = int(delta * myfile['SamplingRate'][0]) N = int(delta * SamplingRate) all_rTNT = [] all_labels = [] all_event = [] all_targets = [] # for t in markers[markers['Identifier'] in [self.target, self.nontarget]]['Time(s)']: for i, t in enumerate(myfile['Time']): if myfile['Target'][i] in target + nontarget: tmp = np.asarray(s.loc[t:t + delta]).T if tmp.shape[1] >= N: trial_cov = np.cov(np.concatenate([ERP, tmp[:, :N]], axis=0)) dist = [ distance(trial_cov, centroids_List[m]) for m in [T, NT] ] all_rTNT.append(np.log(dist[0] / dist[1])) all_event.append(myfile['EVT'][i]) if myfile['Target'][i] in target: all_labels.append(0) all_targets.append(myfile['NumTargetColumn'][i]) if myfile['Target'][i] in nontarget: all_labels.append(1) all_targets.append(myfile['NumTargetColumn'][i]) rTNT = np.array(all_rTNT) labels = np.array(all_labels) event = np.array(all_event) targets = np.array(all_targets) return rTNT, labels, event, targets
def test_distance_generic_euclid(): """Test euclidean distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert distance(A, B, metric='euclid') == distance_euclid(A, B)
# - Schaefer-Strimmer (SCH), # - oracle approximating shrunk (OAS) covariance, # - minimum covariance determinant (MCD), # - and others. # # We will compare the distance of LWF, OAS and SCH estimators with the # groundtruth, while increasing epoch length. estimators = ["lwf", "oas", "sch"] w_len = np.linspace(10, n_times, 20, dtype=int) dfd = list() for est in estimators: for wl in w_len: cov_est = Covariances(estimator=est).transform(X[:, :, :wl]) for k in range(n_matrices): dist = distance(cov_est[k], true_cov[k], metric="riemann") dfd.append(dict(estimator=est, wlen=wl, dist=dist)) dfd = pd.DataFrame(dfd) ############################################################################### fig, ax = plt.subplots(figsize=(6, 4)) ax.set(xscale="log") sns.lineplot(data=dfd, x="wlen", y="dist", hue="estimator", ax=ax) ax.set_title("Distance to groundtruth covariance matrix") ax.set_xlabel("Number of time samples") ax.set_ylabel(r"$\delta(\Sigma, \hat{\Sigma})$") plt.tight_layout() ############################################################################### # Choice of estimator for motor imagery data
def test_distance_generic_logdet(): """Test logdet distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert distance(A, B, metric='logdet') == distance_logdet(A, B)
def test_distance_generic_custom(): """Test custom distance for generic function""" A = 2 * np.eye(3) B = 2 * np.eye(3) assert_equal(distance(A, B, metric=distance_logeuclid), distance_logeuclid(A, B))
cross_subj.append({'X_train': X_train, 'y_train': y_train, 'pipelines': pipelines, 'mean': mean_covariance(mat[atf], metric='riemann', sample_weight=None)}) cov8 = load_data("Cov", 8, range(40), "test") cov9 = load_data("Cov", 8, range(40), "test") cross_subj.append({'X_train': np.array([i for i in range(40)]), 'pipelines': pipelines, 'mean': mean_covariance(cov8, metric='riemann', sample_weight=None)}) cross_subj.append({'X_train': np.array([i for i in range(40)]), 'pipelines': pipelines, 'mean': mean_covariance(cov9, metric='riemann', sample_weight=None)}) all_res = [] for target in trange(8,10): best = np.argmin(np.array([distance(cross_subj[source]['mean'], cross_subj[target]['mean'], metric='riemann') for source in range(8) if source != target])) yens = cross_subj[best]['pipelines']['Ensemble'].predict(cross_subj[target]['X_train']) yens = le.inverse_transform(yens) for i, yp in enumerate(yens): res = {"subject name": "P{:02d}".format(target+1), "trial index": i+1, "prediction": yp} all_res.append(res) df_pred_cross = pd.DataFrame(all_res) # Create a Pandas Excel writer using XlsxWriter as the engine. writer = pd.ExcelWriter('results-cross.xlsx', engine='xlsxwriter') # Convert the dataframe to an XlsxWriter Excel object. for s in df_pred_cross['subject name'].unique():
def generic_test_loop(data, labels, event, ERP, Centroids_list, mu_TNT, sigma_TNT, nb_repetitions, column_number=12, items_list=[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' ], visu=False, flashmode='Splotch'): # nb_repetitions = data.shape[0]/(column_number*nb_targets) T = 0 NT = 1 items_vec = np.array(items_list) item_prediction = [] Max_indice = data.shape[0] J = column_number * nb_repetitions indice_flash = 0 indice_char = 0 nb_rep = 0 item_selected_list = [] r_TNT_test = [] train_NaiveBayes = R_TNT_NaiveBayes(targets=items_list, mu_TNT=mu_TNT, sigma_TNT=sigma_TNT, class_prior=None) # Debut de l'inference while indice_flash < Max_indice: # Get the r_TNT of the current trial x_test = data[indice_flash, :, :] X_test = np.cov(np.concatenate([ERP, x_test], axis=0)) r_TNT = np.log(distance(X_test, Centroids_list[T])) - np.log( distance(X_test, Centroids_list[NT])) r_TNT_test.append(r_TNT) # Update the bayes_prior (vector of length 36) if flashmode == 'RoCo': screen = np.reshape(items_vec, [6, 6]) flashed_item = rtp_indexColumn2Targets( Screen=screen, IndexColumn=event[indice_flash]) flashed_item_index = [ i for i, e in enumerate(items_list) if e in list(flashed_item) ] if flashmode == 'Splotch': SplotchMatrixNumber = int( (indice_flash - indice_char * 12 * nb_repetitions) / 12) + 1 flashed_item = rtp_indexSplotch2Targets( SplotchMatrixNumber=SplotchMatrixNumber, Indexplotch=event[indice_flash], items_vec=items_vec) flashed_item_index = [ i for i, e in enumerate(items_list) if e in list(flashed_item) ] if flashmode == 'EIV': flashed_item_index = [event[indice_flash] - 1] items_posterior_array = train_NaiveBayes.update_class_prior( r_TNT, flashed_item_index) item_selected = items_list[np.argmax(items_posterior_array)] item_selected_list.append(item_selected) # Ask if it's flashed_items_total_number is enough to reset class_prior or to take a decision and change of target indice_flash += 1 if not indice_flash % column_number: nb_rep += 1 if visu: print item_selected if not indice_flash % J: indice_char += 1 item_prediction.append(item_selected) train_NaiveBayes.reset_bayes_prior() if flashmode in ['Splotch', 'RoCo']: temp = np.matrix(item_selected_list) I = temp.shape[1] / J else: temp = np.array(item_selected_list) I = temp.shape[0] / J item_selected_mat = temp.reshape([I, J]) w = find_target_word(e=event, y=labels, nb_repetitions=nb_repetitions, items_vec=items_vec, flashmode=flashmode) if flashmode in ['Splotch', 'RoCo']: target_vec = np.matrix(w.tolist()) else: target_vec = w k = 0 for j in range(J): item_comparison = np.transpose(target_vec) == item_selected_mat[:, j] item_comparison = item_comparison.astype('float') if k == 0: A = item_comparison k = 1 else: A = np.vstack([A, item_comparison]) # A = A.reshape((I,J)) mean_accuracy = np.mean(A, axis=1) var_accuracy = np.std(A, axis=1) if visu: # Visualisation de la distribution des ERP tests visualisation_R_TNT(r_TNT=np.array(r_TNT_test), y=labels, T=1, NT=0, xlim=[-0.06, 0.06]) plt.figure() x = np.linspace(0, J, J) plt.plot(mean_accuracy) plt.fill_between(x, mean_accuracy - 0.5 * var_accuracy, mean_accuracy + 0.5 * var_accuracy, alpha=0.1) plt.ylim(0, 1) plt.xlim(0, J, J) plt.xlabel('#Flash') plt.ylabel('Mean accuracy') plt.title('Accuracy evolution with flashs ') plt.show() return mean_accuracy, var_accuracy