Testy permutacyjne

Author

Sebastian Cieślak

Published

May 14, 2026

1 Wprowadzenie

Testy permutacyjne to podejście nieparametryczne, które dzięki rozwojowi metod komputerowych stało się szeroko stosowane we współczesnej statystyce. Metody te znajdują szczególne zastosowanie w dziedzinach takich jak biostatystyka, psychologia oraz badania kliniczne, gdzie badacze często dysponują niewielkimi próbami danych, które nie spełniają rygorystycznych założeń o normalności rozkładu.

Główna idea opiera się na założeniu, że jeśli między badanymi grupami nie ma żadnej realnej różnicy, to etykiety przypisane do poszczególnych wyników nie mają znaczenia. W praktyce najpierw obliczamy wynik rzeczywisty, na przykład różnicę średnich między naszymi grupami. Następnie program komputerowy “miesza” wszystkie wyniki i losowo przydziela je do grup od nowa, tworząc sztuczne zestawy danych. Proces ten jest powtarzany tysiące razy, a za każdym razem komputer zapisuje wynik, jaki wyszedł w danym losowym rozdaniu. Na koniec porównujemy nasz pierwotny, prawdziwy wynik z całym zbiorem wyników uzyskanych przez losowanie. Jeśli nasz wynik jest bardzo rzadki na tle tych wygenerowanych przypadkowo, uznajemy go za istotny statystycznie.

2 Wymagane pakiety

Code
#install.packages("coin")
#install.packages("perm")
#install.packages("RVAideMemoire")

3 Podstawowy algorytm permutacyjny

Załóżmy, że porównujemy dwie grupy: \(A\) i \(B\) o licznościach \(n_A\) i \(n_B\). Chcemy sprawdzić, czy średnie w tych grupach różnią się istotnie.

3.1 Algorytm krok po kroku:

  1. Obliczenie statystyki: np. różnicę średnich \(D_{obs} = \bar{X}_A - \bar{X}_B\).
  2. Połączenie danych: \(N = n_A + n_B\).
  3. Permutowanie:
  • Losowe wymieszanie \(N\) obserwacji.
  • Podzielenie wymieszanych danych na dwie nowe grupy o rozmiarach \(n_A\) i \(n_B\).
  • Obliczenie statystyki dla tej permutacji \(D^*_i\).
  1. Wykonanie kroku 3 dużą liczbę razy np. \(B = 10 000\).
  2. Obliczenie p-value:

\[ p = \frac{\sum_{i=1}^{B} I(|D^*_i| \ge |D_{obs}|)}{B} \]

3.2 Symulacja podstawowa w R

Code
set.seed(123)

#Generowanie danych
grupa_A <- rnorm(20, mean = 10, sd = 2)
grupa_B <- rnorm(20, mean = 11.5, sd = 2)
obserwowana_roznica <- mean(grupa_B) - mean(grupa_A)

#Łączenie danych
wszystkie_dane <- c(grupa_A, grupa_B)
N <- length(wszystkie_dane)
n_A <- length(grupa_A)

#Symulacja permutacji
B <- 10000
wyniki_perm <- numeric(B)

for(i in 1:B) {
  indeksy <- sample(1:N, n_A, replace = FALSE)
  perm_A <- wszystkie_dane[indeksy]
  perm_B <- wszystkie_dane[-indeksy]
  wyniki_perm[i] <- mean(perm_B) - mean(perm_A)
}

#p-value
p_val <- sum(abs(wyniki_perm) >= abs(obserwowana_roznica)) / B

#Histogram
hist(wyniki_perm, breaks = 50, col = "lightblue", border = "white", main = "Histogram rozkładu permutacyjnego różnicy średnich", xlab = "Różnica średnich")
abline(v = obserwowana_roznica, col = "red", lwd = 2, lty = 2)
text(obserwowana_roznica, 500, paste("Wynik obserwowany\n",
    "p-value = ", p_val), pos = 4, col = "red")

Histogram rozkładu permutacyjnego różnicy średnich
Code
cat("P-value: ", p_val)
P-value:  0.0618

4 Wykorzystanie pakietów statystycznych

4.1 Pakiet coin

W przeciwieństwie do prostych pętli, pakiet ten wykorzystuje statystyki liniowe i macierze wpływów, co pozwala na wyznaczanie rozkładu statystyki testowej zarówno metodami dokładnymi dla małych prób, jak i metodą Monte Carlo dla większych zbiorów danych.

4.1.1 Algorytm w pakiecie coin:

  1. Wybór statystyki: Określenie miary różnicy (np. średnia, ranga lub mediana).
  2. Transformacja danych: Przekształcenie zmiennych w tzw. macierze wpływów.
  3. Losowe generowanie permutacji obserwacji: np. \(B = 10 000\).
  4. Wyznaczenie p-value: \[p = \frac{1}{B} \sum_{i=1}^{B} I(|T_i^{*}| \geq |T_{obs}|)\]

4.1.2 Symulacja z wykorzystaniem coin

  • Hipoteza zerowa (\(H_0\)): \(P(Y | X) = P(Y)\) Rozkład zmiennej wynikowej (\(Y\)) jest niezależny od przynależności do grupy (\(X\)).
  • Hipoteza alternatywna (\(H_1\)): \(P(Y | X) \neq P(Y)\) Istnieje istotna zależność między przynależnością do grupy a rozkładem zmiennej wynikowej.
Code
library(coin)

set.seed(456)

# Generowanie danych
dane <- data.frame(
  wynik = c(rnorm(15, 50, 10),
             rnorm(15, 58, 10)),
  grupa = factor(rep(c("A", "B"), each = 15))
)

# Test permutacyjny
test_res <- oneway_test(
  wynik ~ grupa,
  data = dane,
  distribution = approximate(nresample = 10000)
)

# Wartości statystyki testowej
rozklad_stat <- support(test_res)

# Statystyka obserwowana
statystyka_obs <- statistic(test_res)

# p-value
p_val <- pvalue(test_res)

# Histogram
hist(
  rozklad_stat,
  breaks = 40,
  col = "lightgreen",
  border = "white",
  probability = TRUE,
  main = "Wartości statystyki testowej",
  xlab = "Statystyka testowa"
)

# Linia wyniku obserwowanego
abline(
  v = statystyka_obs,
  col = "darkblue",
  lwd = 2,
  lty = 2
)

# Opis
text(
  statystyka_obs,
  0.05,
  labels = paste0(
    "Wynik obserwowany\n",
    "p-value = ",
    round(p_val, 4)
  ),
  pos = 4,
  col = "darkblue"
)

Wartości statystyki testowej uzyskane z pakietu coin
Code
# Wynik testu
print(test_res)

    Approximative Two-Sample Fisher-Pitman Permutation Test

data:  wynik by grupa (A, B)
Z = -2.2267, p-value = 0.025
alternative hypothesis: true mu is not equal to 0

4.2 Pakiet perm

Pakiet perm jest często stosowany w analizie problemu Behrensa-Fishera, szczególnie gdy klasyczne założenie o równości wariancji jest naruszone.

4.2.1 Algorytm w pakiecie perm:

  1. Wybór statystyki: Określenie miary różnicy między grupami (najczęściej różnica średnich).
  2. Obliczenie statystyki zaobserwowanej (\(S_{obs}\)): Wyznaczenie wartości testowej dla oryginalnego układu danych.
  3. Generowanie permutacji (Monte Carlo): Wielokrotne (\(B = 10\,000\)) losowe przetasowanie etykiet grup.
  4. Wyznaczenie p-value: Obliczenie odsetka statystyk z permutacji równych lub bardziej ekstremalnych od \(S_{obs}\).

4.2.2 Symulacja problemu Behrensa-Fishera w perm

  • Hipoteza zerowa (\(H_0\)): \(P(Y | X) = P(Y)\) Rozkład zmiennej wynikowej (\(Y\)) jest niezależny od przynależności do grupy (\(X\)).
  • Hipoteza alternatywna (\(H_1\)): \(P(Y | X) \neq P(Y)\) Rozkład zmiennej wynikowej różni się między grupami.
Code
if (!require("perm")) install.packages("perm")
library(perm)
set.seed(123)

# Generowanie danych (Problem Behrensa-Fishera)
n1 <- 15
n2 <- 15
dane_bf <- data.frame(
  wynik = c(rnorm(n1, 50, 5), rnorm(n2, 58, 15)),
  grupa = factor(rep(c("A", "B"), each = 15))
)

# Wykonanie testu metodą Monte Carlo
test_bf <- permTS(wynik ~ grupa, data = dane_bf, 
                  method = "exact.mc", 
                  control = permControl(nmc = 10000))

B <- 10000
rozk_fp <- replicate(B, {
  p_labels <- sample(dane_bf$grupa)
  mean(dane_bf$wynik[p_labels == "B"]) - mean(dane_bf$wynik[p_labels == "A"])
})
obs_diff <- mean(dane_bf$wynik[dane_bf$grupa == "B"]) - 
            mean(dane_bf$wynik[dane_bf$grupa == "A"])

# Histogram 
hist(rozk_fp, breaks = 45, col = "lightblue", border = "white",
     main = "Rozkład referencyjny Fishera-Pitmana",
     xlab = "Różnica średnich", probability = TRUE)

# Dodanie wyniku zaobserwowanego
abline(v = obs_diff, col = "red", lwd = 2, lty = 2)
text(obs_diff, 0.01, "Różnica zaobserwowana", pos = 4, col = "red")

Rozkład referencyjny Fishera-Pitmana dla grup o nierównych wariancjach
Code
cat("P-value dla problemu Behrensa-Fishera:", test_bf$p.value)
P-value dla problemu Behrensa-Fishera: 0.4249575

4.3 Pakiet RVAideMemoire

