> ## Documentation Index
> Fetch the complete documentation index at: https://kstats.oremif.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Hypothesentests

> t-Tests, ANOVA, Chi-Quadrat, Fisher-Exakttest, Mann-Whitney, Wilcoxon, Normalitätstests und Varianzhomogenitätstests in kstats-hypothesis.

`kstats-hypothesis` stellt statistische Tests bereit, gegliedert nach der Fragestellung, die sie beantworten. Die meisten Funktionen liefern ein `TestResult` zurück; `oneWayAnova()` gibt ein `AnovaResult` mit der vollständigen ANOVA-Tabelle zurück.

## Ein Testergebnis lesen

Jeder Test erzeugt ein Ergebnis mit einheitlicher Struktur. Die `statistic` ist der berechnete Testwert, der `pValue` gibt die Wahrscheinlichkeit an, unter der Nullhypothese ein mindestens so extremes Ergebnis zu beobachten, und `isSignificant()` vergleicht den p-Wert mit einem Schwellenwert.

```kotlin theme={"system"}
val sample = doubleArrayOf(5.0, 6.0, 7.0, 5.5, 6.5)
val result = tTest(sample, mu = 5.0)

result.testName          // "One-Sample T-Test"
result.statistic         // 2.8284
result.pValue            // 0.0474
result.degreesOfFreedom  // 4.0
result.isSignificant()   // true (p < 0.05)
result.confidenceInterval // (5.02, 6.98)
```

<Note>
  `isSignificant()` verwendet standardmäßig $\alpha = 0.05$. Ein anderer Schwellenwert kann explizit übergeben werden: `result.isSignificant(alpha = 0.01)`.
</Note>

<Note>
  Setzen Sie `alternative` explizit für einseitige Tests. Der Standardwert ist `Alternative.TWO_SIDED`. Mit `Alternative.GREATER` wird geprüft, ob der Stichprobenmittelwert den Referenzwert übersteigt; `Alternative.LESS` prüft, ob er darunter liegt.
</Note>

## Unterscheidet sich mein Stichprobenmittelwert von einem Referenzwert?

Der Einstichproben-t-Test vergleicht den Mittelwert einer einzelnen Stichprobe mit einem bekannten oder hypothetischen Wert.

```kotlin theme={"system"}
val sample = doubleArrayOf(5.1, 4.9, 5.3, 5.0, 4.8)

// Two-sided: is the mean different from 5.0?
val two = tTest(sample, mu = 5.0)
two.statistic            // t value
two.pValue               // two-sided p-value

// One-sided: is the mean greater than 5.0?
val one = tTest(sample, mu = 5.0, alternative = Alternative.GREATER)
one.pValue               // one-sided p-value
```

<Tip>
  Verwenden Sie `Alternative.GREATER` oder `Alternative.LESS` für gerichtete Hypothesen, anstatt einen zweiseitigen p-Wert zu halbieren. Das Konfidenzintervall passt sich entsprechend an.
</Tip>

## Unterscheiden sich zwei Gruppen?

### Zweistichproben-t-Test

Vergleicht die Mittelwerte zweier unabhängiger Stichproben. Welchs t-Test (ungleiche Varianzen) ist die Standardeinstellung.

```kotlin theme={"system"}
val group1 = doubleArrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
val group2 = doubleArrayOf(6.0, 7.0, 8.0, 9.0, 10.0)

val result = tTest(group1, group2)
result.statistic         // -5.0
result.pValue            // 0.0011
result.isSignificant()   // true
```

<Warning>
  `equalVariances` ist standardmäßig `false`, d. h. es wird Welchs t-Test verwendet. Setzen Sie `equalVariances = true` nur, nachdem Sie gleiche Varianzen mit `leveneTest()` oder `bartlettTest()` bestätigt haben.
</Warning>

### Gepaarter t-Test

Vergleicht zwei zusammenhängende Messungen (vorher/nachher, links/rechts) an denselben Versuchspersonen.

```kotlin theme={"system"}
val before = doubleArrayOf(200.0, 190.0, 210.0, 180.0, 195.0)
val after = doubleArrayOf(190.0, 180.0, 195.0, 170.0, 185.0)

val result = pairedTTest(before, after)
result.statistic         // positive t (before > after)
result.pValue            // p-value for the difference
result.isSignificant()   // true if the change is significant
```

