IntoMindLearn

Chapter 6 · Middle school

Chance and fair tests

When someone gets a lot right, is it skill, or luck? And how do you test a model fairly?

Luck can look like skill

Guess heads or tails for ten coin flips, and you will usually get about five right. But not always: about one time in six, guessing alone gets seven or more right.

So in a class of thirty, about five people will look like good guessers, just by luck.

Ten flips How often a guesser gets each number of ten coin flips right. Five is most likely. Seven or more, in orange, happens about one time in six.

Try it

Lucky guessers

In pairs, one person flips a coin ten times, and the other guesses each flip before it lands. Score the guesses, then swap. Put every score in the class on one dot plot.

Work it outI guessed of 10 right. In our class, people got 7 or more.

You should seeMost scores near five, and a few people with seven or more. None of them has a special skill at guessing coins.

More tries, less luck

More tries make luck matter less. Seven right out of ten, 70 percent, happens by luck about one time in six. But 70 percent right out of forty tries happens by luck less than one time in a hundred.

Try it

More tries

Put four people's scores out of ten together, for a score out of 40. How many of the class's scores out of 40 reach 28, which is 70 percent? Compare with the scores out of ten.

Work it outOur score out of 40: . Scores of 28 or more in the class: .

You should seeScores out of 40 bunched near 20, and almost none that reach 28.

A fair test

A fair test of a model does two things. It tests the model on examples it never learned from, as in Models that learn. And it compares the score with what guessing would get, its chance level.

In the Mind-Controlled Light Switch, the model is tested on 88 readings it never learned from. Guessing would get about half of them right, 44. The demo tells you whether your score is clearly better than that.

Talk about it

  1. Someone guessed eight of ten coin flips right. Are they good at guessing coin flips?

  2. Why does 70 percent of 40 tries tell you more than 70 percent of 10?

  3. Name the two things that make a test of a model fair.

Chapter 6 · High school

Chance and fair tests

How do you tell whether a score is better than guessing, and why can't 88 readings count as 88 pieces of evidence?

Luck can look like skill

With two equally likely answers, guessing gets about half right: that is the chance level. But not always exactly half. Guess ten coin flips, and about one time in six you will get seven or more right.

The number right out of n independent guesses follows the binomial distribution, drawn here for ten.

Ten flips How often a guesser gets each number of ten coin flips right. Seven or more, in orange, happens about one time in six.

Try it

Lucky guessers

In pairs, one person flips a coin ten times, and the other guesses each flip before it lands. Score the guesses, then swap. Put every score in the class on one dot plot.

Work it outIn our class, of people got seven or more: about one in .

How often is luck enough?

The chance of a score at least as good as yours, if only guessing were at work, is the one-sided p-value. Below 0.05 is a common line for “unlikely to be luck.” It is a convention, not a law of nature.

The Mind-Controlled Light Switch tests your custom AI head on 88 readings. Guessing would get about 44 of them right, and 53 or more about 3.5 times in 100.

Guessing, 88 times How often a guesser gets each number of 88 readings right. Most often about 44. Fifty-three or more, in orange, about 3.5 times in 100.

Try it

A thousand guessers

In a spreadsheet, make 1,000 rows of 88 guesses each, every guess right or wrong with equal chance: =RANDBETWEEN(0,1), with 1 for right. Score each row with SUM, and plot the scores. Then find the share that reach 53 or more, with COUNTIF.

Work it outRows at 53 or more: of 1,000, a share of .

You should seeScores piled up around 44, and about 35 of the 1,000 rows at 53 or more.

Readings that stick together

The binomial distribution assumes every guess is independent. EEG readings aren't: two readings a few seconds apart are much alike, because the person, the electrodes and the room have hardly changed. Counting 88 readings as 88 independent tries overstates the evidence.

So the Mind-Controlled Light Switch keeps each round of readings together: it tests each whole round with a head that never learned from it, and when it checks for luck, it shuffles whole rounds.

Rounds The light switch's 88 readings, in eight rounds of eleven. Readings in a round are alike, so the demo holds back and tests whole rounds, one at a time. The outlined round is one of them.

Try it

Guesses that stick together

In the same spreadsheet, make the guesses stick: each one matches the guess before it 90 percent of the time, with =IF(RAND()<0.9, B2, 1-B2) in each cell after the first. Score and plot the rows again.

