Der Kolmogorov-Smirnov-Test: Datenverteilungen analysieren

Im Bereich der Datenanalyse und Statistik ist das Verständnis der zugrunde liegenden Verteilung von Daten von entscheidender Bedeutung. Entwickler, Datenwissenschaftler und Ingenieure verlassen sich auf robuste statistische Methoden, um Annahmen zu überprüfen, Modelle zu validieren und fundierte Entscheidungen zu treffen. Eines dieser grundlegenden Werkzeuge ist der Kolmogorov-Smirnov-Test, oft abgekürzt als KS-Test, ein leistungsstarker, nichtparametrischer Test zur Verteilungsprüfung.

Dieser ausführliche Blogbeitrag taucht tief in die Materie ein, beginnend mit der faszinierenden Entstehungsgeschichte dieses Tests. Wir werden die Schlüsselkonzepte hinter der empirischen kumulativen Verteilung (EKV) und der theoretischen kumulativen Verteilung (TKV) detailliert beleuchten, die Teststatistik D und den entscheidenden P-Wert erklären. Weiterhin werden wir die vielfältigen Anwendungsgebiete des Kolmogorov-Smirnov-Tests in der modernen Data Science, dem Machine Learning und der Softwareentwicklung untersuchen. Praktische Codebeispiele in Python werden Ihnen dabei helfen, die Implementierung zu verstehen und den Test effektiv für die Prüfung der Normalität von Daten, den Vergleich zweier Stichprobenverteilungen oder die Modellvalidierung anzuwenden.

Grundlagen und Funktionsweise des Kolmogorov-Smirnov-Tests

Die Geschichte des Kolmogorov-Smirnov-Tests ist eine bemerkenswerte Anekdote wissenschaftlicher Konvergenz. Im Jahr 1933 veröffentlichte der brillante russische Mathematiker Andrei Kolmogorov seinen wegweisenden Artikel „Sulla determinazione empirica di una legge di distribuzione“. Darin stellte er das Konzept der empirischen kumulativen Verteilung (EKV) vor und entwickelte eine entsprechende Teststatistik. Sein Hauptanliegen war es, eine Methode zu finden, um beobachtete Daten mit einer hypothetischen theoretischen Verteilung zu vergleichen, ohne dabei spezielle Annahmen über die Form dieser Verteilung machen zu müssen. Kolmogorovs Ansatz basierte auf der maximalen Abweichung zwischen der EKV und der theoretischen kumulativen Verteilung (TKV), die er durch eine präzise Teststatistik quantifizierte.

Unabhängig davon und einige Jahre später, im Jahr 1939, verfolgte ein weiterer russischer Mathematiker, Nikolai Smirnov, einen ähnlichen Forschungszweig. Sein Artikel „Schätzung der Differenz zwischen empirischen Verteilungsfunktionen in zwei unabhängigen Stichproben“ befasste sich mit dem Problem, zwei unabhängige Stichproben nichtparametrisch zu vergleichen. Smirnov entwickelte ebenfalls eine Teststatistik, die auf der maximalen Differenz zwischen den kumulativen Verteilungen der beiden Datenproben beruhte. Es war ein glücklicher Zufall, dass sich die beiden Wissenschaftler auf einer Mathematikkonferenz trafen. Beim Austausch ihrer Forschungsergebnisse stellten sie mit Erstaunen fest, dass sie an fast identischen Problemen gearbeitet und unabhängig voneinander extrem ähnliche Methoden und Formeln entwickelt hatten. Diese zufällige Begegnung führte zu ihrer Zusammenarbeit und zur Konsolidierung ihrer Ideen in dem heute bekannten und weit verbreiteten Kolmogorov-Smirnov-Test.

Der Kolmogorov-Smirnov-Test ist ein mächtiges statistisches Instrument, das in zahlreichen Disziplinen eingesetzt wird. Er dient primär dazu, die Ähnlichkeit zwischen einer empirischen Verteilung, die aus beobachteten Daten abgeleitet wird, und einer vordefinierten theoretischen Verteilung zu bewerten. Alternativ kann er auch verwendet werden, um die Ähnlichkeit zwischen den Verteilungen zweier unabhängiger Stichproben zu vergleichen. Seine Stärke liegt in seiner nichtparametrischen Natur, was bedeutet, dass er keine spezifischen Annahmen über die zugrunde liegende Verteilungsform der Daten erfordert, im Gegensatz zu parametrischen Tests wie dem t-Test oder dem ANOVA.

