mne.stats.cluster_test#
- mne.stats.cluster_test(df, formula, *, within_id=None, reference=None, stat_fun=None, tail=0, threshold=None, n_permutations=1024, adjacency='auto', max_step=1, exclude=None, step_down_p=0.0, t_power=1.0, check_disjoint=False, out_type='indices', rng=None, buffer_size=None, n_jobs=1, verbose=None)[source]#
Run a cluster permutation test from a DataFrame and a formula.
- Parameters:
- df
pandas.DataFrame Dataframe containing the data, dependent and independent variables.
- formula
str Wilkinson notation formula naming the dependent variable and either a single independent variable (e.g.
"data ~ condition") or a single interaction term between two or more independent variables (e.g."data ~ a:b", tested with a repeated-measures ANOVA; seewithin_id). All names must match columns indf. Testing several effects (e.g. two main effects, or a main effect and an interaction) requires callingcluster_test()once per effect.- within_id
None|str Name of column in
dfto use in identifying within-group contrasts.- If
within_idis notNone: within_idmust match a column name indf, e.g."subject_index"(a name not indf.columnswill result in an error). If the independent variable has 1 level per participant, the data will be treated as already subtracted (e.g., condition A - condition B) and a paired t-test against zero will be performed (usingmne.stats.ttest_1samp_no_p()). If the independent variable has 2 levels, the data will be subtracted for each participant (e.g., condition A - condition B) first. If it has more than 2 levels, a one-way repeated-measures ANOVA is performed (usingmne.stats.f_mway_rm()), with permutations swapping each subject’s observations across the levels (never across subjects).
- If
- If
within_idisNone: Will perform a between-group test (using
mne.stats.f_oneway(); This works for 2 levels or more).
- If
- This parameter is required if:
formula’s right-hand side is an interaction term (e.g."data ~ a:b"), in which case each combination ofwithin_idand the factors must appear exactly once (a fully balanced repeated-measures design).
- reference
str|None Level of the independent variable to treat as the reference, i.e. the level that is subtracted. The test statistic is then computed on
other_level - reference, so positive values mean the other level is larger. Only valid for paired two-level contrasts (a single factor with 2 levels, withwithin_idgiven); for F-tests and repeated-measures ANOVAs the statistic is sign-invariant and passingreferenceraises an error. IfNone(default), levels are taken in sorted order (or in category order if the column is apandas.Categorical) and the second one is the reference.- stat_fun
callable()|None Function called to calculate the test statistic. Must accept 1D-array as input and return a 1D array. If
None(the default), usesmne.stats.ttest_1samp_no_p()for paired tests andmne.stats.f_oneway()for unpaired tests or tests of more than 2 groups..- tail
int If tail is 1, the statistic is thresholded above threshold. If tail is -1, the statistic is thresholded below threshold. If tail is 0, the statistic is thresholded on both sides of the distribution.
- threshold
float|dict|None The so-called “cluster forming threshold” in the form of a test statistic (note: this is not an alpha level / “p-value”). If numeric, vertices with stat values more extreme than
thresholdwill be used to form clusters. IfNone, a t- or F-threshold will be chosen automatically that corresponds to a p-value of 0.05 for the given number of observations (only valid when usingstat_fun=None, i.e., a paired t-test or one-way F-test). Ifthresholdis adict(with keys'start'and'step') then threshold-free cluster enhancement (TFCE) will be used (see the TFCE example and [1]). See Notes for an example on how to compute a threshold based on a particular p-value for one-tailed or two-tailed tests.- n_permutations
int| ‘all’ The number of permutations to compute. Can be ‘all’ to perform an exact test.
- adjacency“auto” |
scipy.sparse.sparray|False Defines adjacency between locations in the data, i.e. which locations may join to form a cluster.
"auto"(default):For
Evoked,EpochsandBaseTFRinput, sensor adjacency is inferred from the montage withmne.channels.find_ch_adjacency(), and the remaining (time and, for TFR data, frequency) dimensions get a regular lattice, connecting each location to its immediate neighbors. The data must have a single channel type. Forndarrayinput there is no sensor information to use, so every dimension gets a lattice.
- a
scipy.sparse.sparray: Assumed symmetric (only the upper triangular half is used) and square, with dimension equal to the product of the last 1, 2, or 3 data dimensions.
mne.stats.combine_adjacency()is useful for building one; note thatcluster_testorders the data dimensions as(n_times[, n_freqs], n_channels).
- a
False:No adjacency: every location is treated as independent and unconnected, so each supra-threshold location forms its own cluster.
Warning
For
ndarrayinput the lattice spans every axis, including whichever one holds your channels, so clusters can grow between channels that are merely adjacent in the array rather than on the scalp. Pass MNE objects (so"auto"can use the real sensor geometry) or build the adjacency yourself if that distinction matters.- max_step
int Maximum distance between samples (time points). Default is 1.
- excludearray_like of bool |
None Mask to apply to the data to exclude certain points from clustering (e.g., medial wall vertices). Should be the same shape as the channels/vertices dimension of the data objects. If
None, no points are excluded.- step_down_p
float To perform a step-down-in-jumps test, pass a p-value for clusters to exclude from each successive iteration. Default is zero, perform no step-down test (since no clusters will be smaller than this value). Setting this to a reasonable value, e.g. 0.05, can increase sensitivity but costs computation time.
- t_power
float Power to raise the statistical values (usually t-values) by before summing (sign will be retained). Note that
t_power=0will give a count of locations in each cluster,t_power=1will weight each location by its statistical score.- check_disjointbool
Whether to check if the
adjacencymatrix can be separated into disjoint sets before clustering. This may lead to faster clustering, especially if the “time” and/or “frequency” dimensions are large.- out_type‘mask’ | ‘indices’
Format used to represent each cluster in the list of clusters stored in the
clustersattribute ofmne.stats.ClusterResult:'mask':Each cluster is represented by a boolean array of the same shape as the
stat_obsattribute array ofmne.stats.ClusterResult, withTruevalues indicating locations that are part of a cluster. Note that MNE-Python’s legacy API (e.g.mne.stats.permutation_cluster_test()) would return slices if the shape is 1D and adjacency isNone, whereascluster_testwill always return a boolean array.
'indices':Each cluster is represented by a tuple of 1D integer arrays, one array per dimension of the array in the
stat_obsattribute ofmne.stats.ClusterResult. The arrays together give the coordinates of all locations belonging to the cluster and can be used to indexstat_obs. Note that for large datasets,'indices'may use far less memory than'mask'.
- rng
None|int| instance ofGenerator|RandomState The random number generator (RNG). If
None(default), a newnumpy.random.Generatorseeded from entropy is used. Pass an int or anumpy.random.Generatorfor reproducible results, or a legacyRandomStateto control the random-number stream or for interoperability with third-party code such as scikit-learn that does not accept generators. An integer seed usesnumpy.random.default_rng()and therefore produces a different stream than the same integer passed to a legacyrandom_stateorseedparameter.New in v1.13.
- buffer_size
int|None Block size to use when computing test statistics. This can significantly reduce memory usage when
n_jobs > 1and memory sharing between processes is enabled (seemne.set_cache_dir()), because the data will be shared between processes and each process only needs to allocate space for a small block of locations at a time.- n_jobs
int|None The number of jobs to run in parallel. If
-1, it is set to the number of CPU cores. Requires thejoblibpackage.None(default) is a marker for ‘unset’ that will be interpreted asn_jobs=1(sequential execution) unless the call is performed under ajoblib.parallel_configcontext manager that sets another value forn_jobs.- verbosebool |
str|int|None Control verbosity of the logging output. If
None, use the default verbosity level. See the logging documentation andmne.verbose()for details. Should only be passed as a keyword argument.
- df
- Returns:
mne.stats.ClusterResultObject containing the results of the cluster permutation test.
Notes
For computing a
thresholdbased on a p-value, use the conversion fromscipy.stats.rv_continuous.ppf():pval = 0.001 # arbitrary # for t-statistic df = n_observations - 1 # degrees of freedom for the t-test thresh = scipy.stats.t.ppf(1 - pval / 2, df) # two-tailed, t distribution # for f-statistic dfn = n_conditions - 1 # degrees of freedom numerator dfd = n_observations - n_conditions # degrees of freedom denominator thresh = scipy.stats.f.ppf(1 - pval, dfn=dfn, dfd=dfd) # F distribution
For a one-tailed test (
tail=1), don’t divide the p-value by 2. For testing the lower tail (tail=-1), don’t subtractpvalfrom 1.New in v1.13.
Examples using mne.stats.cluster_test#
Permutation F-test on sensor data with 1D cluster level
Visualising statistical significance thresholds on EEG data
Non-parametric 1 sample cluster statistic on single trial power
Non-parametric between conditions cluster statistic on single trial power
Mass-univariate twoway repeated measures ANOVA on single trial power
Spatiotemporal permutation F-test on full sensor data
Group-level cluster permutation testing with formula contrasts