↑↓ move↵ open[] previous / next lesson? all shortcuts
Appearance
Theme
Type size
Reading

Focus mode hides the sidebars. Press f to toggle it anywhere.

Keyboard shortcuts
/
Search
[ ]
Previous / next lesson
t
Jump to the table of contents
r
Review queue
f
Focus mode
?
This panel
Explainer14 min

Statistics for small experiments

The binomial bound that says when a classifier is above chance, permutation tests that need no assumptions, cluster correction for waveforms, effect sizes, and the multiple-comparisons trap. Enough to not fool yourself.

AssumesClassification done honestlySpineDecoding / signal processing / ML
On this page14 min
  1. When is a classifier above chance?
  2. Permutation tests
  3. Cluster-based permutation for waveforms
  4. Effect sizes
  5. The traps, named

Your scored 62 percent. Your has a bump. Your feedback nights looked better than sham. Each of these is a number, and the question is always the same: how often would noise alone produce a number this big? The tools on this page answer that for the small, messy datasets you actually have. None of them need more than arithmetic and a loop.

When is a classifier above chance?

Two classes, N trials, a that is really guessing. The number it gets right follows a binomial distribution with probability one half. The 95th percentile of that distribution, divided by N, is the accuracy a guessing beats one time in twenty. For N = 40 it is about 62 percent. For 80, about 59. For 200, about 56. For 1000, about 52. Only above that bound does your accuracy mean anything, and the bound should sit next to the accuracy in every report.

The bound is the inverse binomial tail, per trial:

achance=B−1(1−α;N,1/2)/Na_{chance} = B^{-1}(1 - \alpha; N, 1/2) / N

Here B−1B^{-1} is the inverse cumulative binomial distribution, α=0.05\alpha = 0.05, NN the trial count, and 1/21/2 the guessing rate for two classes.

from scipy.stats import binom
def chance_bound(n_trials, n_classes=2, alpha=0.05):
    return binom.ppf(1 - alpha, n_trials, 1 / n_classes) / n_trials

The bound assumes trials are independent, which shuffled trials from one session are not. So it is the least you need, not the most. For unbalanced classes, use the majority-class rate as the null.

Permutation tests

You want to know whether two conditions differ in some measure: mean amplitude, accuracy, alpha power. Compute the difference. Then shuffle the condition labels, recompute the difference, and repeat ten thousand times. The fraction of shuffles whose difference is at least as large as yours is the p-value. No assumption about distributions, no formula to misremember, and it works for any statistic you can compute. For within-subject designs, shuffle within each participant (swap the two conditions’ labels per person).

The p-value is the tail probability under shuffling:

p=P(∣D∗∣≥∣dobs∣)p = P(|D^*| \ge |d_{obs}|)

Here dobsd_{obs} is the difference measured with the true labels and D∗D^* the differences from shuffled labels.

import numpy as np
def perm_test(a, b, n=10000, rng=np.random.default_rng(0)):
    # a, b: paired measurements per participant
    d = a - b; obs = d.mean()
    signs = rng.choice([-1, 1], size=(n, len(d)))
    null = (signs * d).mean(axis=1)
    return (np.abs(null) >= abs(obs)).mean()
Predict before you look

You test whether an ERP differs between conditions at every one of 200 time points and 32 channels. At a threshold of p below 0.05, how many significant points do you expect if there is no effect at all?

About 320. Five percent of 6400 tests are false positives by construction (E=6400×0.05=320E = 6400 \times 0.05 = 320). Testing many points and reporting the ones that cross the line is the multiple-comparisons problem, and it produces a “significant” cluster somewhere in nearly every dataset. Cluster-based permutation, below, is the standard fix for waveforms.

Cluster-based permutation for waveforms

Compute a t-statistic at every time point (and channel). Threshold it. Group neighbouring above-threshold points into clusters and give each cluster a mass (the sum of its t-values). Shuffle labels, repeat, and record the largest cluster mass in each shuffle. Your cluster’s p-value is the fraction of shuffles whose biggest cluster was bigger. This controls the false-positive rate across the whole waveform while exploiting the fact that real effects are extended in time and space. implements it in one function. Report the cluster’s extent honestly: the test says a difference exists somewhere in the cluster, not that it starts or ends at the cluster’s edges.

Each cluster gets one number, its mass, the sum of its thresholded t-values:

m=∑clustertm = \sum_{cluster} t

Only the largest mass per shuffle is kept, which is what controls the error rate across the whole waveform.

Effect sizes

A p-value says whether an effect is distinguishable from zero. It does not say how big it is. Report the difference in the measure’s own units (2.3 µV) and a standardized effect size (Cohen’s d, the difference divided by the standard deviation across participants). A d of 0.2 is small, 0.5 medium, 0.8 large. Classic effects are large; most “cognitive enhancement” claims are small at best, and a small effect in twelve people is noise.

Cohen’s d standardizes the difference by the spread across participants:

d=xˉ1−xˉ2sd = \frac{\bar{x}_1 - \bar{x}_2}{s}

Here xˉ1−xˉ2\bar{x}_1 - \bar{x}_2 is the mean difference in the measure’s own units and ss is the standard deviation across participants.

The traps, named

Figure 1. Five ways to get a number that is not there, none of which involve lying. Each one has a fix that costs less than the experiment did.

Peeking and stopping. Collecting data until the p-value crosses 0.05 guarantees it will. Set N in advance.

Garden of forking paths. Trying several windows, channels, , and rejection thresholds and reporting the one that worked. Pre-register the analysis.

Double dipping. Choosing the channel or window where the effect looks biggest, then testing it there. The selection already used the data.

Correlation across trials treated as independence. Trials from one person are not independent samples of the population. Test across participants.

Confusing significance with size. A p of 0.001 with a d of 0.1 is a real, tiny effect, probably from a large N. Say so.

Deep dive Bayesian alternatives 2 min

A Bayes factor compares how well the data are predicted by “there is an effect” versus “there is none,” and can express evidence for the null, which a p-value cannot. For accuracy, a Bayesian estimate of the accuracy with a credible interval is often more useful than a bound. The tools (PyMC, brms) are more work to learn; do it when a reviewer asks or when you need to argue that something does not work, which the project may require.

Deep dive Information transfer rate has error bars too 2 min

ITR is computed from an accuracy, and the accuracy has uncertainty. Bootstrap: resample selections with replacement, recompute ITR, repeat, report the 2.5 and 97.5 percentiles. A speller reported at 42 bits per minute with an interval from 30 to 50 is a different claim from one at 42 exactly.

For NN targets at accuracy PP, the bits per selection are:

B=log⁡2N+Plog⁡2P+(1−P)log⁡21−PN−1B = \log_2 N + P\log_2 P + (1-P)\log_2\frac{1-P}{N-1}

Resample the selections, recompute BB each time, and the percentiles of the results are the interval.

Recall
What accuracy must a two-class classifier exceed on 40 trials to be above chance at the 5 percent level, roughly, and why is that still not enough?
About 62 percent. The bound assumes independent trials; correlated trials from one session make it optimistic, so cross-session or cross-subject testing is still needed.
Recall
How does a permutation test work and what is its main advantage?
Shuffle the condition labels many times and recompute the statistic; the p-value is the fraction of shuffles at least as extreme as the observed value. It assumes nothing about distributions and works for any statistic.
Recall
What problem does cluster-based permutation solve, and what does it not tell you?
It controls false positives across thousands of time-channel tests by testing cluster mass against a shuffled maximum. It does not establish where within the cluster the effect begins or ends.
Explain it to your roommate

Explain what this page was about to your roommate in three sentences. No jargon they would not know.