Der Test basiert auf zwei fundamentalen Konzepten: der empirischen kumulativen Verteilung (EKV) und der theoretischen kumulativen Verteilung (TKV). Die EKV wird direkt aus den gesammelten Daten konstruiert und stellt den Anteil der Beobachtungen dar, die kleiner oder gleich einem bestimmten Wert sind. Sie ist im Wesentlichen eine Treppenfunktion, die bei jedem beobachteten Datenpunkt einen Sprung macht. Die TKV hingegen ist die kumulative Verteilungsfunktion einer hypothetischen, vom Anwender festgelegten theoretischen Verteilung, wie zum Beispiel einer Normalverteilung, einer Exponentialverteilung oder einer Uniformverteilung.

Das Kernziel des KS-Tests ist es, den maximalen Abstand zwischen der EKV und der TKV zu quantifizieren. Dieser maximale Abstand wird als Teststatistik D bezeichnet und ist ein Maß dafür, wie stark die beobachteten Daten von der angenommenen theoretischen Verteilung abweichen. D wird berechnet, indem der absolute Wert der größten Differenz zwischen den beiden kumulativen Verteilungen über alle Datenpunkte hinweg ermittelt wird. Ein höherer Wert von D deutet auf eine größere Diskrepanz zwischen der empirischen und der theoretischen Verteilung hin.

Um die statistische Signifikanz dieses Abstands zu beurteilen, wird ein P-Wert berechnet. Der P-Wert ist die Wahrscheinlichkeit, einen Wert für D zu erhalten, der genauso extrem oder extremer ist als der beobachtete Wert, unter der Annahme, dass die Nullhypothese zutrifft. Die Nullhypothese (H0) des Kolmogorov-Smirnov-Tests besagt, dass die empirische Stichprobenverteilung von der theoretischen Verteilung nicht signifikant abweicht oder dass die beiden Stichproben aus der gleichen Verteilung stammen. Die Alternativhypothese (H1) postuliert, dass ein signifikanter Unterschied besteht. Wenn der P-Wert unter einem vordefinierten Signifikanzniveau (Alpha, z.B. 0.05) liegt, wird die Nullhypothese verworfen, was darauf hindeutet, dass die beobachteten Unterschiede wahrscheinlich nicht zufällig sind und die Verteilungen unvereinbar sind.

„Die Eleganz des Kolmogorov-Smirnov-Tests liegt in seiner Fähigkeit, tiefgreifende Fragen über Datenverteilungen zu beantworten, ohne dass man sich in starren parametrischen Annahmen verfangen muss – ein echter Segen für die robuste Datenanalyse.“

Die Empirische und Theoretische Kumulative Verteilung (EKV und TKV)

Die empirische kumulative Verteilung (EKV) ist ein grundlegendes Konzept im Kolmogorov-Smirnov-Test und bietet eine direkte Möglichkeit, die Verteilung einer beobachteten Datenstichprobe zu visualisieren und zu quantifizieren. Für eine gegebene Stichprobe von n Beobachtungen (x_1, x_2, …, x_n) wird die EKV, oft als F_n(x) bezeichnet, als der Anteil der Beobachtungen in der Stichprobe definiert, die kleiner oder gleich einem bestimmten Wert x sind. Mathematisch lässt sie sich als:

F_n(x) = (Anzahl der Beobachtungen <= x) / n

darstellen. Die EKV ist eine Treppenfunktion, die bei jedem einzigartigen Datenwert um 1/n ansteigt. Sie liefert eine nichtparametrische Schätzung der zugrunde liegenden kumulativen Verteilungsfunktion der Population, aus der die Stichprobe gezogen wurde.

