Type I and type II errors in hypothesis testing
Null and alternative hypotheses, alpha, type I and type II errors and power, shown by counting false positives and misses across 2,000 seeded studies.
Updated . Written by Matt Gencer.
On this page
A hypothesis test can go wrong in two ways. It can call a difference real when there is none (a type I error, a false positive), or it can fail to see a difference that is there (a type II error, a miss). This post defines the four ideas that sit around those errors, then counts both kinds in a seeded simulation of 2,000 studies, so the trade-off shows up as numbers instead of a diagram.
All counts below come from that simulation, run through a deterministic engine. The data are synthetic, and nothing here describes any real study or person.
Null and alternative hypotheses
The null hypothesis is the default claim a test tries to find evidence against, usually “no difference” or “no effect”. The alternative hypothesis is what you would conclude instead, for example “the two group means differ”. A test starts from the null, computes how unusual the data would be if it were true, and rejects it only when the data are unusual enough.
The p-value is that measure of unusualness: the probability, under the statistical model and the null hypothesis, of a result at least as extreme as the one observed (Wasserstein and Lazar 2016). It is not the probability that the null hypothesis is true. The p-values and confidence intervals guide covers the definition, the common misreadings and how to report one.
Alpha, the significance level
Alpha is the cut-off for “unusual enough”, chosen before the data are seen. If p is at or below alpha, the null hypothesis is rejected and the result is called statistically significant. The conventional value is 0.05, a convention and not a law of mathematics. The p-values guide explains the label; here the point is only what alpha controls.
Alpha is the long-run rate of type I errors when the null hypothesis is true. Set it at 0.05 and, across many studies of a truly null effect, about 5 in 100 will come out significant by chance alone. A group of researchers has proposed 0.005 as the threshold for claims of new discoveries (Benjamin et al. 2018). Whatever the level, fix it in the analysis plan, and justify it by what a false positive would cost.
Type I and type II errors
Every test of a hypothesis ends in a decision, and the truth is either that the null is right or that it is wrong. That gives four outcomes (Neyman and Pearson 1933).
| Null is true (no real effect) | Null is false (a real effect) | |
|---|---|---|
| Test is significant | Type I error, a false positive | Correct: effect detected |
| Test is not significant | Correct | Type II error, a miss |
Two rates matter. The type I error rate is alpha. The type II error rate, written beta, is the chance of a miss, and it is not fixed by any single setting: it depends on how big the real effect is, how variable the measurements are, how many observations there are, and alpha itself.
The simulation
The example builds 2,000 independent two-group studies. In 1,000 of them the groups truly differ by half a standard deviation; in the other 1,000 there is no difference at all. Both groups in every study are drawn from normal distributions with the same standard deviation. Each study is analysed with a Welch t-test (see the assumptions behind parametric tests) at the stated alpha, and its outcome, significant or not, is recorded against the truth that built it.
Because the truth of every study is known, the engine can score the tests as it would a diagnostic test: “significant” is the test result and “a real effect” is the reference. Its diagnostic accuracy method then reports sensitivity (the share of real effects flagged, which is the power of the design) and specificity (the share of null studies correctly left unflagged, which is one minus the false-positive rate).
With 20 per group at alpha 0.05
Of the 1,000 null studies, 53 came out significant: 53 false positives. The remaining 947 were correctly not significant, a specificity of 0.947 (95% CI 0.9312 to 0.9601), which is a false-positive rate of 0.053. That sits close to the alpha of 0.05 the design promised; the gap is within the ordinary sampling error of counting 1,000 studies.
Of the 1,000 studies with a real effect, only 339 were significant, a sensitivity of 0.339 (95% CI 0.3097 to 0.3693). The other 661 were misses. With 20 per group, a half-standard-deviation difference is missed about two times in three. The test never “failed”: it behaved exactly as designed, and the design could not tell this effect from noise reliably.
This is the general lesson of the table above. Alpha is under your control, and the false-positive rate stayed where it was set. The miss rate was left to the sample size, and it was large.
What a larger sample does
Repeat the same simulation with 64 per group and alpha 0.05. The false positives stay near alpha: 44 of the 1,000 null studies, a specificity of 0.956 (95% CI 0.9414 to 0.9679). The misses fall sharply: 789 of the 1,000 real effects were detected, a sensitivity of 0.789 (95% CI 0.7624 to 0.8139), and 211 were missed.
That is the pattern behind the usual planning target of about 80 percent power. For a half-standard-deviation difference and alpha 0.05, 64 per group is the size at which a two-group comparison reaches it (Cohen 1992), which is why the simulation uses it. The effect sizes guide shows how to choose the effect size such a calculation needs.
What a stricter alpha does
Now keep 64 per group and tighten alpha to 0.005. The false positives nearly vanish: 3 of 1,000 null studies were significant, a specificity of 0.997 (95% CI 0.9913 to 0.9994), in line with the 5 in 1,000 that alpha 0.005 predicts. But the real effects are now harder to detect: only 482 of 1,000 were significant, a sensitivity of 0.482 (95% CI 0.4506 to 0.5135), and 518 were missed.
| Design | Alpha | False positives (of 1,000 null) | Detected (of 1,000 real) | Misses (of 1,000 real) |
|---|---|---|---|---|
| 20 per group | 0.05 | 53 | 339 | 661 |
| 64 per group | 0.05 | 44 | 789 | 211 |
| 64 per group | 0.005 | 3 | 482 | 518 |
Read the table in two directions. Down the rows from the first to the second, a larger sample reduced misses without raising false positives. From the second to the third, a stricter alpha reduced false positives and raised misses. Both rows score the very same 2,000 simulated studies, so the only change is alpha. That second move is the trade-off: with the data and design fixed, you cannot lower one error rate without paying in the other. The remaining ways out are to collect more data, measure more precisely or use a more efficient design.
Why this matters for the claims you make
A type I error is the error of announcing something that is not there. A type II error is the error of overlooking something that is there. Which is worse depends on the setting: a false positive in a screening of many candidates wastes follow-up effort, while a miss in a safety question can hide a real signal. State which you are guarding against and why, in the plan, before the data are seen.
Two cautions follow. First, a non-significant result is not evidence of no effect. In the 20-per-group design, 661 of 1,000 real effects were non-significant, so a lone non-significant result tells you little (Altman and Bland 1995). Report the estimate and its confidence interval, and say what size of effect the data still allow.
Second, alpha is the false-positive rate among null effects, which is not the share of significant findings that are false. That share also depends on how many of the tested effects are real and on the power. When most hypotheses are untrue and power is low, a large fraction of significant results can be false (Button et al. 2013). The simulation holds half the effects real, a generous setting for illustration.
Running many tests inflates the type I error. Each test at alpha 0.05 carries its own 5 percent chance of a false positive, and across a family of tests the chance of at least one rises quickly. The multiple comparisons guide sets out the corrections that restore control over the family.
Power
Power is the probability that a test rejects the null hypothesis when a specified real effect exists. It equals one minus beta, and the simulation estimates it by the detected share: 0.339, 0.789 and 0.482 in the three designs above. The 64-per-group interval, 0.7624 to 0.8139, contains the 80 percent that the standard calculation gives for that design.
Power belongs to a design, not to a finished result. It depends on four things that move together: the effect size, the variability, the sample size and alpha. Fix any three and the fourth follows, which is how a sample size is chosen. Pick the smallest effect worth detecting, choose alpha, choose a target such as 80 percent, and solve for n. The effect sizes guide covers how to pick that effect and the standardised measures that sample size software uses.
Power computed after the fact from the observed effect adds nothing to the p-value and should not be used to explain a non-significant result (Hoenig and Heisey 2001). Compute it before the study, or report the interval after it.
Rerunning the example
The worked example’s script is shown below this post exactly as the engine generated it, with its seed and printed output. It reads the 2,000 simulated studies (one row per study: whether its Welch test was significant, and whether its effect was real) and recomputes the sensitivity, specificity and their intervals from the resulting two-by-two table. The studies themselves were generated once, with the seed shown, before the engine scored them. The 64-per-group and stricter-alpha runs use the same code and the same seed with the sample size or alpha changed, and each has its own output.
The printed output leads with Youden’s J, which is sensitivity plus specificity minus one (here, power minus the false-positive rate). The interval printed beside it belongs to the sensitivity, which is the power.
Because the simulation is seeded, the same counts come out every time. A different seed would shift each count slightly, by about the amount the confidence intervals above express. The counts are estimates of the underlying rates, not the rates themselves.
What these numbers do and do not say
These are results from synthetic studies built to show how test decisions behave. They show how often a test errs under stated conditions; they are not a statement about any real treatment, person or dataset. For the choice of test for your own design, see the guide to choosing a statistical test.
Worked example
Data: synthetic, generated in the script below. Seed: 20261023.
Run on Celeus engine 0.31.1, seed 20261023, synthetic data.
Output
# Results - Test: Diagnostic accuracy (2x2) - n: 2000 - statistic: NA - p-value: NA - effect size: Youden's J = 0.286 - 95% CI: [0.3097, 0.3693] - seed: 20261023 ## Assumption checks - sample size: passed=TRUE (adequate n) ## Power - Power is not calculated for this test.
R script
# Celeus - reproduce.R (run from this package folder; bundled data in data/)
# Test: Diagnostic accuracy (2x2) | engine 0.31.1 | catalog c39-d3cd
# Research context: not provided for this run.
# Reproduces the recorded result deterministically.
set.seed(20261023)
.data_path <- "data/type-i-and-type-ii-errors.csv"
if (!file.exists(.data_path)) stop("Run reproduce.R from the package folder (the bundled data is in data/).")
data <- readr::read_csv(.data_path, show_col_types = FALSE) # needs the readr package
clean_cells <- function (df)
{
ctrl_collapse <- "[\r\n\t\v\f]+"
zero_width_chars <- intToUtf8(c(8203L, 65279L), multiple = TRUE)
uni_space_chars <- intToUtf8(c(160L, 8239L, 8199L), multiple = TRUE)
clean_text <- function(x) {
out <- x
for (ch in zero_width_chars) out <- gsub(ch, "", out,
fixed = TRUE)
out <- gsub(ctrl_collapse, " ", out)
for (ch in uni_space_chars) out <- gsub(ch, " ", out,
fixed = TRUE)
trimws(gsub(" +", " ", out))
}
changed_cols <- character(0)
cells_cleaned <- 0L
retyped <- character(0)
for (j in seq_along(df)) {
col <- df[[j]]
if (!is.character(col))
next
cleaned <- clean_text(col)
n_changed <- sum(!is.na(col) & !is.na(cleaned) & col !=
cleaned, na.rm = TRUE)
if (n_changed > 0L) {
changed_cols <- c(changed_cols, names(df)[j])
cells_cleaned <- cells_cleaned + n_changed
}
df[[j]] <- cleaned
non_blank <- cleaned[!is.na(cleaned) & nzchar(cleaned)]
if (length(non_blank) && all(grepl("^[+-]?(0|[1-9][0-9]*)([.][0-9]+)?$",
non_blank))) {
parsed <- suppressWarnings(as.numeric(cleaned))
was_blank <- is.na(cleaned) | !nzchar(cleaned)
lost <- (is.na(parsed) | is.infinite(parsed)) & !was_blank
if (!any(lost)) {
finite <- parsed[!is.na(parsed)]
all_whole <- all(finite == floor(finite))
in_range <- all(abs(finite) <= .Machine$integer.max)
df[[j]] <- if (all_whole && in_range)
as.integer(parsed)
else parsed
retyped <- c(retyped, names(df)[j])
}
}
}
names(df) <- clean_text(names(df))
if (length(changed_cols)) {
attr(df, "ingest_clean_columns") <- changed_cols
attr(df, "ingest_clean_cells_cleaned") <- cells_cleaned
}
if (length(retyped))
attr(df, "ingest_clean_retyped") <- retyped
df
}
data <- clean_cells(data)
# Complete-case analysis: drop rows missing any analysis value.
.acols <- c("test_significant", "effect_real")
data <- data[stats::complete.cases(data[, .acols, drop = FALSE]), , drop = FALSE]
result <- { .t <- table(factor(as.character(data[["test_significant"]]), levels = c("yes", "no")), factor(as.character(data[["effect_real"]]), levels = c("yes", "no"))); .tp <- .t[1, 1]; .fp <- .t[1, 2]; .fn <- .t[2, 1]; .tn <- .t[2, 2]; .ci <- function(x, n) if (n > 0) as.numeric(stats::binom.test(x, n)$conf.int) else c(NA_real_, NA_real_); .p <- function(x, n) if (n > 0) x / n else NA_real_; .z <- stats::qnorm(1 - (1 - 0.95) / 2); .dis <- .tp + .fn; .nd <- .fp + .tn; .lr <- function(ok, v, se) if (ok) list(value = v, ci = exp(log(v) + c(-1, 1) * .z * se)) else list(value = NA_real_, ci = c(NA_real_, NA_real_)); .lp <- .lr(.tp > 0 && .fp > 0, (.tp / .dis) / (.fp / .nd), sqrt(1 / .tp - 1 / .dis + 1 / .fp - 1 / .nd)); .ln <- .lr(.fn > 0 && .tn > 0, (.fn / .dis) / (.tn / .nd), sqrt(1 / .fn - 1 / .dis + 1 / .tn - 1 / .nd)); .do <- .lr(all(c(.tp, .fp, .fn, .tn) > 0), (.tp * .tn) / (.fp * .fn), sqrt(1 / .tp + 1 / .fp + 1 / .fn + 1 / .tn)); list(counts = list(tp = .tp, fp = .fp, fn = .fn, tn = .tn), sensitivity = .p(.tp, .tp + .fn), specificity = .p(.tn, .tn + .fp), ppv = .p(.tp, .tp + .fp), npv = .p(.tn, .tn + .fn), sensitivity_ci = .ci(.tp, .tp + .fn), specificity_ci = .ci(.tn, .tn + .fp), ppv_ci = .ci(.tp, .tp + .fp), npv_ci = .ci(.tn, .tn + .fn), prevalence = (.tp + .fn) / (.tp + .fp + .fn + .tn), lr_pos = .lp$value, lr_pos_ci = .lp$ci, lr_neg = .ln$value, lr_neg_ci = .ln$ci, dor = .do$value, dor_ci = .do$ci) }
print(result)Common questions
What is the difference between a type I and a type II error?
A type I error is rejecting a null hypothesis that is true, a false positive. A type II error is failing to reject a null hypothesis that is false, a miss. The type I error rate is set by the significance level alpha you choose. The type II error rate depends on the true effect, the sample size, the variability and alpha.
How do you remember which error is which?
Type I is the error of seeing something that is not there, a false alarm. Type II is the error of missing something that is there. Another aid is that type I comes first because it is the error the test controls first and directly, through the significance level alpha.
Can you reduce both type I and type II errors at once?
Not by changing alpha alone, because lowering alpha makes false positives rarer and misses commoner. A larger sample, less variable measurements or a better design can lower the miss rate without raising the false-positive rate. That is why the sample size is planned around the effect worth detecting before data are collected.
What is the relationship between alpha, beta and power?
Alpha is the probability of a type I error when the null hypothesis is true. Beta is the probability of a type II error when a specific alternative is true. Power is one minus beta, the probability of detecting that alternative. Each is defined for a stated design, test and effect size.
Does p below 0.05 mean the finding is a false positive only 5 percent of the time?
No. Alpha is the false-positive rate among studies where the null hypothesis is true. The share of significant results that are false depends also on how many tested effects are real and on the power. With low power or many unlikely hypotheses, far more than 5 percent of significant results can be false.
Sources
- Neyman J, Pearson ES (1933). On the problem of the most efficient tests of statistical hypotheses. Philosophical Transactions of the Royal Society A 231:289-337. doi:10.1098/rsta.1933.0009
- Wasserstein RL, Lazar NA (2016). The ASA statement on p-values: context, process, and purpose. The American Statistician 70(2):129-133. doi:10.1080/00031305.2016.1154108
- Cohen J (1992). A power primer. Psychological Bulletin 112(1):155-159. doi:10.1037/0033-2909.112.1.155
- Altman DG, Bland JM (1995). Absence of evidence is not evidence of absence. BMJ 311(7003):485. doi:10.1136/bmj.311.7003.485
- Button KS, Ioannidis JPA, Mokrysz C, et al. (2013). Power failure: why small sample size undermines the reliability of neuroscience. Nature Reviews Neuroscience 14(5):365-376. doi:10.1038/nrn3475
- Benjamin DJ, Berger JO, Johannesson M, et al. (2018). Redefine statistical significance. Nature Human Behaviour 2(1):6-10. doi:10.1038/s41562-017-0189-z
- Hoenig JM, Heisey DM (2001). The abuse of power: the pervasive fallacy of power calculations for data analysis. The American Statistician 55(1):19-24. doi:10.1198/000313001300339897
Methods discussed
Try it on your own data
Upload a dataset and Celeus suggests a method, checks its assumptions, runs it in R, and gives you the script to rerun it.
Try it in Celeus