Spaces:
Running
Running
| # Authors: The MNE-Python contributors. | |
| # License: BSD-3-Clause | |
| # Copyright the MNE-Python contributors. | |
| import numpy as np | |
| def _ecdf(x): | |
| """No frills empirical cdf used in fdrcorrection.""" | |
| nobs = len(x) | |
| return np.arange(1, nobs + 1) / float(nobs) | |
| def fdr_correction(pvals, alpha=0.05, method="indep"): | |
| """P-value correction with False Discovery Rate (FDR). | |
| Correction for multiple comparison using FDR :footcite:`GenoveseEtAl2002`. | |
| This covers Benjamini/Hochberg for independent or positively correlated and | |
| Benjamini/Yekutieli for general or negatively correlated tests. | |
| Parameters | |
| ---------- | |
| pvals : array_like | |
| Set of p-values of the individual tests. | |
| alpha : float | |
| Error rate. | |
| method : 'indep' | 'negcorr' | |
| If 'indep' it implements Benjamini/Hochberg for independent or if | |
| 'negcorr' it corresponds to Benjamini/Yekutieli. | |
| Returns | |
| ------- | |
| reject : array, bool | |
| True if a hypothesis is rejected, False if not. | |
| pval_corrected : array | |
| P-values adjusted for multiple hypothesis testing to limit FDR. | |
| References | |
| ---------- | |
| .. footbibliography:: | |
| """ | |
| pvals = np.asarray(pvals) | |
| shape_init = pvals.shape | |
| pvals = pvals.ravel() | |
| pvals_sortind = np.argsort(pvals) | |
| pvals_sorted = pvals[pvals_sortind] | |
| sortrevind = pvals_sortind.argsort() | |
| if method in ["i", "indep", "p", "poscorr"]: | |
| ecdffactor = _ecdf(pvals_sorted) | |
| elif method in ["n", "negcorr"]: | |
| cm = np.sum(1.0 / np.arange(1, len(pvals_sorted) + 1)) | |
| ecdffactor = _ecdf(pvals_sorted) / cm | |
| else: | |
| raise ValueError("Method should be 'indep' and 'negcorr'") | |
| reject = pvals_sorted < (ecdffactor * alpha) | |
| if reject.any(): | |
| rejectmax = max(np.nonzero(reject)[0]) | |
| else: | |
| rejectmax = 0 | |
| reject[:rejectmax] = True | |
| pvals_corrected_raw = pvals_sorted / ecdffactor | |
| pvals_corrected = np.minimum.accumulate(pvals_corrected_raw[::-1])[::-1] | |
| pvals_corrected[pvals_corrected > 1.0] = 1.0 | |
| pvals_corrected = pvals_corrected[sortrevind].reshape(shape_init) | |
| reject = reject[sortrevind].reshape(shape_init) | |
| return reject, pvals_corrected | |
| def bonferroni_correction(pval, alpha=0.05): | |
| """P-value correction with Bonferroni method. | |
| Parameters | |
| ---------- | |
| pval : array_like | |
| Set of p-values of the individual tests. | |
| alpha : float | |
| Error rate. | |
| Returns | |
| ------- | |
| reject : array, bool | |
| True if a hypothesis is rejected, False if not. | |
| pval_corrected : array | |
| P-values adjusted for multiple hypothesis testing to limit FDR. | |
| """ | |
| pval = np.asarray(pval) | |
| pval_corrected = pval * float(pval.size) | |
| # p-values must not be larger than 1. | |
| pval_corrected = pval_corrected.clip(max=1.0) | |
| reject = pval_corrected < alpha | |
| return reject, pval_corrected | |