Die theoretische kumulative Verteilung (TKV), oft F(x) genannt, ist die kumulative Verteilungsfunktion einer hypothetischen Verteilung, mit der wir unsere empirischen Daten vergleichen möchten. Dies könnte eine Normalverteilung mit bestimmten Parametern (Mittelwert und Standardabweichung), eine Exponentialverteilung, eine Uniformverteilung oder jede andere bekannte Wahrscheinlichkeitsverteilung sein. Die TKV ist eine glatte Funktion (im Falle kontinuierlicher Verteilungen) und stellt die erwartete kumulative Wahrscheinlichkeit dar, dass eine Beobachtung kleiner oder gleich x ist, wenn die Daten tatsächlich dieser theoretischen Verteilung folgen würden.

Die Visualisierung dieser beiden Funktionen ist oft sehr aufschlussreich. Wenn die EKV der TKV eng folgt, deutet dies darauf hin, dass die empirischen Daten gut zur theoretischen Verteilung passen. Große Abweichungen, insbesondere die maximale vertikale Distanz zwischen den beiden Kurven, sind der Kern der Teststatistik D.

Betrachten wir ein einfaches Python-Beispiel zur Berechnung und Darstellung der EKV:

import numpy as np
import matplotlib.pyplot as plt

# Beispieldaten
data = np.array([2.1, 3.5, 1.8, 4.2, 2.9, 3.1, 2.5, 3.8])
data_sorted = np.sort(data) # Daten sortieren ist für EKV wichtig
n = len(data_sorted)

# Werte für die EKV
y_ekv = np.arange(1, n + 1) / n

# Funktion zur EKV-Berechnung und Visualisierung
def plot_ekv(data, label='Empirische KVF'):
    data_sorted = np.sort(data)
    n = len(data_sorted)
    y_ekv = np.arange(1, n + 1) / n
    
    plt.step(data_sorted, y_ekv, where='post', label=label)
    plt.xlabel('Datenwert x')
    plt.ylabel('F(x) - Kumulative Wahrscheinlichkeit')
    plt.title('Empirische Kumulative Verteilungsfunktion (EKV)')
    plt.grid(True)
    plt.legend()

plt.figure(figsize=(10, 6))
plot_ekv(data)
plt.show()

Die Teststatistik D und der P-Wert

Die Teststatistik D ist das Herzstück des Kolmogorov-Smirnov-Tests. Sie misst die maximale absolute vertikale Distanz zwischen der empirischen kumulativen Verteilungsfunktion (EKV) und der theoretischen kumulativen Verteilungsfunktion (TKV). Formal wird D wie folgt definiert:

D = max_x |F_n(x) – F(x)|

wobei F_n(x) die EKV und F(x) die TKV ist. Diese maximale Differenz wird über alle möglichen Werte von x gesucht. Ein großer Wert von D weist darauf hin, dass die empirische Verteilung erheblich von der theoretischen Verteilung abweicht.

Der P-Wert ist der entscheidende Indikator für die statistische Signifikanz des Testergebnisses. Er quantifiziert die Wahrscheinlichkeit, dass die beobachtete maximale Differenz D oder eine noch größere Differenz zufällig auftritt, wenn die Nullhypothese wahr ist (d.h., wenn die Daten tatsächlich der theoretischen Verteilung folgen). Ein kleiner P-Wert (typischerweise kleiner als das vorher festgelegte Signifikanzniveau α, z.B. 0.05) legt nahe, dass die beobachteten Daten wahrscheinlich nicht aus der angenommenen theoretischen Verteilung stammen, und führt zur Ablehnung der Nullhypothese. Ein großer P-Wert hingegen bedeutet, dass kein ausreichender Beweis vorliegt, um die Nullhypothese abzulehnen, und die Daten sind konsistent mit der theoretischen Verteilung.

Obwohl die manuelle Berechnung von D für große Datensätze aufwendig ist, ist das zugrundeliegende Prinzip einfach. Hier ein konzeptionelles Beispiel:

# Konzeptionelles Beispiel für D-Berechnung
# Angenommen, wir haben eine sortierte Datenstichprobe und eine TKV.
# Für jeden Punkt x_i in den sortierten Daten:
#   EKV(x_i) = i/n
#   TKV(x_i) = F(x_i), wobei F die CDF der theoretischen Verteilung ist.
#   Wir berechnen die absolute Differenz |EKV(x_i) - TKV(x_i)|
#   Wir berechnen auch die absolute Differenz |EKV(x_i-1) - TKV(x_i)|, da die EKV
#   vor x_i konstant ist und bei x_i springt. D ist das Maximum dieser Differenzen.