Work it outRows at 53 or more now: of 1,000.

You should seeA much wider spread, and many more lucky high scores.

Shuffle the labels

A permutation test asks the question directly. Relabel the data in every way that keeps its structure, score every relabeling the same way, and see where the real score falls among them.

The Mind-Controlled Light Switch relabels whole rounds: with eight rounds, four of them On, there are 70 ways to label them, and it teaches and tests a fresh custom AI head for each.

70 labelings Every way of calling four of eight rounds On. The real one, and its mirror, are outlined. The p-value is the share that score at least as well as the real one.

Try it

Shuffle your Alpha Flower numbers

Take one wearer's six numbers from Alpha Flower, three open and three closed, and number them 1 to 6. The score is the mean of the three called closed, minus the mean of the other three. Work out the score for all 20 ways to choose which three are called closed.

Called closedScore
1 2 3
1 2 4
1 2 5
1 2 6
1 3 4
1 3 5
1 3 6
1 4 5
1 4 6
1 5 6
2 3 4
2 3 5
2 3 6
2 4 5
2 4 6
2 5 6
3 4 5
3 4 6
3 5 6
4 5 6

Work it outThe real labeling ranks of 20, so p = .

Talk about it

  1. What does a one-sided p-value of 0.03 mean for a light switch score?

  2. When the guesses stuck together, high scores became more common. Why does that matter for EEG readings?

  3. Why does the demo shuffle whole rounds, not single readings?

Sources

Combrisson, E., and Jerbi, K. (2015). Exceeding chance level by chance: the caveat of theoretical chance levels in brain signal classification and statistical assessment of decoding accuracy. Journal of Neuroscience Methods.

Chapter 6 · College

Chance and fair tests

When does a classifier's score mean more than luck? Readings that stick together, tuning on the test, and many tests at once can each make noise look like signal.

Chance level, and p-values

With two states taught equally, guessing gets each reading right half the time: the chance level. If the 88 readings of the Mind-Controlled Light Switch were independent, the number a guesser gets right would follow a binomial distribution, mean 44, standard deviation √22, about 4.7.

A p-value is how often a result at least this strong would happen if only chance were at work. Under the binomial, 53 or more of 88 happens about 3.5 times in 100, below the conventional 0.05.

Guessing, 88 times How often a guesser gets each number of 88 independent readings right. Most often about 44, and 53 or more, in orange, about 3.5 times in 100.

Readings that stick together

EEG readings close in time are alike: the contact, the posture and the wearer's state change slowly. So the 88 readings aren't independent, they carry less evidence than 88 coin flips, and the binomial overstates how unlikely a score is.

Worse, a test that mixes them up leaks. Split the readings into random folds, and every test reading has near-copies from its own round in training: leakage. Holding out whole rounds, blocked folds, keeps neighbors on the same side.

Rounds The light switch's 88 readings come in eight rounds of eleven, Off and On in turn. Readings in a round are alike, so the demo tests on a whole held-out round.

Permutation tests

A permutation test builds the null distribution from the data itself: relabel it in every way the null hypothesis allows, score each relabeling exactly as the real one was scored, and count the share that score at least as well. Labels are only exchangeable in blocks, so permute whole rounds.

Calling four of eight rounds On can be done C(8, 4) = 70 ways. The Mind-Controlled Light Switch scores every one, and since a labeling and its mirror, with Off and On swapped, score alike, its p-value can't go below 2/70.

70 labelings Every way of calling four of the eight rounds On. Each is scored like the taught one, outlined with its mirror, and the p-value is the share that score at least as well.

Try it

Noise that looks like signal

Make 88 readings of 76 numbers in eight rounds, with no difference at all between Off and On, only an offset shared within each round. Score a ridge classifier with random folds, then with one round held out at a time, and run the permutation test over rounds.

import numpy as np
from itertools import combinations

rng = np.random.default_rng(6)
rounds, per, d = 8, 11, 76
# 88 readings of 76 numbers, in rounds of Off and On in turn, with no difference between
# the states at all. Each round has its own offset, so readings in a round are alike.
round_of = np.repeat(np.arange(rounds), per)
X = rng.normal(size=(rounds, d))[round_of] + rng.normal(size=(rounds * per, d))
y = (round_of % 2).astype(float)

