def test_eval_bootstrap(self): from pyrsa.inference import eval_bootstrap from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed rdms = RDMs(np.random.rand(11, 10)) # 11 5x5 rdms m = ModelFixed('test', rdms.get_vectors()[0]) value = eval_bootstrap(m, rdms, N=10)
def __init__(self, name, rdm): """ Fixed model This is a parameter-free model that simply predicts a fixed RDM It takes rdm object, a vector or a matrix as input to define the RDM Args: Name(String): Model name rdm(pyrsa.rdm.RDMs): rdms in one object """ Model.__init__(self, name) if isinstance(rdm, RDMs): self.rdm_obj = rdm self.rdm = np.mean(rdm.get_vectors(), axis=0) self.n_cond = rdm.n_cond elif rdm.ndim == 1: # User passed a vector self.rdm_obj = RDMs(np.array([rdm])) self.n_cond = (1 + np.sqrt(1 + 8 * rdm.size)) / 2 if self.n_cond % 1 != 0: raise NameError( "RDM vector needs to have size of ncond*(ncond-1)/2") self.rdm = rdm else: # User passed a matrix self.rdm_obj = RDMs(np.array([rdm])) self.rdm = batch_to_vectors(np.array([rdm]))[0] self.n_cond = self.rdm_obj.n_cond self.n_param = 0 self.default_fitter = fit_mock self.rdm_obj.pattern_descriptors['index'] = np.arange(self.n_cond)
def test_crossval(self): from pyrsa.inference import crossval from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed dis = np.random.rand(11, 10) # 11 5x5 rdms mes = "Euclidean" des = {'subj': 0} rdm_des = {'session': np.array([0, 1, 2, 2, 4, 5, 6, 7, 7, 7, 7])} pattern_des = {'type': np.array([0, 1, 2, 2, 4])} rdms = RDMs(dissimilarities=dis, rdm_descriptors=rdm_des, pattern_descriptors=pattern_des, dissimilarity_measure=mes, descriptors=des) m = ModelFixed('test', rdms[0]) train_set = [ (rdms.subset_pattern('type', [0, 1]), np.array([0, 1])), (rdms.subset_pattern('type', [0, 4]), np.array([0, 4])), ] test_set = [ (rdms.subset_pattern('type', [2, 4]), np.array([2, 4])), (rdms.subset_pattern('type', [1, 2]), np.array([1, 2])), ] ceil_set = [ (rdms.subset_pattern('type', [2, 4]), np.array([2, 4])), (rdms.subset_pattern('type', [1, 2]), np.array([1, 2])), ] crossval(m, rdms, train_set, test_set, ceil_set, pattern_descriptor='type')
def test_eval_bootstrap(self): from pyrsa.inference import eval_bootstrap from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed rdms = RDMs(np.random.rand(11, 10)) # 11 5x5 rdms m = ModelFixed('test', rdms.get_vectors()[0]) m2 = ModelFixed('test2', rdms.get_vectors()[1]) result = eval_bootstrap([m, m2], rdms, N=10) assert result.evaluations.shape[1] == 2 assert result.evaluations.shape[0] == 10
def test_fit(self): from pyrsa.rdm import RDMs rdm = np.random.rand(2, 6) pattern_descriptors = {'test': ['a', 'b', 'c', 'd']} rdm_descriptors = {'ind': np.array([1, 2])} rdm_obj = RDMs(rdm, dissimilarity_measure='euclid', pattern_descriptors=pattern_descriptors, rdm_descriptors=rdm_descriptors) m = model.ModelWeighted('Test Model', rdm_obj) train = rdm_obj.subset('ind', 2) theta = m.fit(train)
def test_bootstrap_testset_rdm(self): from pyrsa.inference import bootstrap_testset_rdm from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed rdms = RDMs(np.random.rand(11, 10)) # 11 5x5 rdms m = ModelFixed('test', rdms.get_vectors()[0]) evaluations, n_rdms = bootstrap_testset_rdm(m, rdms, method='cosine', fitter=None, N=100, rdm_descriptor=None)
def test_fit(self): from pyrsa.rdm import RDMs rdm = np.random.rand(5, 15) pattern_descriptors = {'test': ['a', 'b', 'c', 'd', 'e', 'f']} rdm_descriptors = {'ind': np.array([1, 2, 3, 1, 2])} rdm_obj = RDMs(rdm, dissimilarity_measure='euclid', pattern_descriptors=pattern_descriptors, rdm_descriptors=rdm_descriptors) m = model.ModelInterpolate('Test Model', rdm_obj) train = rdm_obj.subset('ind', 2) theta = m.fit(train) pre = m.predict(theta)
def test_bootstrap_testset_pattern(self): from pyrsa.inference import bootstrap_testset_pattern from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed rdms = RDMs(np.random.rand(11, 10)) # 11 5x5 rdms m = ModelFixed('test', rdms.get_vectors()[0]) m2 = ModelFixed('test2', rdms.get_vectors()[1]) evaluations, n_cond = bootstrap_testset_pattern( [m, m2], rdms, method='cosine', fitter=None, N=100, pattern_descriptor=None)
def test_sort_by(self): from pyrsa.rdm import RDMs rdm = np.array([[0., 1., 2., 3.], [1., 0., 1., 2.], [2., 1., 0., 1.], [3., 2., 1., 0.]]) conds = ['b', 'a', 'c', 'd'] rdms = RDMs(np.atleast_2d(squareform(rdm)), pattern_descriptors=dict(conds=conds)) rdms.sort_by(conds='alpha') new_order = np.argsort(conds) rdm_reordered = rdm[np.ix_(new_order, new_order)] assert_array_equal(np.atleast_2d(squareform(rdm_reordered)), rdms.dissimilarities) assert_array_equal(sorted(conds), rdms.pattern_descriptors.get('conds'))
def test_reorder(self): from pyrsa.rdm import RDMs rdm = np.array([[0., 1., 2., 3.], [1., 0., 1., 2.], [2., 1., 0., 1.], [3., 2., 1., 0.]]) conds = ['a', 'b', 'c', 'd'] rdms = RDMs(np.atleast_2d(squareform(rdm)), pattern_descriptors=dict(conds=conds)) conds_ordered = ['b', 'a', 'c', 'd'] new_order = [conds.index(cond_idx) for cond_idx in conds_ordered] rdm_reordered = rdm[np.ix_(new_order, new_order)] rdms.reorder(new_order) assert_array_equal(np.atleast_2d(squareform(rdm_reordered)), rdms.dissimilarities) assert_array_equal(conds_ordered, rdms.pattern_descriptors.get('conds'))
def test_bootstrap_crossval_k1(self): from pyrsa.inference import bootstrap_crossval from pyrsa.rdm import RDMs from pyrsa.model import ModelFixed dis = np.random.rand(11, 45) # 11 10x10 rdms mes = "Euclidean" des = {'subj': 0} rdm_des = {'session': np.array([0, 1, 2, 2, 4, 5, 6, 7, 7, 7, 7])} pattern_des = {'type': np.array([0, 1, 2, 2, 4, 5, 5, 5, 6, 7])} rdms = RDMs(dissimilarities=dis, rdm_descriptors=rdm_des, pattern_descriptors=pattern_des, dissimilarity_measure=mes, descriptors=des) m = ModelFixed('test', rdms[0]) bootstrap_crossval(m, rdms, N=10, k_rdm=1, k_pattern=2, pattern_descriptor='type', rdm_descriptor='session') bootstrap_crossval(m, rdms, N=10, k_rdm=2, k_pattern=1, pattern_descriptor='type', rdm_descriptor='session')
def test_bootstrap_sample_pattern(self): from pyrsa.inference import bootstrap_sample_pattern from pyrsa.rdm import RDMs rdms = RDMs(np.random.rand(11, 10)) # 11 5x5 rdms rdm_sample = bootstrap_sample_pattern(rdms) assert rdm_sample[0].n_cond == 5 assert rdm_sample[0].n_rdm == 11
def pool_rdm(rdms, method='cosine', sigma_k=None): """pools multiple RDMs into the one with maximal performance under a given evaluation metric rdm_descriptors of the generated rdms are empty Args: rdms (pyrsa.rdm.RDMs): RDMs to be pooled method : String, optional Which comparison method to optimize for. The default is 'cosine'. Returns: pyrsa.rdm.RDMs: the pooled RDM, i.e. a RDM with maximal performance under the chosen method """ rdm_vec = rdms.get_vectors() if method == 'euclid': rdm_vec = _nan_mean(rdm_vec) elif method == 'cosine': rdm_vec = rdm_vec / np.sqrt( np.nanmean(rdm_vec**2, axis=1, keepdims=True)) rdm_vec = _nan_mean(rdm_vec) elif method == 'corr': rdm_vec = rdm_vec - np.nanmean(rdm_vec, axis=1, keepdims=True) rdm_vec = rdm_vec / np.nanstd(rdm_vec, axis=1, keepdims=True) rdm_vec = _nan_mean(rdm_vec) rdm_vec = rdm_vec - np.nanmin(rdm_vec) elif method == 'cosine_cov': rdm_vec = rdm_vec / np.sqrt( np.nanmean(rdm_vec**2, axis=1, keepdims=True)) rdm_vec = _nan_mean(rdm_vec) elif method == 'corr_cov': rdm_vec = rdm_vec - np.nanmean(rdm_vec, axis=1, keepdims=True) rdm_vec = rdm_vec / np.nanstd(rdm_vec, axis=1, keepdims=True) rdm_vec = _nan_mean(rdm_vec) rdm_vec = rdm_vec - np.nanmin(rdm_vec) elif method == 'spearman' or method == 'rho-a': rdm_vec = np.array([_nan_rank_data(v) for v in rdm_vec]) rdm_vec = _nan_mean(rdm_vec) elif method == 'rho-a': rdm_vec = np.array([_nan_rank_data(v) for v in rdm_vec]) rdm_vec = _nan_mean(rdm_vec) elif method == 'kendall' or method == 'tau-b': Warning('Noise ceiling for tau based on averaged ranks!') rdm_vec = np.array([_nan_rank_data(v) for v in rdm_vec]) rdm_vec = _nan_mean(rdm_vec) elif method == 'tau-a': Warning('Noise ceiling for tau based on averaged ranks!') rdm_vec = np.array([_nan_rank_data(v) for v in rdm_vec]) rdm_vec = _nan_mean(rdm_vec) else: raise ValueError('Unknown RDM comparison method requested!') return RDMs(rdm_vec, dissimilarity_measure=rdms.dissimilarity_measure, descriptors=rdms.descriptors, rdm_descriptors=None, pattern_descriptors=rdms.pattern_descriptors)
def __init__(self, name, rdm): Model.__init__(self, name) if isinstance(rdm, RDMs): self.rdm_obj = rdm self.rdm = rdm.get_vectors() elif rdm.ndim == 2: # User supplied vectors self.rdm_obj = RDMs(rdm) self.n_cond = (1 + np.sqrt(1 + 8 * rdm.shape[1])) / 2 if self.n_cond % 1 != 0: raise NameError( "RDM vector needs to have size of ncond*(ncond-1)/2") self.rdm = rdm else: # User passed matrixes self.rdm_obj = RDMs(rdm) self.rdm = batch_to_vectors(rdm) self.n_param = self.rdm_obj.n_rdm self.n_rdm = self.rdm_obj.n_rdm self.default_fitter = fit_interpolate
def test_creation_rdm(self): from pyrsa.rdm import RDMs rdm = np.array(np.ones(6)) rdm_obj = RDMs(np.array([rdm])) m = model.ModelFixed('Test Model', rdm_obj) m.fit(rdm_obj) pred = m.predict() assert np.all(pred == rdm) pred_obj = m.predict_rdm() assert isinstance(pred_obj, RDMs)
def test_boot_noise_ceiling_runs_for_method(self, method): from pyrsa.inference import boot_noise_ceiling from pyrsa.rdm import RDMs dis = np.random.rand(11, 10) # 11 5x5 rdms mes = "Euclidean" des = {'subj': 0} rdm_des = {'session': np.array([1, 1, 2, 2, 4, 5, 6, 7, 7, 7, 7])} pattern_des = {'type': np.array([0, 1, 2, 2, 4])} rdms = RDMs(dissimilarities=dis, rdm_descriptors=rdm_des, pattern_descriptors=pattern_des, dissimilarity_measure=mes, descriptors=des) _, _ = boot_noise_ceiling(rdms, method=method)
def test_creation_rdm(self): from pyrsa.rdm import RDMs rdm = np.random.rand(2, 6) pattern_descriptors = {'test': ['a', 'b', 'c', 'd']} rdm_obj = RDMs(rdm, dissimilarity_measure='euclid', pattern_descriptors=pattern_descriptors) m = model.ModelWeighted('Test Model', rdm_obj) pred = m.predict(np.array([1, 0])) assert np.all(pred == rdm[0]) pred_obj = m.predict_rdm() assert isinstance(pred_obj, RDMs) assert pred_obj.n_rdm == 1 assert pred_obj.pattern_descriptors == pattern_descriptors
def test_bootstrap_sample_pattern_descriptors(self): from pyrsa.inference import bootstrap_sample_pattern from pyrsa.rdm import RDMs dis = np.random.rand(11, 10) # 11 5x5 rdms mes = "Euclidean" des = {'subj': 0} rdm_des = {'session': np.array([0, 1, 2, 2, 4, 5, 6, 7, 7, 7, 7])} pattern_des = {'type': np.array([0, 1, 2, 2, 4])} rdms = RDMs(dissimilarities=dis, rdm_descriptors=rdm_des, pattern_descriptors=pattern_des, dissimilarity_measure=mes, descriptors=des) rdm_sample = bootstrap_sample_pattern(rdms, 'type')
def test_cv_noise_ceiling(self): from pyrsa.inference import cv_noise_ceiling from pyrsa.inference import sets_k_fold_rdm from pyrsa.rdm import RDMs dis = np.random.rand(11, 10) # 11 5x5 rdms mes = "Euclidean" des = {'subj': 0} rdm_des = {'session': np.array([1, 1, 2, 2, 4, 5, 6, 7, 7, 7, 7])} pattern_des = {'type': np.array([0, 1, 2, 2, 4])} rdms = RDMs(dissimilarities=dis, rdm_descriptors=rdm_des, pattern_descriptors=pattern_des, dissimilarity_measure=mes, descriptors=des) _, test_set, ceil_set = sets_k_fold_rdm(rdms, k_rdm=3, random=False) _, _ = cv_noise_ceiling(rdms, ceil_set, test_set, method='cosine')
def predict_rdm(self, theta=None): """ Returns the predicted rdm vector For the fixed model there are no parameters. Args: theta(numpy.ndarray): the model parameter vector (one dimensional) Returns: pyrsa.rdm.RDMs: rdm object """ if theta is None: theta = np.ones(self.n_rdm) theta = np.maximum(theta, 0) theta = np.array(theta) dissimilarities = np.matmul(self.rdm.T, theta.reshape(-1)) rdms = RDMs(dissimilarities.reshape(1, -1), dissimilarity_measure=self.rdm_obj.dissimilarity_measure, descriptors=self.rdm_obj.descriptors, pattern_descriptors=self.rdm_obj.pattern_descriptors) return rdms
def test_save_load_result(self): from pyrsa.rdm import RDMs from pyrsa.inference import Result from pyrsa.inference import load_results from pyrsa.model import ModelFixed import io rdm = RDMs(np.random.rand(10), pattern_descriptors={ 'test': ['test1', 'test1', 'test1', 'test3', 'test'] }) m1 = ModelFixed('test1', rdm) m2 = ModelFixed('test2', np.random.rand(10)) models = [m1, m2] evaluations = np.random.rand(100, 2) method = 'test_method' cv_method = 'test_cv_method' noise_ceiling = np.array([0.5, 0.2]) res = Result(models, evaluations, method, cv_method, noise_ceiling) f = io.BytesIO() # Essentially a Mock file res.save(f, file_type='hdf5') res_loaded = load_results(f, file_type='hdf5') assert res_loaded.method == method assert res_loaded.cv_method == cv_method assert np.all(res_loaded.evaluations == evaluations)
def test_Icon_from_rdm(self): from pyrsa.vis import Icon from pyrsa.rdm import RDMs rdm = RDMs(np.random.rand(1, 190)) ic = Icon(rdm) self.assertEqual(ic.final_image.size[0], 100)
def get_searchlight_RDMs(data_2d, centers, neighbors, events, method='correlation', verbose=True): """Iterates over all the searchlight centers and calculates the RDM Args: data_2d (2D numpy array): brain data, shape n_observations x n_channels (i.e. voxels/vertices) centers (1D numpy array): center indices for all searchlights as provided by pyrsa.util.searchlight.get_volume_searchlight neighbors (list): list of lists with neighbor voxel indices for all searchlights as provided by pyrsa.util.searchlight.get_volume_searchlight events (1D numpy array): 1D array of length n_observations method (str, optional): distance metric, see pyrsa.rdm.calc for options. Defaults to 'correlation'. verbose (bool, optional): Defaults to True. Returns: RDM [pyrsa.rdm.RDMs]: RDMs object with the RDM for each searchlight the RDM.rdm_descriptors['voxel_index'] describes the center voxel index each RDM is associated with """ data_2d, centers = np.array(data_2d), np.array(centers) n_centers = centers.shape[0] # For memory reasons, we chunk the data if we have more than 1000 RDMs if n_centers > 1000: # we can't run all centers at once, that will take too much memory # so lets to some chunking chunked_center = np.split(np.arange(n_centers), np.linspace(0, n_centers, 101, dtype=int)[1:-1]) # loop over chunks n_conds = len(np.unique(events)) RDM = np.zeros((n_centers, n_conds * (n_conds - 1) // 2)) for chunks in tqdm(chunked_center, desc='Calculating RDMs...'): center_data = [] for c in chunks: # grab this center and neighbors center = centers[c] center_neighbors = neighbors[c] # create a database object with this data ds = Dataset(data_2d[:, center_neighbors], descriptors={'center': center}, obs_descriptors={'events': events}, channel_descriptors={'voxels': center_neighbors}) center_data.append(ds) RDM_corr = calc_rdm(center_data, method=method, descriptor='events') RDM[chunk, :] = RDM_corr.dissimilarities else: center_data = [] for c in range(n_centers): # grab this center and neighbors center = centers[c] nb = neighbors[c] # create a database object with this data ds = Dataset(data_2d[:, nb], descriptors={'center': c}, obs_descriptors={'events': events}, channel_descriptors={'voxels': nb}) center_data.append(ds) # calculate RDMs for each database object RDM = calc_rdm(center_data, method=method, descriptor='events').dissimilarities SL_rdms = RDMs(RDM, rdm_descriptors={'voxel_index': centers}, dissimilarity_measure=method) return SL_rdms