# Beispiel: Daten = [1, 2, 3], n = 3. Vergleich mit einer theoretischen Uniform(0,4)
# TKV für Uniform(0,4): F(x) = x/4 für 0 <= x <= 4

# x=1:
#   EKV(1) = 1/3
#   TKV(1) = 1/4
#   |1/3 - 1/4| = 1/12
# x=2:
#   EKV(2) = 2/3
#   TKV(2) = 2/4 = 1/2
#   |2/3 - 1/2| = 1/6
# x=3:
#   EKV(3) = 3/3 = 1
#   TKV(3) = 3/4
#   |1 - 3/4| = 1/4

# Die Teststatistik D wäre das Maximum dieser Differenzen. In diesem stark
# vereinfachten Beispiel wäre D = 1/4. In der Praxis werden exakte Werte
# für D von Bibliotheken berechnet, die auch die Sprungstellen berücksichtigen.

Hypothesenformulierung im Kolmogorov-Smirnov-Test

Die präzise Formulierung der Null- und Alternativhypothesen ist entscheidend für das korrekte Verständnis und die Interpretation des Kolmogorov-Smirnov-Tests. Der Test kann in zwei Hauptvarianten angewendet werden:

1. Ein-Stichproben-Kolmogorov-Smirnov-Test (Goodness-of-Fit-Test): Dieser Test wird verwendet, um zu überprüfen, ob eine einzelne Stichprobe aus einer bestimmten hypothetischen Verteilung stammt.

  • Nullhypothese (H0): Die Daten stammen aus der spezifizierten theoretischen Verteilung (z.B. Normalverteilung, Exponentialverteilung, etc.). Formal: F_n(x) = F(x) für alle x.
  • Alternativhypothese (H1): Die Daten stammen nicht aus der spezifizierten theoretischen Verteilung. Formal: F_n(x) ≠ F(x) für mindestens ein x.

2. Zwei-Stichproben-Kolmogorov-Smirnov-Test: Dieser Test wird verwendet, um zu überprüfen, ob zwei unabhängige Stichproben aus derselben Verteilung stammen (unabhängig davon, welche das ist).

  • Nullhypothese (H0): Die beiden Stichproben stammen aus derselben Verteilung. Formal: F_n1(x) = F_n2(x) für alle x.
  • Alternativhypothese (H1): Die beiden Stichproben stammen aus unterschiedlichen Verteilungen. Formal: F_n1(x) ≠ F_n2(x) für mindestens ein x.

Die Wahl der richtigen Hypothese ist entscheidend, da sie die Interpretation des P-Wertes direkt beeinflusst. In Python können diese Tests einfach mit der `scipy.stats`-Bibliothek durchgeführt werden:

from scipy import stats
import numpy as np

# Ein-Stichproben-KS-Test Beispiel: Prüfen auf Normalverteilung
np.random.seed(42)
data_sample = np.random.normal(loc=0, scale=1, size=100) # Stichprobe aus Normalverteilung

# Führen Sie den KS-Test gegen eine Normalverteilung durch
# 'norm' ist für die Standard-Normalverteilung (Mittelwert=0, Standardabweichung=1)
# Für eine beliebige Normalverteilung: `stats.kstest(data_sample, 'norm', args=(mean, std))`
stat_one_sample, p_value_one_sample = stats.kstest(data_sample, 'norm')

print(f"Ein-Stichproben-KS-Test (Normalverteilung):")
print(f"  Teststatistik D: {stat_one_sample:.4f}")
print(f"  P-Wert: {p_value_one_sample:.4f}")

if p_value_one_sample > 0.05:
    print("  P-Wert > 0.05: Nullhypothese kann nicht abgelehnt werden. Daten sind konsistent mit einer Normalverteilung.")