def fit(X, y, lam=100.0):
    A = np.c_[X, np.ones(len(X))]
    P = lam * np.eye(A.shape[1])
    P[-1, -1] = 0
    return np.linalg.solve(A.T @ A + P, A.T @ y)

def accuracy(X, y, folds):
    right = 0
    for test in folds:
        train = np.setdiff1d(np.arange(len(y)), test)
        w = fit(X[train], y[train])
        right += np.sum((np.c_[X[test], np.ones(len(test))] @ w > 0.5) == y[test])
    return right / len(y)

random_folds = np.array_split(rng.permutation(len(y)), 8)
round_folds = [np.flatnonzero(round_of == r) for r in range(rounds)]
print("random folds:", round(accuracy(X, y, random_folds), 2))
real = accuracy(X, y, round_folds)
print("a round held out at a time:", round(real, 2))

# Every way of calling four of the eight rounds On, each scored the same way.
null = [accuracy(X, np.isin(round_of, on).astype(float), round_folds)
        for on in combinations(range(rounds), 4)]
print("relabelings score", round(np.mean(null), 2), "on average")
print("p, over 70 labelings of the rounds:", round(np.mean(np.array(null) >= real), 2))

You should seeRandom folds scoring all 88 right, on pure noise. One round held out at a time, about a half. The relabelings averaging well below a half, and a p of about 0.14: no evidence, rightly.

Tuning on the test, and many tests

Choosing anything with the test in view, the penalty, the features, the frequency band, the wearer or the session to report, fits that choice to the test and flatters its score. Selecting data by the same statistic you then test is called double dipping. Tune inside the training data only, by nested cross-validation.

Run many tests at 0.05 and false positives arrive at that rate: multiple comparisons. Holm's method controls the chance of any false positive among them, and the Benjamini–Hochberg procedure the expected share of false discoveries. Either way, report how many tests you ran.

Problems

  1. What does a one-sided p-value of 0.03 mean for a light switch score?

  2. Why does the demo shuffle whole rounds, not single readings?

  3. You tune the penalty on the same folds you report. Why is the result optimistic, and how do you fix it?

  4. You test 20 pairs of mental states at 0.05 each. How many false positives should you expect if none truly differ, and what would you do?

  5. On the same folds, logistic regression got 3 more of 88 readings right than ridge regression. Is it the better classifier?

Sources

Combrisson, E., and Jerbi, K. (2015). Exceeding chance level by chance: the caveat of theoretical chance levels in brain signal classification and statistical assessment of decoding accuracy. Journal of Neuroscience Methods.

Kriegeskorte, N., Simmons, W. K., Bellgowan, P. S. F., and Baker, C. I. (2009). Circular analysis in systems neuroscience: the dangers of double dipping. Nature Neuroscience.

Varoquaux, G. (2018). Cross-validation failure: small sample sizes lead to large error bars. NeuroImage.

Benjamini, Y., and Hochberg, Y. (1995). Controlling the false discovery rate: a practical and powerful approach to multiple testing. Journal of the Royal Statistical Society, Series B.

Chapter 6 · Graduate

Chance and fair tests

When is a decoding accuracy evidence of anything, with windows that depend on each other, few of them, and many ways to analyze them?

Chance isn't a number

Two classes in equal numbers don't make chance 50 percent. With n independent trials, a guesser reaches k correct with binomial probability, and with 88 trials 53 correct, 60 percent, still happens one time in 29. With fewer trials the bar is higher, and many published decoding results clear 50 percent by less than chance alone would (Combrisson and Jerbi, 2015). Cross-validated accuracy on samples of a hundred or so has error bars of about ten percentage points either way (Varoquaux, 2018).

Windows that stick together

Those counts assume independent trials. Windows from one session aren't: they overlap, they share each round's state of the electrodes and the person, and they drift together. Eight rounds of eleven windows carry closer to eight observations than to eighty-eight, and a binomial on the windows treats them as eighty-eight. If folds mix windows from the same round into training and test, a decoder can recognize the round rather than the state, and score well on noise. Leakage of this kind, between what a model learns from and what it is tested on, runs through machine learning in science (Kapoor and Narayanan, 2023).

A test that respects the design