### Mann-Whitney-U-Test

Nichtparametrische Alternative zum Zweistichproben-t-Test. Vergleicht Ränge statt Mittelwerte.

```kotlin theme={"system"}
val group1 = doubleArrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
val group2 = doubleArrayOf(6.0, 7.0, 8.0, 9.0, 10.0)

val result = mannWhitneyUTest(group1, group2)
result.statistic         // U = 0.0
result.pValue            // < 0.02
result.isSignificant()   // true
```

### Wilcoxon-Vorzeichen-Rang-Test

Nichtparametrische Alternative zum gepaarten t-Test. Prüft, ob gepaarte Differenzen symmetrisch um Null verteilt sind.

```kotlin theme={"system"}
val before = doubleArrayOf(10.0, 12.0, 14.0, 16.0, 18.0)
val after = doubleArrayOf(8.0, 9.0, 11.0, 12.0, 13.0)

val result = wilcoxonSignedRankTest(before, after)
result.statistic         // W+ = 15.0
result.pValue            // p-value with continuity correction
```

## Unterscheiden sich drei oder mehr Gruppen?

### Einfaktorielle ANOVA

Prüft, ob sich die Mittelwerte von drei oder mehr Gruppen unterscheiden. Gibt ein `AnovaResult` mit der vollständigen ANOVA-Tabelle zurück.

```kotlin theme={"system"}
val g1 = doubleArrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
val g2 = doubleArrayOf(6.0, 7.0, 8.0, 9.0, 10.0)
val g3 = doubleArrayOf(11.0, 12.0, 13.0, 14.0, 15.0)

val anova = oneWayAnova(g1, g2, g3)
anova.fStatistic         // 50.0
anova.pValue             // < 0.00001
anova.dfBetween          // 2
anova.dfWithin           // 12
anova.ssBetween          // 250.0
anova.ssWithin           // 30.0
anova.msBetween          // 125.0
anova.msWithin           // 2.5
```

<Note>
  Die ANOVA setzt Normalverteilung innerhalb jeder Gruppe und gleiche Varianzen über alle Gruppen voraus. Prüfen Sie die Normalverteilung mit `shapiroWilkTest()` und die Varianzhomogenität mit `leveneTest()` oder `bartlettTest()`, bevor Sie eine ANOVA durchführen.
</Note>

### Friedman-Test

Nichtparametrische Alternative zur ANOVA mit Messwiederholung. Vergleicht Ränge über verbundene Gruppen.

```kotlin theme={"system"}
val treatment1 = doubleArrayOf(5.0, 6.0, 7.0, 5.5, 6.5)
val treatment2 = doubleArrayOf(4.0, 5.0, 6.0, 4.5, 5.5)
val treatment3 = doubleArrayOf(7.0, 8.0, 9.0, 7.5, 8.5)

val result = friedmanTest(treatment1, treatment2, treatment3)
result.statistic         // Friedman chi-squared
result.pValue            // p-value
```

## Sind meine Daten normalverteilt?

Vier Normalitätstests stehen zur Verfügung. Jeder gibt ein `TestResult` zurück — ein signifikantes Ergebnis (niedriger p-Wert) deutet auf Abweichungen von der Normalverteilung hin.

```kotlin theme={"system"}
val sample = doubleArrayOf(
    -1.2, -0.5, 0.0, 0.5, 1.2, 0.3, -0.1, 0.8, -0.4, 0.6,
    -0.8, 0.2, 0.9, -0.3, 0.4, -0.6, 1.0, -0.9, 0.1, 0.7
)

shapiroWilkTest(sample).pValue       // high p → consistent with normality
andersonDarlingTest(sample).pValue   // high p → consistent with normality
dagostinoPearsonTest(sample).pValue  // combines skewness and kurtosis tests
jarqueBeraTest(sample).pValue        // asymptotic test based on skewness and kurtosis
```

<Tip>
  Der Shapiro-Wilk-Test ist die gebräuchlichste Wahl und in der Regel der stärkste Test für kleine bis mittlere Stichproben (n \< 5000). Der Anderson-Darling-Test ist empfindlicher gegenüber Abweichungen in den Verteilungsrändern. D'Agostino-Pearson und Jarque-Bera sind schneller bei großen Stichproben.