else:
    print("  P-Wert  0.05:
    print("  P-Wert > 0.05: Nullhypothese kann nicht abgelehnt werden. Die Stichproben stammen möglicherweise aus der gleichen Verteilung.")
else:
    print("  P-Wert <= 0.05: Nullhypothese wird abgelehnt. Die Stichproben stammen wahrscheinlich aus unterschiedlichen Verteilungen.")

Praktische Anwendungen des Kolmogorov-Smirnov-Tests

Die Vielseitigkeit des Kolmogorov-Smirnov-Tests macht ihn zu einem unverzichtbaren Werkzeug in der Praxis der Datenanalyse. Von den Sozialwissenschaften über die Wirtschaft und Biologie bis hin zur Physik, dem Ingenieurwesen und der modernen Informationstechnologie – die Fähigkeit, Verteilungen objektiv zu vergleichen, ist von enormer Bedeutung. Insbesondere in der Data Science, dem Machine Learning und der Künstlichen Intelligenz dient er nicht nur der grundlegenden Datenprüfung, sondern auch komplexeren Aufgaben wie der Modellvalidierung und der Feature-Auswahl.

Prüfung der Normalität von Daten

Eine der häufigsten Anwendungen des Kolmogorov-Smirnov-Tests ist die Überprüfung, ob eine gegebene Stichprobe aus einer Normalverteilung stammt. Viele statistische Modelle und Verfahren, insbesondere parametrische Tests, setzen eine Normalverteilung der Daten voraus. Wenn diese Annahme verletzt wird, können die Ergebnisse dieser Tests irreführend sein. Der KS-Test bietet eine robuste Möglichkeit, diese Annahme zu überprüfen, indem er die empirische Verteilung der Daten mit der kumulativen Verteilungsfunktion einer theoretischen Normalverteilung vergleicht.

Ein Beispiel in Python, das zeigt, wie man eine Datenstichprobe auf Normalität prüft:

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# 1. Daten, die einer Normalverteilung ähneln sollten
data_normal = np.random.normal(loc=10, scale=2, size=200)

# 2. Daten, die KEINER Normalverteilung folgen (z.B. Exponentialverteilung)
data_exponential = np.random.exponential(scale=2, size=200)

# KS-Test für Normalverteilung (Mittelwert und Standardabweichung der Stichprobe als Argumente verwenden)
# Achtung: Wenn Sie die Parameter der Normalverteilung aus den Daten schätzen,
# müssen Sie berücksichtigen, dass der P-Wert konservativer sein kann.
# Für eine genauere Prüfung mit geschätzten Parametern gibt es den Lilliefors-Test.
# Hier verwenden wir die geschätzten Parameter der Stichprobe für 'norm'.
mean_normal, std_normal = np.mean(data_normal), np.std(data_normal)
ks_stat_normal, p_value_normal = stats.kstest(data_normal, 'norm', args=(mean_normal, std_normal))

print(f"Test auf Normalität für 'data_normal':")
print(f"  Teststatistik D: {ks_stat_normal:.4f}")
print(f"  P-Wert: {p_value_normal:.4f}")
if p_value_normal > 0.05:
    print("  => Die Daten sind konsistent mit einer Normalverteilung (H0 kann nicht abgelehnt werden).")
else:
    print("  => Die Daten weichen signifikant von einer Normalverteilung ab (H0 wird abgelehnt).")

print("n" + "="50 + "n")

# KS-Test für Normalverteilung für 'data_exponential'
mean_exp, std_exp = np.mean(data_exponential), np.std(data_exponential)
ks_stat_exp, p_value_exp = stats.kstest(data_exponential, 'norm', args=(mean_exp, std_exp))

print(f"Test auf Normalität für 'data_exponential':")
print(f"  Teststatistik D: {ks_stat_exp:.4f}")
print(f"  P-Wert: {p_value_exp:.4f}")
if p_value_exp > 0.05:
    print("  => Die Daten sind konsistent mit einer Normalverteilung (H0 kann nicht abgelehnt werden).")
else:
    print("  => Die Daten weichen signifikant von einer Normalverteilung ab (H0 wird abgelehnt).")

# Optional: Visualisierung der EKV gegen TKV
def plot_ks_test(data, theoretical_dist_name, theoretical_args=()):
    data_sorted = np.sort(data)
    n = len(data_sorted)
    y_ekv = np.arange(1, n + 1) / n

    plt.figure(figsize=(10, 6))
    plt.step(data_sorted, y_ekv, where='post', label='Empirische KVF')

    # Erstelle die theoretische KVF
    if theoretical_dist_name == 'norm':
        loc, scale = theoretical_args
        x_theo = np.linspace(data_sorted.min(), data_sorted.max(), 500)
        y_tkv = stats.norm.cdf(x_theo, loc=loc, scale=scale)
    elif theoretical_dist_name == 'expon':
        loc, scale = theoretical_args
        x_theo = np.linspace(data_sorted.min(), data_sorted.max(), 500)
        y_tkv = stats.expon.cdf(x_theo, loc=loc, scale=scale)
    # Weitere Distributionen können hier hinzugefügt werden

    plt.plot(x_theo, y_tkv, label=f'Theoretische KVF ({theoretical_dist_name})', color='red', linestyle='--')
    plt.xlabel('Datenwert x')
    plt.ylabel('Kumulative Wahrscheinlichkeit')
    plt.title(f'Kolmogorov-Smirnov Test: EKV vs. TKV ({theoretical_dist_name})')
    plt.grid(True)
    plt.legend()
    plt.show()

# Visualisierung für data_normal
# plot_ks_test(data_normal, 'norm', theoretical_args=(mean_normal, std_normal))

# Visualisierung für data_exponential
# plot_ks_test(data_exponential, 'norm', theoretical_args=(mean_exp, std_exp)) # Hier prüfen wir bewusst gegen 'norm'
# plot_ks_test(data_exponential, 'expon', theoretical_args=(0, mean_exp)) # Und hier gegen eine Exponentialverteilung

Vergleich zweier Stichprobenverteilungen

Ein weiterer wichtiger Anwendungsfall ist der Vergleich zweier unabhängiger Stichproben. Dies ist besonders nützlich in Experimenten, A/B-Tests, Qualitätskontrollen oder überall dort, wo man feststellen möchte, ob zwei Datensätze aus derselben Grundgesamtheit stammen oder ob es signifikante Unterschiede in ihren Verteilungen gibt. Zum Beispiel könnte man testen, ob zwei verschiedene Produktionslinien Produkte mit der gleichen Verteilung von Qualitätsmerkmalen liefern oder ob eine neue Behandlungsform die Verteilung der Genesungszeiten im Vergleich zu einer Kontrollgruppe verändert hat.

Der Zwei-Stichproben-KS-Test vergleicht die EKV der ersten Stichprobe mit der EKV der zweiten Stichprobe und berechnet die maximale absolute Differenz zwischen ihnen. Ein kleines P-Wert würde darauf hindeuten, dass die beiden Stichproben wahrscheinlich aus unterschiedlichen Verteilungen stammen.

Hier ist ein Python-Beispiel, das zwei Stichproben miteinander vergleicht:

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# Stichprobe A: Daten aus einer Normalverteilung
sample_a = np.random.normal(loc=5, scale=1, size=150)

# Stichprobe B: Daten aus einer leicht verschobenen Normalverteilung
sample_b = np.random.normal(loc=5.5, scale=1, size=180)

# Stichprobe C: Daten aus einer anderen Verteilung (z.B. Uniform)
sample_c = np.random.uniform(low=4, high=7, size=150)

# Vergleich von Stichprobe A und Stichprobe B
ks_stat_ab, p_value_ab = stats.ks_2samp(sample_a, sample_b)

print(f"Vergleich von Stichprobe A und Stichprobe B:")
print(f"  Teststatistik D: {ks_stat_ab:.4f}")
print(f"  P-Wert: {p_value_ab:.4f}")
if p_value_ab > 0.05:
    print("  => H0 kann nicht abgelehnt werden. Die Stichproben A und B stammen möglicherweise aus der gleichen Verteilung.")
else:
    print("  => H0 wird abgelehnt. Die Stichproben A und B stammen wahrscheinlich aus unterschiedlichen Verteilungen.")

print("n" + "="50 + "n")

# Vergleich von Stichprobe A und Stichprobe C
ks_stat_ac, p_value_ac = stats.ks_2samp(sample_a, sample_c)

print(f"Vergleich von Stichprobe A und Stichprobe C:")
print(f"  Teststatistik D: {ks_stat_ac:.4f}")
print(f"  P-Wert: {p_value_ac:.4f}")
if p_value_ac > 0.05:
    print("  => H0 kann nicht abgelehnt werden. Die Stichproben A und C stammen möglicherweise aus der gleichen Verteilung.")
else:
    print("  => H0 wird abgelehnt. Die Stichproben A und C stammen wahrscheinlich aus unterschiedlichen Verteilungen.")


# Optional: Visualisierung der EKVs für den Zwei-Stichproben-Test
def plot_ks_2samp_test(data1, data2, label1='Stichprobe 1', label2='Stichprobe 2'):
    data1_sorted = np.sort(data1)
    data2_sorted = np.sort(data2)
    n1 = len(data1_sorted)
    n2 = len(data2_sorted)

    y_ekv1 = np.arange(1, n1 + 1) / n1
    y_ekv2 = np.arange(1, n2 + 1) / n2

    plt.figure(figsize=(10, 6))
    plt.step(data1_sorted, y_ekv1, where='post', label=label1)
    plt.step(data2_sorted, y_ekv2, where='post', label=label2, color='red', linestyle='--')

    plt.xlabel('Datenwert x')
    plt.ylabel('Kumulative Wahrscheinlichkeit')
    plt.title('Kolmogorov-Smirnov Test: Vergleich zweier EKVs')
    plt.grid(True)
    plt.legend()
    plt.show()

# plot_ks_2samp_test(sample_a, sample_b, 'Normal (loc=5)', 'Normal (loc=5.5)')
# plot_ks_2samp_test(sample_a, sample_c, 'Normal (loc=5)', 'Uniform (4-7)')

Modellvalidierung und Anomalieerkennung

Im Bereich des Machine Learning und der Statistik ist der Kolmogorov-Smirnov-Test ein nützliches Werkzeug zur Modellvalidierung. Man kann beispielsweise prüfen, ob die Residuen eines Regressionsmodells einer Normalverteilung folgen, was oft eine Annahme für die Gültigkeit von Konfidenzintervallen und Hypothesentests ist. Wenn die Residuen nicht normalverteilt sind, könnte dies auf Mängel im Modell oder das Vorhandensein von Nicht-Linearitäten hindeuten, die nicht erfasst wurden. Indem man die EKV der Residuen mit einer theoretischen Normalverteilung vergleicht, lassen sich potenzielle Modellfehler oder Verzerrungen identifizieren.

Darüber hinaus kann der KS-Test indirekt zur Anomalieerkennung genutzt werden. Wenn man eine Baseline-Verteilung von Daten unter normalen Bedingungen kennt, kann man kontinuierlich neue eingehende Datenstichproben mit dieser Baseline vergleichen. Ein signifikanter P-Wert des KS-Tests würde darauf hinweisen, dass die neue Stichprobe eine andere Verteilung aufweist als die normale Baseline, was auf eine Anomalie oder eine Veränderung im System hindeuten könnte.

Obwohl es für die direkte Anomalieerkennung oft spezialisiertere Algorithmen gibt, bietet der KS-Test einen schnellen und robusten statistischen Indikator für Abweichungen in der Datenverteilung, der in verschiedenen Ingenieur- und Softwareentwicklungskontexten wertvoll sein kann, etwa bei der Überwachung von Sensordaten, Netzwerkverkehr oder Systemprotokollen.

Konzeptionelles Beispiel für Modellvalidierung mittels Residuen-Analyse:

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

# 1. Annahme: Wir haben ein Modell, das Vorhersagen (y_pred) für tatsächliche Werte (y_true) liefert.
# Fiktive Daten für tatsächliche und vorhergesagte Werte
np.random.seed(42)
y_true = np.random.normal(loc=100, scale=10, size=200)
# Modell mit zufälligem Rauschen, das (hoffentlich) normalverteilt ist
y_pred_good_model = y_true + np.random.normal(loc=0, scale=1, size=200)
# Modell mit verzerrtem Rauschen (z.B. schief oder mit Ausreißern)
y_pred_bad_model = y_true + np.random.exponential(scale=2, size=200) - 2 # Verschiebung für Mittelwertnähe

# 2. Berechnung der Residuen
residuals_good = y_true - y_pred_good_model
residuals_bad = y_true - y_pred_bad_model

# 3. Prüfung der Residuen auf Normalverteilung mit dem KS-Test
# Für eine gute Modellierung sollten Residuen nahe an einer Normalverteilung um den Mittelwert 0 liegen.
# Wir verwenden die geschätzten Parameter der Residuen für den Vergleich.
mean_res_good, std_res_good = np.mean(residuals_good), np.std(residuals_good)
ks_stat_good, p_value_good = stats.kstest(residuals_good, 'norm', args=(mean_res_good, std_res_good))

print(f"KS-Test für Residuen des 'guten' Modells (Erwartung: Normalverteilung):")
print(f"  Teststatistik D: {ks_stat_good:.4f}")
print(f"  P-Wert: {p_value_good:.4f}")
if p_value_good > 0.05:
    print("  => H0 kann nicht abgelehnt werden. Residuen sind konsistent mit Normalverteilung.")
else:
    print("  => H0 wird abgelehnt. Residuen weichen signifikant von Normalverteilung ab.")

print("n" + "="50 + "n")

mean_res_bad, std_res_bad = np.mean(residuals_bad), np.std(residuals_bad)
ks_stat_bad, p_value_bad = stats.kstest(residuals_bad, 'norm', args=(mean_res_bad, std_res_bad))

print(f"KS-Test für Residuen des 'schlechten' Modells (Erwartung: Abweichung von Normalverteilung):")
print(f"  Teststatistik D: {ks_stat_bad:.4f}")
print(f"  P-Wert: {p_value_bad:.4f}")
if p_value_bad > 0.05:
    print("  => H0 kann nicht abgelehnt werden. Residuen sind konsistent mit Normalverteilung.")
else:
    print("  => H0 wird abgelehnt. Residuen weichen signifikant von Normalverteilung ab.")

# Optional: Histogramme der Residuen zur visuellen Prüfung
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.hist(residuals_good, bins=30, density=True, alpha=0.6, color='g')
plt.title('Residuen des "guten" Modells')
plt.xlabel('Residuenwert')
plt.ylabel('Dichte')

plt.subplot(1, 2, 2)
plt.hist(residuals_bad, bins=30, density=True, alpha=0.6, color='r')
plt.title('Residuen des "schlechten" Modells')
plt.xlabel('Residuenwert')
plt.ylabel('Dichte')
plt.tight_layout()
plt.show()

Der Kolmogorov-Smirnov-Test in der modernen Datenwelt

Der Kolmogorov-Smirnov-Test bleibt ein Eckpfeiler in der Welt der Statistik und Datenanalyse. Seine Eleganz und seine nichtparametrische Natur machen ihn zu einem bevorzugten Werkzeug, wenn es darum geht, fundierte Aussagen über Datenverteilungen zu treffen, ohne dabei an strenge parametrische Annahmen gebunden zu sein. Für Entwickler, Studenten und Technologiebegeisterte bietet der KS-Test einen unschätzbaren Einblick in die Beschaffenheit ihrer Daten und ist ein entscheidender Baustein für solide Modellvalidierung und tiefgehende statistische Untersuchungen.

Wir haben die historische Entwicklung, die mathematischen Grundlagen und die breite Palette an praktischen Anwendungen des Kolmogorov-Smirnov-Tests beleuchtet. Seine Relevanz in Bereichen wie der Prüfung auf Normalität, dem Vergleich zweier Stichprobenverteilungen und der Anomalieerkennung in Datenreihen unterstreicht seine fortwährende Bedeutung für jeden, der mit Daten arbeitet. Tauchen Sie weiter ein in die spannende Welt der statistischen Tests und der Datenanalyse Werkzeuge für Ingenieure und entdecken Sie, wie diese Methoden Ihre Projekte bereichern können.