A permutation test compares the statistic with its values under relabelings that are equally likely if nothing is there, and is exact when the labels are exchangeable under that null (Nichols and Holmes, 2002). For a classifier, the whole pipeline, folds and fitting and scoring, is rerun for every relabeling (Ojala and Garriga, 2010). With labels that come in rounds, only whole rounds trade labels.

Its null need not center on one half. Holding out a whole round leaves the training set with more rounds of the other class, and a decoder that leans toward the training majority is pushed to guess wrong on every held-out round, so cross-validated accuracy under the null sits below chance (Jamalabadi and others, 2016). The binomial knows nothing of this, and the permutation null includes it.

Many analyses

Every choice made after seeing the data, a band, a window, a penalty, an exclusion, is a test that wasn't counted. Holm's procedure (1979) controls the chance of any false positive among m tests, and Benjamini and Hochberg's (1995) the expected share of false positives among those declared. Neither helps with comparisons nobody counted: the garden of forking paths, where each analysis is reasonable and the one reported was chosen because it worked (Gelman and Loken, 2014). Writing the analysis down before the data is the remedy, which is what preregistration is for.

In the demo

The Mind-Controlled Light Switch keeps 88 windows in eight rounds of 11, alternating Off and On, starting with Off. Its folds are contiguous, five to begin with, more until every training set has more windows than the head has weights, which with 88 windows makes eight folds of 11, one round each. Each fold's penalty uses no labels, so it is computed once. Every way of labeling four of the eight rounds On, 70 in all, is scored with the same folds by heads rounded as the device runs them, and p is the share that score at least as well as the taught labeling. Swapping On and Off splits the rounds the same way and scores the same, so p is never below 2/70, about 0.029. Below 0.05, the demo says the head is clearly better than guessing.

Analysis

Analysis

Three tests on sessions with and without a signal

Simulate sessions shaped like the light switch's, 8 rounds of 11 embeddings with an offset shared within each round, with no signal and with one. On each, test a ridge head three ways: folds that mix the rounds with a binomial test, rounds held out with a binomial test, and rounds held out against all 70 labelings. Do it with the demo's penalty, and with a heavier one that also uses no labels.

import numpy as np
from itertools import combinations
from scipy.stats import binom

rng = np.random.default_rng(6)
ROUNDS, PER, D = 8, 11, 76
rounds = np.repeat(np.arange(ROUNDS), PER)
labels = (rounds % 2).astype(float)                   # Off, On, Off, On, as the demo teaches
u = rng.normal(size=D)
u = (u - u.mean()) / np.linalg.norm(u - u.mean())    # sums to zero, like every embedding

def session(signal, drift=0.3):
    """88 embeddings: noise, an offset shared within each round, and the label times u."""
    x = rng.normal(size=(ROUNDS * PER, D))
    x += np.repeat(rng.normal(0, drift, (ROUNDS, D)), PER, axis=0)
    return x - x.mean(axis=1, keepdims=True) + signal * labels[:, None] * u

def accuracy(x, folds, Y, penalty):
    """Held-out accuracy of ridge for every labeling in Y, one row per labeling. Neither
    penalty uses labels: "gap" is the demo's, "mean" the Gram matrix's mean eigenvalue."""
    right = np.zeros(len(Y))
    for train, test in folds:
        xc = x[train] - x[train].mean(0)
        ev = np.linalg.eigvalsh(xc.T @ xc)
        lam = np.sqrt(max(ev[0], 1) * ev[1]) if penalty == "gap" else ev.mean()
        fit = np.linalg.solve(xc.T @ xc + lam * np.eye(D), xc.T)
        yt = Y[:, train]
        w = (yt - yt.mean(1, keepdims=True)) @ fit.T              # a weight vector per labeling
        score = (x[test] - x[train].mean(0)) @ w.T + yt.mean(1)
        right += ((score > 0.5) == (Y[:, test].T == 1)).sum(0)
    return right / x.shape[0]

n = len(labels)
by_round = [(np.flatnonzero(rounds != r), np.flatnonzero(rounds == r)) for r in range(ROUNDS)]
relabel = np.array([np.isin(rounds, c) for c in combinations(range(ROUNDS), 4)], float)  # 70
taught = next(i for i, r in enumerate(relabel) if np.array_equal(r, labels))