</Tip>

## Stimmen meine beobachteten Häufigkeiten mit erwarteten Anteilen überein?

### Chi-Quadrat-Anpassungstest

Prüft, ob beobachtete Häufigkeiten den erwarteten Häufigkeiten entsprechen.

```kotlin theme={"system"}
val observed = intArrayOf(50, 30, 20)
val expected = doubleArrayOf(40.0, 40.0, 20.0)

val result = chiSquaredTest(observed, expected)
result.statistic         // 5.0
result.pValue            // 0.0821
result.isSignificant()   // false at α = 0.05
```

### G-Test

Likelihood-Ratio-Alternative zum Chi-Quadrat-Test. Oft bevorzugt bei kleinen erwarteten Häufigkeiten.

```kotlin theme={"system"}
val observed = intArrayOf(50, 30, 20)
val expected = doubleArrayOf(40.0, 40.0, 20.0)

val result = gTest(observed, expected)
result.statistic         // G statistic
result.pValue            // p-value
```

### Binomialtest

Prüft, ob der beobachtete Anteil an Erfolgen einer hypothetischen Wahrscheinlichkeit entspricht.

```kotlin theme={"system"}
val result = binomialTest(successes = 60, trials = 100, probability = 0.5)
result.pValue            // p-value for H₀: p = 0.5
result.isSignificant()   // true if 60/100 is significantly different from 0.5
```

### Fisher-Exakttest

Exakter Test für 2x2-Kontingenztafeln. Dem Chi-Quadrat-Test bei kleinen Stichproben vorzuziehen.

```kotlin theme={"system"}
// 2×2 table: [[10, 30], [20, 40]]
val result = fisherExactTest(arrayOf(intArrayOf(10, 30), intArrayOf(20, 40)))
result.pValue            // exact p-value
result.isSignificant()   // true or false
```

<Warning>
  Der Fisher-Exakttest ist für kleine Kontingenztafeln konzipiert. Für größere Tabellen verwenden Sie `chiSquaredTest()` mit einem Chi-Quadrat-Unabhängigkeitstest.
</Warning>

## Haben meine Gruppen gleiche Varianzen?

Varianzhomogenität ist eine Voraussetzung der ANOVA und einiger t-Test-Varianten. Drei Tests stehen zur Verfügung:

```kotlin theme={"system"}
val g1 = doubleArrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
val g2 = doubleArrayOf(2.0, 4.0, 6.0, 8.0, 10.0)
val g3 = doubleArrayOf(1.0, 3.0, 5.0, 7.0, 9.0)

leveneTest(g1, g2, g3).pValue         // robust to non-normality
bartlettTest(g1, g2, g3).pValue       // most powerful when normality holds
flignerKilleenTest(g1, g2, g3).pValue // rank-based, robust to outliers
```

<Tip>
  Der Levene-Test ist die sicherste Standardwahl — er ist robust gegenüber Abweichungen von der Normalverteilung. Verwenden Sie den Bartlett-Test nur, wenn die Daten innerhalb jeder Gruppe annähernd normalverteilt sind (Bartlett ist in diesem Fall leistungsfähiger). Der Fligner-Killeen-Test ist am robustesten gegenüber Ausreißern.
</Tip>

## Passt meine Stichprobe zu einer Referenzverteilung?

### Kolmogorow-Smirnow-Test

Der Zweistichproben-KS-Test prüft, ob zwei Stichproben aus derselben stetigen Verteilung stammen.

```kotlin theme={"system"}
val sample1 = doubleArrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
val sample2 = doubleArrayOf(1.5, 2.5, 3.5, 4.5, 5.5)

val result = kolmogorovSmirnovTest(sample1, sample2)
result.statistic         // D = max difference between ECDFs
result.pValue            // p-value
```

## Sind Beobachtungen Ausreißer?

### Grubbs-Test

Der Grubbs-Test (Extreme Studentized Deviate Test) prüft formell, ob die am weitesten vom Mittelwert entfernte Beobachtung ein Ausreißer ist, vorausgesetzt, die übrigen Daten sind näherungsweise normalverteilt. Die Teststatistik lautet

