def predict(self, x_test, y_test): y_predict = np.zeros_like(y_test) # shape = (n_sample, n_unit) corrs = [] # list of pearson correlations for each unit max_corr = 0 max_corr_unit = 0 for i in range(self.n_unit): true_features = y_test[:, i] model = self.models[i] unit_status = 'valid' if model != 0 else 'invalid*****' # print(f'start predicting on unit {i} ({unit_status})') # feature prediction if unit_status != 'valid': # SLR failed in this unit prediction = np.zeros(true_features.shape) else: x_test_subset = x_test[:, self.subset_indices[i]] x_test_subset = add_bias(x_test_subset, axis=1) prediction = model.predict(x_test_subset) mu, std = self.normal_terms[i] prediction = prediction * std + mu # de-normalize corr, p_value = stats.pearsonr(prediction, true_features) corr = 0 if np.isnan(corr) else corr if corr > max_corr: max_corr = corr max_corr_unit = i corrs.append(corr) y_predict[:, i] = prediction return y_predict, corrs, max_corr_unit
def test_add_bias_invalidaxis(self): '''Exception test of bdpy.ml.regress.add_bias (invalid input in 'axis')''' x = np.array([[100, 110, 120], [200, 210, 220]]) self.assertRaises(ValueError, lambda: ml.add_bias(x, axis=-1))
def test_add_bias_axiszero(self): '''Test of bdpy.ml.regress.add_bias (axis=0)''' x = np.array([[100, 110, 120], [200, 210, 220]]) exp_y = np.array([[100, 110, 120], [200, 210, 220], [1, 1, 1]]) test_y = ml.add_bias(x, axis=0) np.testing.assert_array_equal(test_y, exp_y)
def fit(self, x_train, y_train): self.x_train = x_train self.y_train = y_train self.n_unit = y_train.shape[1] # normalize mri data x (along each voxel) mu = np.mean(self.x_train, axis=0) std = np.std(self.x_train, axis=0, ddof=1) std[std == 0] = 1 self.x_train = (self.x_train - mu) / std # for each feature unit train a sparse linear regression for i in range(self.n_unit): feature_unit = self.y_train[:, i] print(f'start training on unit {i}') # normalize image features y (along each unit) # this must be done separately because we need to de-normalize later mu = np.mean(feature_unit, axis=0) std = np.std(feature_unit, axis=0, ddof=1) std = 1 if std == 0 else std feature_unit = (feature_unit - mu) / std self.normal_terms.append((mu, std)) # voxel selection, select the top `n_voxel` voxels with highest correlations # corr = corrcoef(feature_unit, x_train, var='col') corr = corr2_coeff(feature_unit.reshape((-1, 1)).T, x_train.T).ravel() corr[np.isnan(corr)] = 0 # mark np.nan values as 0 contribution x_train_subset, subset_index = select_top(x_train, np.abs(corr), self.n_voxel, axis=1, verbose=False) # add bias terms x_train_subset = add_bias(x_train_subset, axis=1) # set up the model model = SparseLinearRegression(n_iter=self.n_iter, prune_mode=1) # model = LinearRegression() # train model parameters try: model.fit(x_train_subset, feature_unit) self.models.append(model) self.subset_indices.append(subset_index) except: self.models.append(0) self.subset_indices.append(0)
def predict_feature_unit(analysis): '''Run feature prediction for each unit Parameters ---------- analysis : dict Analysis parameters. This contains the following items: - subject - roi - num_voxel - feature - unit - num_test_category - ardreg_num_itr Returns ------- dict Results dictionary. This contains the following items: - subject - roi - feature - unit - predict_percept - predict_imagery - predict_percept_ave - predict_imagery_ave ''' ## Set analysis parameters ------------- num_voxel = analysis['num_voxel'] unit = analysis['unit'] nitr = analysis['ardreg_num_itr'] print 'Unit %d' % unit ## Get data ---------------------------- ## Get brain data for training, test (perception), and test (imagery) ind_tr = data_type == 1 ind_te_p = data_type == 2 ind_te_i = data_type == 3 data_train = data[ind_tr, :] data_test_percept = data[ind_te_p, :] data_test_imagery = data[ind_te_i, :] label_train = data_label[ind_tr] label_test_percept = data_label[ind_te_p] label_test_imagery = data_label[ind_te_i] ## Get image features for training ind_feat_tr = feature_type == 1 feature_train = feature[ind_feat_tr, unit - 1] feature_label_train = feature_label[ind_feat_tr] ## Match training features to labels feature_train = bdpy.get_refdata(feature_train, feature_label_train, label_train) ## Preprocessing ----------------------- ## Normalize data data_train_mean = np.mean(data_train, axis=0) data_train_std = np.std(data_train, axis=0, ddof=1) data_train_norm = (data_train - data_train_mean) / data_train_std data_test_percept_norm = (data_test_percept - data_train_mean) / data_train_std data_test_imagery_norm = (data_test_imagery - data_train_mean) / data_train_std feature_train_mean = np.mean(feature_train, axis=0) feature_train_std = np.std(feature_train, axis=0, ddof=1) if feature_train_std == 0: feature_train_norm = feature_train - feature_train_mean else: feature_train_norm = (feature_train - feature_train_mean) / feature_train_std ## Voxel selection based on correlation corr = corrcoef(feature_train_norm, data_train_norm, var='col') data_train_norm, select_ind = select_top(data_train_norm, np.abs(corr), num_voxel, axis=1, verbose=False) data_test_percept_norm = data_test_percept_norm[:, select_ind] data_test_imagery_norm = data_test_imagery_norm[:, select_ind] ## Add bias term data_train_norm = add_bias(data_train_norm, axis=1) data_test_percept_norm = add_bias(data_test_percept_norm, axis=1) data_test_imagery_norm = add_bias(data_test_imagery_norm, axis=1) ## Decoding ---------------------------- if feature_train_std == 0: predict_percept_norm = np.zeros(data_test_percept.shape[0], feature_train_norm[1]) predict_imagery_norm = np.zeros(data_test_imagery.shape[0], feature_train_norm[1]) else: try: model = SparseLinearRegression(n_iter=nitr, prune_mode=1) ## Model training #import pdb; pdb.set_trace() model.fit(data_train_norm, feature_train_norm) except: model = SparseLinearRegression(n_iter=75, prune_mode=1) ## Model training # import pdb; pdb.set_trace() model.fit(data_train_norm, feature_train_norm) ## Image feature preiction (percept & imagery) predict_percept_norm = model.predict(data_test_percept_norm) predict_imagery_norm = model.predict(data_test_imagery_norm) # De-normalize predicted features predict_percept = predict_percept_norm * feature_train_std + feature_train_mean predict_imagery = predict_imagery_norm * feature_train_std + feature_train_mean ## Average prediction results for each test category # [Note] # Image IDs (labels) is '<category_id>.<image_id>' # (e.g., '123456.7891011' is 'image 7891011 in category 123456'). # Thus, the integer part of `label` represents the category ID. cat_te_p = np.floor(label_test_percept) cat_te_i = np.floor(label_test_imagery) category_test_percept = sorted(set(cat_te_p)) category_test_imagery = sorted(set(cat_te_i)) predict_percept_ave = [ np.mean(predict_percept[cat_te_p == i]) for i in category_test_percept ] predict_imagery_ave = [ np.mean(predict_imagery[cat_te_i == i]) for i in category_test_imagery ] #import pdb; pdb.set_trace() ## Return results return { 'subject': analysis['subject'], 'roi': analysis['roi'], 'feature': analysis['feature'], 'unit': unit, 'predict_percept': predict_percept, 'predict_imagery': predict_imagery, 'predict_percept_catave': predict_percept_ave, 'predict_imagery_catave': predict_imagery_ave, 'category_test_percept': category_test_percept, 'category_test_imagery': category_test_imagery }
def feature_prediction(x_train, y_train, x_test, y_test, n_voxel=500, n_iter=200): '''Run feature prediction Parameters ---------- x_train, y_train : array_like [shape = (n_sample, n_voxel)] Brain data and image features for training x_test, y_test : array_like [shape = (n_sample, n_unit)] Brain data and image features for test n_voxel : int The number of voxels n_iter : int The number of iterations Returns ------- predicted_label : array_like [shape = (n_sample, n_unit)] Predicted features ture_label : array_like [shape = (n_sample, n_unit)] True features in test data ''' n_unit = y_train.shape[1] # Normalize brian data (x) norm_mean_x = np.mean(x_train, axis=0) norm_scale_x = np.std(x_train, axis=0, ddof=1) x_train = (x_train - norm_mean_x) / norm_scale_x x_test = (x_test - norm_mean_x) / norm_scale_x # Feature prediction for each unit print('Running feature prediction') y_true_list = [] y_pred_list = [] for i in range(n_unit): print('Unit %03d' % (i + 1)) start_time = time() # Get unit features y_train_unit = y_train[:, i] y_test_unit = y_test[:, i] # Normalize image features for training (y_train_unit) norm_mean_y = np.mean(y_train_unit, axis=0) std_y = np.std(y_train_unit, axis=0, ddof=1) norm_scale_y = 1 if std_y == 0 else std_y y_train_unit = (y_train_unit - norm_mean_y) / norm_scale_y # Voxel selection corr = corrcoef(y_train_unit, x_train, var='col') x_train_unit, voxel_index = select_top(x_train, np.abs(corr), n_voxel, axis=1, verbose=False) x_test_unit = x_test[:, voxel_index] # Add bias terms x_train_unit = add_bias(x_train_unit, axis=1) x_test_unit = add_bias(x_test_unit, axis=1) # Setup regression # For quick demo, use linaer regression model = LinearRegression() #model = SparseLinearRegression(n_iter=n_iter, prune_mode=1) # Training and test try: model.fit(x_train_unit, y_train_unit) # Training y_pred = model.predict(x_test_unit) # Test except: # When SLiR failed, returns zero-filled array as predicted features y_pred = np.zeros(y_test_unit.shape) # Denormalize predicted features y_pred = y_pred * norm_scale_y + norm_mean_y y_true_list.append(y_test_unit) y_pred_list.append(y_pred) print('Time: %.3f sec' % (time() - start_time)) # Create numpy arrays for return values y_predicted = np.vstack(y_pred_list).T y_true = np.vstack(y_true_list).T return y_predicted, y_true