def test_make_correlated_xy(corr, size, tol, seed): out = datasets.make_correlated_xy(corr=corr, size=size, tol=tol, seed=seed) # ensure output is expected shape assert out.shape[1:] == size assert len(out) == len(corr) if hasattr(corr, '__len__') else 2 # check outputs are correlated within specified tolerance realcorr = np.corrcoef(out.reshape(len(out), -1)) if len(realcorr) == 2 and not hasattr(corr, '__len__'): realcorr = realcorr[0, 1] assert np.all(np.abs(realcorr - corr) < tol) # check that seed generates reproducible values duplicate = datasets.make_correlated_xy(corr=corr, size=size, tol=tol, seed=seed) assert np.allclose(out, duplicate)
def test_permtest_pearsonr(): np.random.seed(12345678) x, y = datasets.make_correlated_xy(corr=0.1, size=100) r, p = stats.permtest_pearsonr(x, y) assert np.allclose([r, p], [0.10032564626876286, 0.3046953046953047]) x, y = datasets.make_correlated_xy(corr=0.5, size=100) r, p = stats.permtest_pearsonr(x, y) assert np.allclose([r, p], [0.500040365781984, 0.000999000999000999]) z = x + np.random.normal(loc=1, size=100) r, p = stats.permtest_pearsonr(x, np.column_stack([y, z])) assert np.allclose(r, np.array([0.50004037, 0.25843187])) assert np.allclose(p, np.array([0.000999, 0.01098901])) a, b = datasets.make_correlated_xy(corr=0.9, size=100) r, p = stats.permtest_pearsonr(np.column_stack([x, a]), np.column_stack([y, b])) assert np.allclose(r, np.array([0.50004037, 0.89927523])) assert np.allclose(p, np.array([0.000999, 0.000999]))
def test_make_correlated_xy_errors(corr): with pytest.raises(ValueError): datasets.make_correlated_xy(corr)
=================================== This example shows how to perform "spin-tests" (a la Alexander-Bloch et al., 2018, NeuroImage) to assess whether two brain patterns are correlated above and beyond what would be expected from a spatially-autocorrelated null model. For the original MATLAB toolbox published alongside the paper by Alexander-Bloch and colleagues refer to https://github.com/spin-test/spin-test. """ ############################################################################### # First let's generate some randomly correlated data. We'll set a random seed # to make sure that things are reproducible: from netneurotools import datasets x, y = datasets.make_correlated_xy(size=68, seed=1234) ############################################################################### # We can correlate the resulting vectors to see how related they are: from scipy.stats import pearsonr r, p = pearsonr(x, y) print(r, p) ############################################################################### # The p-value suggests that our data are, indeed, highly correlated. # Unfortunately, when doing this sort of correlation with brain data the null # model used in generating the p-value does not take into account that the data # are constrained by a spatial toplogy (i.e., the brain) and thus spatially # auto-correlated. The p-values will be "inflated" because our true degrees of # freedom are less than the number of samples we have!
def matching_multinorm_grfs(corr, tol=0.005, *, alpha=3.0, normalize=True, seed=None, debug=False): """ Generates two surface GRFs (fsaverage5) that correlate at r = `corr` Starts by generating two random variables from a multivariate normal distribution with correlation `corr`, adds spatial autocorrelation with specified `alpha`, and projects to the surface. Continues this procedure until two variables are generated that have correlation `corr` on the surface. Parameters ---------- corr : float Desired correlation of generated GRFs tol : float Tolerance for correlation between generated GRFs alpha : float (positive), optional Exponent of the power-law distribution. Only used if `use_gstools` is set to False. Default: 3.0 normalize : bool, optional Whether to normalize the returned field to unit variance. Default: True seed : None, int, default_rng, optional Random state to seed GRF generation. Default: None debug : bool, optional Whether to print debug info Return ------ x, y : (20484,) np.ndarray Generated surface GRFs """ rs = np.random.default_rng(seed) acorr, n = np.inf, 0 while np.abs(np.abs(acorr) - corr) > tol: if alpha > 0: x, y = make_correlated_xy(corr, size=902629, seed=rs.integers(MSEED)) # smooth correlated noise vectors + project to surface xs = create_surface_grf(noise=x, alpha=alpha, normalize=normalize) ys = create_surface_grf(noise=y, alpha=alpha, normalize=normalize) else: xs, ys = make_correlated_xy(corr, size=20484, seed=rs.integers(MSEED)) # remove medial wall to ensure data are still sufficiently correlated. # this is important for parcellations that will ignore the medial wall xs, ys = _mod_medial(xs, remove=True), _mod_medial(ys, remove=True) acorr = np.corrcoef(xs, ys)[0, 1] if debug: # n:>3 because dear lord i hope it doesn't take more than 999 tries print(f'{n:>3}: {acorr:>6.3f}') n += 1 if acorr < 0: ys *= -1 if normalize: xs, ys = sstats.zscore(xs), sstats.zscore(ys) return _mod_medial(xs, remove=False), _mod_medial(ys, remove=False)
np.random.normal(scale=0.2, size=500)) print(nnstats.permtest_rel(rvs1, rvs3)) ############################################################################### # Permutation tests for correlations # ---------------------------------- # # Sometimes rather than assessing differences in means we want to assess the # strength of a relationship between two variables. While we might normally do # this with a Pearson (or Spearman) correlation, we can assess the significance # of this relationship via permutation tests. # # First, we'll generate two correlated variables: from netneurotools import datasets x, y = datasets.make_correlated_xy(corr=0.2, size=100) ############################################################################### # We can generate the Pearson correlation with the standard parametric p-value: print(stats.pearsonr(x, y)) ############################################################################### # Or use permutation testing to derive the p-value: print(nnstats.permtest_pearsonr(x, y)) ############################################################################### # All the same arguments as with :func:`~.permtest_1samp` and # :func:`~.permtest_rel` apply here, so you can provide same-sized arrays and # correlations will only be calculated for paired columns: