Słownik metodologiczny · Open science i wnioskowanie

Krzywa specyfikacji – jak pokazać wynik we wszystkich rozsądnych wersjach analizy?

Krzywa specyfikacji pokazuje wynik tej samej hipotezy we wszystkich rozsądnych wersjach analizy zamiast w jednej wybranej. Wyjaśniamy trzy kroki metody, wykres z dwóch paneli, wnioskowanie łączne, związek z multiverse i przykład w R.

Strona główna / Słownik / Krzywa specyfikacji
W skrócie: Krzywa specyfikacji to analiza, w której hipotezę testuje się we wszystkich uzasadnionych wersjach analizy (specyfikacjach), pokazuje posortowane oszacowania na wykresie z dwóch paneli i wnioskuje łącznie ze wszystkich, zamiast raportować jedną wybraną wersję.

Co to jest krzywa specyfikacji?

Krzywa specyfikacji (ang. specification curve analysis) to metoda, w której tę samą hipotezę testuje się we wszystkich rozsądnych wersjach analizy, a nie w jednej. Wersja, czyli specyfikacja, to zestaw decyzji: jak zmierzyć wynik, które zmienne kontrolować, kogo wykluczyć. Simonsohn, Simmons i Nelson (2020) opisują trzy kroki: wyznaczenie zbioru specyfikacji uzasadnionych teoretycznie, poprawnych statystycznie i nieredundantnych, wykres wyników oraz łączne wnioskowanie ze wszystkich specyfikacji.

Krzywa specyfikacji a multiverse

Pokrewna analiza wieloświatowa (multiverse) Steegen i in. (2016) przelicza wynik we wszystkich zbiorach danych, jakie dają rozsądne decyzje o wykluczeniach, przekształceniach i kodowaniu. Krzywa specyfikacji dokłada do tego standardowy wykres i test łączny. Obie metody są rozbudowaną analizą wrażliwości i jawną odpowiedzią na ukryty p-hacking: zamiast wybierać po cichu jedną ścieżkę, pokazuje się wszystkie.

Wykres z dwóch paneli

Górny panel to oszacowania efektu posortowane od najmniejszego do największego, z zaznaczeniem istotnych. Dolny panel to tabela decyzji: pod każdym punktem kropki pokazują, jakie wybory złożyły się na daną specyfikację. Widać od razu, która decyzja przesuwa wynik.

Przykład

W danych symulowanych (n = 300) porównano 18 specyfikacji: 2 wersje wyniku × 3 zestawy kontroli × 3 progi wykluczania obserwacji odstających. Oszacowania wahały się od 0.076 do 0.253, mediana 0.125, a 12 z 18 było istotnych i dodatnich. Najsilniejsze wyniki dawały modele bez kontroli dochodu, czyli zmiennej zakłócającej. W teście permutacyjnym co najmniej tak dużą medianę dało 1% przetasowanych zbiorów (p = .010), a co najmniej 12 istotnych wyników – 1.2% (p = .012).

Jak opisać w pracy

W analizie krzywej specyfikacji (18 specyfikacji) mediana oszacowań wyniosła 0.125 (zakres 0.076–0.253), a 12 specyfikacji dało istotny dodatni efekt. Test permutacyjny: p = .010 dla mediany. Efekt był słabszy po kontroli dochodu.

Na co uważać

  • To nie wybór „najlepszej” specyfikacji. Raportowanie tylko najsilniejszego wyniku przywraca problem, który metoda ma rozwiązać.
  • Zbiór specyfikacji ustal z góry. Najlepiej w prerejestracji; specyfikacje błędne merytorycznie nie należą do zbioru.
  • Specyfikacje nie są niezależne. Liczby istotnych wyników nie porównuje się z 5%, tylko z rozkładem w danych z wymuszoną hipotezą zerową.

Pełny przykład z wykresem pokazuje wpis Analiza multiverse i krzywa specyfikacji, a szerzej – Analiza wrażliwości w artykule i kryzys replikacyjny.

Przykład reprodukowalny

Krzywa specyfikacji w R

Kod w bazowym R przelicza regresję liniową w 18 specyfikacjach, sortuje wyniki (dane do obu paneli wykresu) i wykonuje uproszczony test permutacyjny: predyktor jest tasowany, a cała krzywa liczona od nowa 500 razy.

18 specyfikacji: wersja wyniku, kontrola, wykluczenia

Dane wejściowe: predyktor x, dwie wersje wyniku (y1, y2), wiek i dochód 300 osób; dochód wiąże się z x i z wynikiem (dane symulowane, set.seed(3401)).

Co odczytać: posortowane oszacowania b i p z decyzjami w kolumnach, medianę, liczbę istotnych dodatnich wyników i ich p z permutacji.

R
set.seed(3401)
n <- 300
wiek <- rnorm(n, 40, 10); dochod <- rnorm(n)
x  <- 0.3 * dochod + rnorm(n)                          # predyktor, np. czas w mediach
y1 <- 0.12 * x + 0.4 * dochod + 0.02 * wiek + rnorm(n) # wynik, wersja 1
y2 <- 0.6 * y1 + rnorm(n, sd = 0.8)                    # wynik, wersja 2 (inna skala)
d <- data.frame(x, y1, y2, wiek, dochod)
spec <- expand.grid(wynik = c("y1", "y2"),
                    kontrola = c("", "+ wiek", "+ wiek + dochod"),
                    odciecie = c(Inf, 3, 2.5), stringsAsFactors = FALSE)
krzywa <- function(d) t(sapply(seq_len(nrow(spec)), function(i) {
  s <- spec[i, ]
  z <- abs(scale(d[[s$wynik]]))
  m <- lm(as.formula(paste(s$wynik, "~ x", s$kontrola)), data = d[z < s$odciecie, ])
  coef(summary(m))["x", c(1, 4)]
}))
w <- krzywa(d)
spec$b <- round(w[, 1], 3); spec$p <- round(w[, 2], 4)
spec <- spec[order(spec$b), ]; rownames(spec) <- NULL
spec                                                   # dane do krzywej (panel górny i dolny)
obs <- c(mediana_b = median(w[, 1]), istotne_dodatnie = sum(w[, 1] > 0 & w[, 2] < .05))
null <- replicate(500, {                               # świat bez efektu: permutacja x
  d0 <- d; d0$x <- sample(d$x)
  w0 <- krzywa(d0)
  c(median(w0[, 1]), sum(w0[, 1] > 0 & w0[, 2] < .05))
})
round(c(obs, p_mediana = mean(abs(null[1, ]) >= abs(obs[1])),
        p_istotne = mean(null[2, ] >= obs[2])), 3)
Wynik w R
   wynik        kontrola odciecie     b      p
1     y2 + wiek + dochod      Inf 0.076 0.1988
2     y2 + wiek + dochod      3.0 0.078 0.1790
3     y2 + wiek + dochod      2.5 0.078 0.1790
4     y1 + wiek + dochod      3.0 0.095 0.0926
5     y1 + wiek + dochod      Inf 0.097 0.0883
6     y1 + wiek + dochod      2.5 0.100 0.0665
7     y2                      3.0 0.124 0.0238
8     y2                      2.5 0.124 0.0238
9     y2          + wiek      3.0 0.125 0.0226
10    y2          + wiek      2.5 0.125 0.0226
11    y2                      Inf 0.126 0.0260
12    y2          + wiek      Inf 0.128 0.0237
13    y1                      2.5 0.237 0.0000
14    y1                      3.0 0.240 0.0000
15    y1          + wiek      2.5 0.242 0.0000
16    y1          + wiek      3.0 0.243 0.0000
17    y1                      Inf 0.250 0.0000
18    y1          + wiek      Inf 0.253 0.0000
       mediana_b istotne_dodatnie        p_mediana        p_istotne
           0.125           12.000            0.010            0.012

Bibliografia oprogramowania

Wyniki pochodzą z uruchomienia pokazanego kodu w R 4.5.3 (funkcje pakietów base i stats). W pracy podaj wersję R, której faktycznie użyto (sessionInfo()).

  1. R: R Core Team. (2026). R: A language and environment for statistical computing (Version 4.5.3) [Computer software]. R Foundation for Statistical Computing. https://www.R-project.org/

Najczęstsze pytania

Czym krzywa specyfikacji różni się od analizy multiverse?

Obie przeliczają wynik we wszystkich rozsądnych wersjach analizy. Multiverse (Steegen i in., 2016) kładzie nacisk na przejrzyste pokazanie zależności od decyzji, a krzywa specyfikacji (Simonsohn i in., 2020) dodaje standardowy wykres i test łączny.

Ile specyfikacji powinno się znaleźć w analizie?

Tyle, ile wynika z rozsądnych, równorzędnych decyzji: zwykle od kilkunastu do kilku tysięcy. Liczy się jakość zbioru, a nie liczba – wersje błędne merytorycznie albo dublujące się pomija się.

Jak zrobić krzywą specyfikacji w R?

Zbuduj siatkę decyzji funkcją expand.grid(), dopasuj model w pętli dla każdego wiersza, posortuj oszacowania i narysuj dwa panele (np. w ggplot2). Test łączny uzyskasz, powtarzając całą krzywą na danych z wymuszoną hipotezą zerową.

Powiązane hasła

Poradniki, w których użyjesz tego pojęcia

Potrzebujesz wsparcia w analizie danych?

Wybierz ofertę dopasowaną do pracy dyplomowej albo profesjonalnego projektu naukowego.

Wyceń analizęOferta dla studentów

Bibliografia i dalsza literatura naukowa (APA 7)

  1. Simonsohn, U., Simmons, J. P., & Nelson, L. D. (2020). Specification curve analysis. Nature Human Behaviour, 4(11), 1208–1214. https://doi.org/10.1038/s41562-020-0912-z
  2. Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W. (2016). Increasing transparency through a multiverse analysis. Perspectives on Psychological Science, 11(5), 702–712. https://doi.org/10.1177/1745691616658637

Cytowania BibTeX

@article{simonsohn2020specification, author={Simonsohn, Uri and Simmons, Joseph P. and Nelson, Leif D.}, title={{Specification curve analysis}}, journal={Nature Human Behaviour}, year={2020}, volume={4}, number={11}, pages={1208--1214}, doi={10.1038/s41562-020-0912-z}}
@article{steegen2016increasing, author={Steegen, Sara and Tuerlinckx, Francis and Gelman, Andrew and Vanpaemel, Wolf}, title={{Increasing transparency through a multiverse analysis}}, journal={Perspectives on Psychological Science}, year={2016}, volume={11}, number={5}, pages={702--712}, doi={10.1177/1745691616658637}}
R