$$
G = \frac{\max_{i} |x_i - \bar{x}|}{s},
$$

umgerechnet in eine Student-$t$-Statistik mit $N - 2$ Freiheitsgraden und Bonferroni-korrigiert dafür, dass jede Beobachtung getestet wurde.

```kotlin theme={"system"}
// Response times (ms) with a suspected outlier
val latencies = doubleArrayOf(12.0, 14.0, 11.0, 13.0, 15.0, 98.0, 12.0)

val result = grubbsTest(latencies)
result.statistic                       // G statistic
result.pValue                          // Bonferroni-corrected p-value
result.additionalInfo["outlierIndex"]  // index of the suspected outlier
result.additionalInfo["outlierValue"]  // the suspected outlier's value
result.isSignificant()                 // true if outlier is significant at α = 0.05
```

Verwenden Sie `Alternative.GREATER` oder `Alternative.LESS`, um nur einen Tail zu testen, wenn Sie ausschließlich an einem auffällig großen bzw. kleinen Wert interessiert sind:

```kotlin theme={"system"}
// Only test for a suspiciously large value (upper tail)
val data = doubleArrayOf(2.1, 2.5, 2.3, 2.8, 10.0, 2.4, 2.2)
val upper = grubbsTest(data, alternative = Alternative.GREATER)
upper.additionalInfo["outlierValue"] // 10.0 — the maximum

// Only test for a suspiciously small value (lower tail)
val dataLow = doubleArrayOf(2.1, 2.5, 2.3, 2.8, -5.0, 2.4, 2.2)
val lower = grubbsTest(dataLow, alternative = Alternative.LESS)
lower.additionalInfo["outlierValue"] // -5.0 — the minimum
```

Für mehrere Ausreißer wendet `grubbsTestIterative()` den Test wiederholt an und entfernt jeweils einen signifikanten Ausreißer, bis keiner mehr übrig ist oder die Stichprobe unter drei Beobachtungen fällt.

```kotlin theme={"system"}
// Remove multiple outliers by repeatedly applying the test
val data = doubleArrayOf(10.0, 11.0, 12.0, 13.0, 14.0, 80.0, 90.0)
val cleaned = grubbsTestIterative(data, alpha = 0.05)

cleaned.outlierIndices // indices (in the original array) that were removed
cleaned.cleanedData    // observations after removing all detected outliers
cleaned.iterations     // TestResult from each round (last one is non-significant)
```

<Tip>
  Der Grubbs-Test setzt voraus, dass die Daten bis auf den Ausreißer näherungsweise normalverteilt sind. Validieren Sie mit `shapiroWilkTest()` an den Daten nach Entfernen des Verdächtigen, bevor Sie ein signifikantes Ergebnis berichten.
</Tip>

<Warning>
  Das iterative Verfahren kann Ausreißer **maskieren**, wenn mehrere Extreme zusammenliegen — jeder Einzeltest wird durch seine Nachbarn verdünnt. Bevorzugen Sie bei großen Clustern einen speziellen Mehrfach-Ausreißer-Test (z. B. verallgemeinertes ESD) oder einen robusten Schätzer.
</Warning>

## Die Alternative-Aufzählung

`Alternative` steuert die Richtung des Tests:

| Wert        | Bedeutung                                                                           |
| ----------- | ----------------------------------------------------------------------------------- |
| `TWO_SIDED` | Prüft, ob der Parameter in beliebiger Richtung vom Referenzwert abweicht (Standard) |
| `GREATER`   | Prüft, ob der Parameter den Referenzwert übersteigt                                 |
| `LESS`      | Prüft, ob der Parameter unter dem Referenzwert liegt                                |

Gerichtete Alternativen werden von `tTest`, `pairedTTest`, `mannWhitneyUTest`, `wilcoxonSignedRankTest` und `binomialTest` unterstützt.

## API-Referenz

<Card title="Vollständige API-Referenz" icon="book-open" href="https://oremif.github.io/kstats">
  Alle Testfunktionen, Ergebnistypen und Parameterüberladungen in der Dokka-generierten Referenz durchsuchen.
</Card>
