skbio.stats.distance.permanova#
- skbio.stats.distance.permanova(distmat, grouping, column=None, permutations=999, seed=None, engine=None)[source]#
Test for significant differences between groups using PERMANOVA.
Permutational Multivariate Analysis of Variance (PERMANOVA) is a non-parametric method that tests whether two or more groups of objects (e.g., samples) are significantly different based on a categorical factor. It is conceptually similar to ANOVA except that it operates on distances between objects via a distance matrix, which allows for multivariate analysis. Unlike classical Multivariate Analysis of Variance (MANOVA), PERMANOVA makes no assumptions about the distribution of the underlying data. As such, rather than computing a true F statistic based in known distributions of variables, it computes a pseudo-F statistic whose significance can be assessed by a permutation test.
The pseudo-F statistic is the ratio of between-group variance to within-group variance, defined in [1] analogously to the F statistic in ANOVA:
\[F = \frac{{SS}_{between}/(g - 1)}{{SS}_{within}/(n - g)}\]It is computed from the sums of squares \({SS}_{between}\) and \({SS}_{within}\) divided by their corresponding degrees of freedom, where \(n\) is the number of distinct objects and \(g\) is the number of groups.
Statistical significance is assessed via a permutation test. Objects in the distance matrix are assigned to groups (grouping) based on a categorical factor. This assignment of groups is permuted a number of times (controlled via permutations), and a pseudo-F statistic is computed for each permutation. Under the null hypothesis that the groupings of objects have no effect on the distribution of the underlying data, the pseudo-F statistics of these permutations should be identically distributed for a given distance matrix. The probability of a given pseudo-F statistic being at least as extreme as an observed one is then the proportion of permuted pseudo-F statistics (\(F^{\pi}\)) that are greater than or equal to the observed (unpermuted) one (\(F\)):
\[p = \frac{1 + \text{no. of } F^{\pi} \geq F}{1 + \text{no. of permutations}}\]- Parameters:
- distmat
DistanceMatrix Distance matrix containing distances between samples.
Changed in version 0.7.0: Renamed from
distance_matrix. The old name is kept as an alias.- grouping1-D array-like or pandas.DataFrame
Vector indicating the assignment of samples to groups. These could be strings or integers denoting which group a sample belongs to. If 1-D array-like, it must be the same length and in the same order as the samples in
distmat. If a DataFrame, the column specified bycolumnwill be used as the grouping vector. The DataFrame must be indexed by the IDs indistmat, but the order of IDs betweendistmatand the DataFrame need not be the same. All IDs in the distance matrix must be present in the DataFrame. Extra IDs in the DataFrame are allowed and ignored in the calculation.- columnstr, optional
Column name to use as the grouping vector if
groupingis a DataFrame. Must be provided ifgroupingis a DataFrame. Cannot be provided ifgroupingis 1-D array-like.- permutationsint, optional
Number of permutations to use when assessing statistical significance. Must be greater than or equal to zero. If zero, statistical significance calculations will be skipped and the p-value will be NaN.
- seedint, Generator or RandomState, optional
A user-provided random seed or random generator instance. See
details.Added in version 0.6.3.
- engine{‘cython’, ‘numba’, ‘fast’}, optional
Compute engine for the PERMANOVA statistic and permutation test. If None (default), use the global
compute_enginesetting. ‘fast’ selects Numba if installed, otherwise Cython. See Compute engines for details.Added in version 0.7.4.
- distmat
- Returns:
- pandas.Series
Results of the statistical test, including
test statisticandp-value.
Notes
This function supports the Python array API standard. Compatible array backends:
Backend
CPU
GPU
NumPy
✓
n/a
JAX
✓
✓
PyTorch
✓
✓
CuPy
n/a
✓
See [1] for the original method reference, as well as
vegan::adonis, available in R’s vegan package [2].The precision of the p-value is dependent on the number of permutations. The default precision is \(0.001=1/(1+999)\) from the default value
permutations=999. The unpermuted grouping always contributes the first permutation to the numerator and denominator of the p-value, so 1 is added to both. This circumvents the risk of the probability being zero by chance even when it is nonzero. It is suggested in [1] that at least 1000 permutations should be performed for a confidence level of 0.05, and 5000 permutations should be performed for a confidence level of 0.01. The p-value will benp.nanifpermutationsis zero.A related statistic reported by some implementations (such as
vegan::adonis) is the \(R^2\) value, which describes the proportion of variance in the data explained by the grouping:\[R^2 = \frac{{SS}_{between}}{{SS}_{total}}\]This is not currently computed by this function, but it may be derived from the outputs using the following formula:
\[R^2 = \frac{1}{1 + \frac{n - g}{(g - 1)F}}\]where \(F\) is the pseudo-F statistic, \(n\) is the number of objects, and \(g\) is the number of groups.
Performance
This function uses parallel computation for improved performance. See the parallelization guide for information on controlling the number of threads used. See also Optional binary acceleration for another option of acceleration.
On a GPU-resident distance matrix with
engine='numba', a fused GPU kernel runs on CuPy or PyTorch matrices, on both CUDA and ROCm devices. The exception is ROCm PyTorch on stacks where a Numba HIP kernel cannot be compiled after ROCm PyTorch has been imported in the same process; those matrices fall back to the array-API path, which runs on the device regardless. The result is identical across all paths.With
engine='numba', GPU buffers must belong to the default device. On a system with several devices, the default must be changed to match the buffer ownership before this function is invoked, throughnumba.cuda.select_deviceon CUDA ornumba.hip.select_deviceon ROCm. A mismatch is not reported when the kernel is launched, and on ROCm it has been observed to leave the GPU context unusable for the rest of the process. The array-API path, taken whenengine='numba'is not requested, honors whichever device the input is on.References
Examples
See
skbio.stats.distance.anosimfor usage examples (both functions provide similar interfaces).