Pakiet ten oferuje funkcję perm.t.test(), która stanowi permutacyjną wersję klasycznego testu t-Studenta. Jest to szczególnie przydatne narzędzie w kontekście problemu Behrensa-Fishera, gdy chcemy uniknąć metod opartych na losowaniu ze zwracaniem (Bootstrap).

4.3.1 Algorytm w pakiecie RVAideMemoire:

  1. Wyznaczenie statystyki zaobserwowanej (\(t_{obs}\)): Obliczenie standardowej statystyki t dla oryginalnego układu danych.
  2. Generowanie rozkładu permutacyjnego: Wielokrotne przetasowanie etykiet grup w celu wyznaczenia statystyk \(t^*\) dla każdej kombinacji.
  3. Wyznaczenie p-value: Określenie frakcji uzyskanych statystyk \(t^*\), które są co najmniej tak ekstremalne jak wartość zaobserwowana: \[p = \frac{\text{liczba}(|t^*| \geq |t_{obs}|)}{B}\] Gdzie \(B\) to liczba przeprowadzonych permutacji (np. 10 000).

4.3.2 Symulacja permutacyjnego testu t-Studenta w RVAideMemoire

  • Hipoteza zerowa (\(H_0\)): \(\mu_A = \mu_B\) Średnie w obu grupach są identyczne, a obserwowane różnice wynikają z losowości próby.
  • Hipoteza alternatywna (\(H_1\)): \(\mu_A \neq \mu_B\) Istnieje istotna statystycznie różnica średnich między analizowanymi grupami.
Code
if (!require("RVAideMemoire")) install.packages("RVAideMemoire")
library(RVAideMemoire)
set.seed(123)

#Dane
n1 <- 15
n2 <- 15
dane_rv <- data.frame(
  wynik = c(rnorm(n1, 50, 5), rnorm(n2, 55, 12)),
  grupa = factor(rep(c("A", "B"), each = 15))
)

#Wykonanie testu
invisible(capture.output(
  res_rv <- perm.t.test(wynik ~ grupa, data = dane_rv, nperm = 9999)
))

#Statystyka obserwowana
obs_t <- t.test(wynik ~ grupa, data = dane_rv)$statistic

#Rozkład do wizualizacji
rozk_t <- replicate(9999, {
  temp_data <- dane_rv
  temp_data$grupa <- sample(temp_data$grupa)
  t.test(wynik ~ grupa, data = temp_data)$statistic
})

#Wykres
hist(rozk_t, breaks = 45, col = "thistle", border = "white",
     main = "Rozkład referencyjny statystyki t",
     xlab = "Wartość statystyki t*", probability = TRUE)

#Wynik obserwowany
abline(v = obs_t, col = "darkmagenta", lwd = 2, lty = 2)

text(
  obs_t,
  0.38,
  labels = "Statystyka obserwowana",
  pos = 4,
  col = "darkmagenta"
)

Rozkład referencyjny statystyki t (RVAideMemoire)
Code
cat("P-value z testu RVAideMemoire:", res_rv$p.value)
P-value z testu RVAideMemoire: 0.7196

5 Bibliografia

  1. Podstawy teoretyczne i metoda Fishera–Pitmana
  • Pitman, E. J. G. (1938). Significance tests which may be applied to samples from any populations. III. The analysis of variance test. Biometrika, 29(3/4), 322–335.

  • Test permutacyjny. (n.d.). W Wikipedia.
    Link

  • Behrens–Fisher problem. (n.d.). In Wikipedia.
    Link


  1. Pakiet coin i testy permutacyjne
  • Hothorn, T., Hornik, K., van de Wiel, M. A., & Zeileis, A. (2008). Implementing a Class of Permutation Tests: The coin Package. Journal of Statistical Software, 28(8), 1–23.
    Link
  • coin: Conditional Inference Procedures in R. (n.d.). R package manual.
    Link

  1. Pakiet perm i metody Monte Carlo
  • perm: Exact and Monte Carlo Permutation Tests. (n.d.). R package documentation.
    Link
  • Metropolis, N. (1987). The Beginning of the Monte Carlo Method. Los Alamos Science (Special Issue dedicated to Stanisław Ulam), s. 125–130.

  1. Pakiet RVAideMemoire i testy t
  • Hervé, M. (2020). RVAideMemoire: Testing and Plotting Procedures for Biostatistics. R package manual.
    Link
  • Good, P. (2005). Permutation, Parametric, and Bootstrap Tests of Hypotheses. Springer. (Rozdział 3: Testing Hypotheses, s. 48-61)

  1. Metody resamplingu i wnioskowanie statystyczne
  • Manly, B. F. J. (2004). Randomization, Bootstrap and Monte Carlo Methods in Biology. Chapman & Hall/CRC. (Rozdział 6: One- and Two-Sample Tests, s. 107-130)
  • Efron, B., & Tibshirani, R. J. (1993). An Introduction to the Bootstrap. Chapman & Hall/CRC. (Rozdział 15: Permutation Tests, s. 202–219).