def tests(x, penalty):
    mixed = rng.permutation(n).reshape(ROUNDS, PER)              # folds that ignore the rounds
    folds = [(np.setdiff1d(np.arange(n), m), m) for m in mixed]
    leaky = accuracy(x, folds, labels[None], penalty)
    scores = accuracy(x, by_round, relabel, penalty)
    return {"leaky folds, binomial": binom.sf(round(leaky[0] * n) - 1, n, 0.5),
            "rounds, binomial": binom.sf(round(scores[taught] * n) - 1, n, 0.5),
            "rounds, 70 labelings": np.mean(scores >= scores[taught] - 1e-12),
            "null's mean accuracy": scores.mean()}

for penalty, signal in (("gap", 0.0), ("mean", 0.0), ("mean", 2.0)):
    runs = [tests(session(signal), penalty) for _ in range(300)]
    print(f"penalty {penalty}, signal {signal}:")
    for k in runs[0]:
        v = np.array([r[k] for r in runs])
        shown = f"{v.mean():.2f}" if "mean" in k else f"p < 0.05 in {np.mean(v < 0.05):.0%}"
        print(f"   {k:21s} {shown}")

You should seeWith no signal, mixed folds declare a head clearly better than guessing in 36 and 89 percent of sessions. Rounds held out with a binomial test do it in 10 percent with the demo's penalty and 1 percent with the heavier one, whose null averages 0.37. The 70 labelings do it in 3 percent with either. With a signal, the labelings find it in 58 percent of sessions and the binomial in 48.

Then report: why the binomial errs in opposite directions with the two penalties, and what the drift between rounds does to each test when you raise it.

Open problems

  1. Folds for data that drift. No way of splitting one session predicts how a decoder will do in the next, when the data will have moved. Estimating that from the session at hand is open.
  2. Small samples. With one person and a hundred windows, error bars are wide whatever the test (Varoquaux, 2018), and what to report beyond a p-value, and how, is not settled.
  3. From people to populations. A t-test on decoding accuracies across people asks whether the average exceeds chance, not whether a typical person's decoder works. Allefeld, Görgen and Haynes (2016) propose testing the prevalence of an effect instead, and practice hasn't settled.

Problems

  1. How many of 88 independent windows must be right for a one-sided binomial p below 0.05? How many of 8 independent rounds?

  2. Why do folds that mix windows from the same round score well on noise when rounds carry offsets?

  3. Why is the demo's p never below 2/70? With ten rounds, five of each, what would the smallest p be?

  4. With one round held out, why does a decoder that leans toward the training majority guess wrong on every held-out round?

  5. A paper reports 70 percent decoding accuracy, p < 0.001 by a binomial test over 400 trials from 4 runs, with the trials shuffled into ten folds. What would you ask for?

Sources

Holm, S. (1979). A simple sequentially rejective multiple test procedure. Scandinavian Journal of Statistics.

Benjamini, Y., and Hochberg, Y. (1995). Controlling the false discovery rate: a practical and powerful approach to multiple testing. Journal of the Royal Statistical Society, Series B.

Nichols, T. E., and Holmes, A. P. (2002). Nonparametric permutation tests for functional neuroimaging: a primer with examples. Human Brain Mapping.

Ojala, M., and Garriga, G. C. (2010). Permutation tests for studying classifier performance. Journal of Machine Learning Research.

Gelman, A., and Loken, E. (2014). The statistical crisis in science. American Scientist.

Combrisson, E., and Jerbi, K. (2015). Exceeding chance level by chance: the caveat of theoretical chance levels in brain signal classification and statistical assessment of decoding accuracy. Journal of Neuroscience Methods.

Allefeld, C., Görgen, K., and Haynes, J.-D. (2016). Valid population inference for information-based imaging: from the second-level t-test to prevalence inference. NeuroImage.

Jamalabadi, H., Alizadeh, S., Schönauer, M., Leibold, C., and Gais, S. (2016). Classification based hypothesis testing in neuroscience: below-chance level classification rates and overlooked statistical properties of linear parametric classifiers. Human Brain Mapping.

Varoquaux, G. (2018). Cross-validation failure: small sample sizes lead to large error bars. NeuroImage.

Kapoor, S., and Narayanan, A. (2023). Leakage and the reproducibility crisis in machine-learning-based science. Patterns.