W3docs

Normalverteilung von Daten

Normalverteilung in Python: PDF, CDF, Z-Scores, empirische Regel, Normalitätstests und Log-Transformation.

Die Normalverteilung (auch Gaußsche Verteilung genannt) ist die bei weitem wichtigste Wahrscheinlichkeitsverteilung in der Statistik und im maschinellen Lernen. Sie wirklich zu verstehen — nicht nur ihre Glockenkurvenform zu erkennen, sondern zu wissen, wie man sie misst, testet und in Python damit arbeitet — gibt Ihnen eine solide Grundlage für Datenvorbereitung, Modellauswahl und Ergebnisinterpretation.

Dieses Kapitel behandelt:

  • Was die Normalverteilung ist und warum ihre Form wichtig ist
  • Die empirische Regel (68–95–99,7-Regel) und wie man sie überprüft
  • Normalverteilte Daten mit NumPy erzeugen
  • Die Wahrscheinlichkeitsdichtefunktion (PDF) und kumulative Verteilungsfunktion (CDF) mit SciPy auswerten
  • Z-Scores berechnen und interpretieren
  • Testen, ob Ihre Daten normalverteilt sind
  • Was zu tun ist, wenn Daten nicht normal verteilt sind

Was ist die Normalverteilung?

Eine Wahrscheinlichkeitsverteilung beschreibt, wie wahrscheinlich es ist, dass jeder Wert in einem Datensatz auftritt. Die Normalverteilung ist eine stetige, symmetrische, glockenförmige Verteilung, die durch zwei Parameter definiert wird:

  • Mittelwert (μ) — der Mittelpunkt der Glocke; wo der Scheitelpunkt liegt
  • Standardabweichung (σ) — wie breit oder schmal die Glocke ist; ein größeres σ streut die Werte weiter vom Mittelpunkt

Da die Kurve symmetrisch um den Mittelwert ist, sind Mittelwert, Median und Modus bei einer perfekten Normalverteilung identisch.

Die Formel für die Wahrscheinlichkeitsdichtefunktion lautet:

f(x) = (1 / (σ√(2π))) × e^(−(x−μ)² / (2σ²))

Sie müssen diese Formel nicht von Hand anwenden — SciPys stats.norm übernimmt das —, aber es ist nützlich zu wissen, dass die Form nur von μ und σ abhängt.

Die empirische Regel (68–95–99,7)

Eine der praktischsten Eigenschaften der Normalverteilung ist die empirische Regel, auch als 68–95–99,7-Regel bekannt:

Abstand vom MittelwertProzentsatz der Werte
Innerhalb von ±1 Standardabweichung~68%
Innerhalb von ±2 Standardabweichungen~95%
Innerhalb von ±3 Standardabweichungen~99,7%

Das bedeutet, dass in einem normalverteilten Datensatz fast alle Werte innerhalb von drei Standardabweichungen vom Mittelwert liegen. Werte jenseits von ±3σ sind wirklich selten — ungefähr 1 von 370 Beobachtungen.

Das folgende Beispiel simuliert 10 000 Werte aus einer Standardnormalverteilung (μ=0, σ=1) und überprüft die Regel:

import numpy as np

rng = np.random.default_rng(seed=42)
mu, sigma = 0, 1
data = rng.normal(loc=mu, scale=sigma, size=10000)

w1 = np.mean(np.abs(data - mu) < 1 * sigma) * 100
w2 = np.mean(np.abs(data - mu) < 2 * sigma) * 100
w3 = np.mean(np.abs(data - mu) < 3 * sigma) * 100

print(f"Within 1 std: {w1:.1f}%  (expected ~68%)")
print(f"Within 2 std: {w2:.1f}%  (expected ~95%)")
print(f"Within 3 std: {w3:.1f}%  (expected ~99.7%)")

Ausgabe:

Within 1 std: 67.8%  (expected ~68%)
Within 2 std: 95.4%  (expected ~95%)
Within 3 std: 99.7%  (expected ~99.7%)

Die empirische Regel ist unmittelbar nützlich: Wenn ein Testergebnis mehr als zwei Standardabweichungen über dem Mittelwert liegt, fällt es in die oberen ~2,5% aller Ergebnisse.

Normalverteilte Daten mit NumPy erzeugen

NumPys Zufallszahlengenerator erzeugt Stichproben, die eine Normalverteilung approximieren. Die Methode rng.normal() akzeptiert den Mittelwert (loc), die Standardabweichung (scale) und die Anzahl der Stichproben (size):

import numpy as np

rng = np.random.default_rng(seed=7)

# Simulate IQ scores: mean=100, std=15
samples = rng.normal(loc=100, scale=15, size=1000)

print(f"Sample mean:  {samples.mean():.1f}")
print(f"Sample std:   {samples.std():.1f}")
print(f"Min:          {samples.min():.1f}")
print(f"Max:          {samples.max():.1f}")
print(f"Sample size:  {len(samples)}")

Ausgabe:

Sample mean:  98.9
Sample std:   14.1
Min:          51.2
Max:          138.6
Sample size:  1000

Der Stichprobenmittelwert und die Standardabweichung sind nahe an — aber nicht exakt — 100 und 15, weil eine endliche Stichprobe natürliche Zufallsvariation aufweist. Mit 10 000 Stichproben nähern sich die Schätzungen den wahren Parametern weiter an.

Warum einen Seed verwenden? Die Übergabe von seed=7 an default_rng macht die Ergebnisse reproduzierbar. Jeder, der denselben Code ausführt, erhält dieselben Zahlen — das ist für das Debuggen und das Teilen von Ergebnissen unerlässlich. Die default_rng-Schnittstelle (eingeführt in NumPy 1.17) ist dem älteren np.random.normal() vorzuziehen, da sie gemeinsamen globalen Zustand vermeidet.

PDF und CDF mit SciPy auswerten

Wahrscheinlichkeitsdichtefunktion (PDF)

Die PDF gibt die relative Wahrscheinlichkeit eines Wertes an. Ein höherer PDF-Wert bei x bedeutet, dass x häufiger vorkommt. Bei einer Normalverteilung liegt der Scheitelpunkt beim Mittelwert:

from scipy import stats

mu, sigma = 0, 1

x_values = [-2, -1, 0, 1, 2]
for x in x_values:
    pdf = stats.norm.pdf(x, loc=mu, scale=sigma)
    print(f"  pdf({x:2d}) = {pdf:.4f}")

Ausgabe:

  pdf(-2) = 0.0540
  pdf(-1) = 0.2420
  pdf( 0) = 0.3989
  pdf( 1) = 0.2420
  pdf( 2) = 0.0540

Die PDF ist symmetrisch: pdf(-1) entspricht pdf(1), und pdf(0) ist das Maximum (der Scheitelpunkt der Glockenkurve). Der PDF-Wert selbst ist keine Wahrscheinlichkeit — er ist eine Dichte. Um eine Wahrscheinlichkeit zu erhalten, integriert man die PDF über einen Bereich, was die CDF leistet.

Kumulative Verteilungsfunktion (CDF)

Die CDF bei einem Wert x gibt die Wahrscheinlichkeit an, dass eine zufällig gezogene Beobachtung kleiner oder gleich x ist. Verwenden Sie stats.norm.cdf(), um praktische Wahrscheinlichkeitsfragen zu beantworten:

from scipy import stats

mu, sigma = 170, 10  # adult heights in cm

# Probability that a randomly chosen person is shorter than 180 cm
p_below_180 = stats.norm.cdf(180, loc=mu, scale=sigma)
print(f"P(height < 180 cm) = {p_below_180:.4f}")

# Probability of being taller than 185 cm
p_above_185 = 1 - stats.norm.cdf(185, loc=mu, scale=sigma)
print(f"P(height > 185 cm) = {p_above_185:.4f}")

# Probability of falling between 160 cm and 180 cm
p_range = stats.norm.cdf(180, loc=mu, scale=sigma) - stats.norm.cdf(160, loc=mu, scale=sigma)
print(f"P(160 < height < 180 cm) = {p_range:.4f}")

Ausgabe:

P(height < 180 cm) = 0.8413
P(height > 185 cm) = 0.0668
P(160 < height < 180 cm) = 0.6827

Das dritte Ergebnis bestätigt die empirische Regel: Der Bereich μ±σ (160–180 cm) enthält etwa 68% der Beobachtungen.

Z-Scores: Die Verteilung standardisieren

Ein Z-Score (auch Standardwert genannt) misst, wie viele Standardabweichungen ein Wert vom Mittelwert entfernt ist:

Z = (x − μ) / σ

Z-Scores ermöglichen den Vergleich von Werten aus Verteilungen mit unterschiedlichen Mittelwerten und Standardabweichungen auf einer gemeinsamen Skala. Ein Z-Score von +2,0 bedeutet, dass ein Wert zwei Standardabweichungen über dem Mittelwert liegt, unabhängig von den ursprünglichen Einheiten.

import numpy as np
from scipy import stats

heights = np.array([171.3, 168.7, 176.4, 171.0, 164.6, 173.6, 183.0, 179.5])

# Calculate Z-scores manually
mean = heights.mean()
std  = heights.std(ddof=1)   # ddof=1 for the sample standard deviation
z_manual = (heights - mean) / std
print("Z-scores (manual):", np.round(z_manual, 2))

# Or use scipy directly
z_scipy = stats.zscore(heights, ddof=1)
print("Z-scores (scipy): ", np.round(z_scipy, 2))

Ausgabe:

Z-scores (manual): [-0.37 -0.81  0.49 -0.42 -1.5   0.01  1.59  1.01]
Z-scores (scipy):  [-0.37 -0.81  0.49 -0.42 -1.5   0.01  1.59  1.01]

Eine Person mit einer Körpergröße von 183,0 cm hat einen Z-Score von +1,59, was bedeutet, dass sie 1,59 Standardabweichungen über dem Mittelwert liegt. In einer Normalverteilung platziert sie das ungefähr in den oberen 6% der Bevölkerung.

Wann Z-Scores nützlich sind

  • Ausreißererkennung: Werte mit |Z| > 3 sind in einer Normalverteilung fast sicher Ausreißer.
  • Feature-Skalierung: Das Umrechnen von Features in Z-Scores (Mittelwert null, Einheitsvarianz) wird Standardisierung genannt und ist für Algorithmen erforderlich, die empfindlich auf die Größenordnung von Features reagieren, wie SVM und k-nächste Nachbarn. Im Kapitel zur Feature-Skalierung erfahren Sie, wie man dies mit scikit-learns StandardScaler anwendet.
  • Äpfel mit Birnen vergleichen: Wenn Sie das Mathematikergebnis eines Schülers (Mittelwert 70, Standardabweichung 10) mit seinem Leseergebnis (Mittelwert 50, Standardabweichung 5) vergleichen möchten, ermöglichen Z-Scores einen fairen Vergleich.

Testen, ob Daten normalverteilt sind

Bevor man Algorithmen anwendet, die Normalverteilung voraussetzen, sollte man diese Annahme überprüfen. Die zwei häufigsten Ansätze sind der Shapiro-Wilk-Test (für Stichproben bis ~5 000) und eine schnelle visuelle Inspektion.

Shapiro-Wilk-Test

Der Shapiro-Wilk-Test liefert eine Statistik W und einen p-Wert. Ein p-Wert über 0,05 bedeutet, dass es nicht genug Beweise gibt, um die Normalverteilung abzulehnen. Ein p-Wert bei oder unter 0,05 zeigt an, dass die Daten wahrscheinlich nicht normal verteilt sind.

import numpy as np
from scipy import stats

rng = np.random.default_rng(seed=42)

# Normally distributed sample
normal_sample = rng.normal(loc=0, scale=1, size=50)
stat_n, p_n = stats.shapiro(normal_sample)
print(f"Normal sample  — W={stat_n:.3f}, p={p_n:.3f}")
if p_n > 0.05:
    print("  => Cannot reject normality.")
else:
    print("  => Reject normality.")

# Skewed sample (exponential distribution)
skewed_sample = rng.exponential(scale=1, size=50)
stat_s, p_s = stats.shapiro(skewed_sample)
print(f"Skewed sample  — W={stat_s:.3f}, p={p_s:.3f}")
if p_s > 0.05:
    print("  => Cannot reject normality.")
else:
    print("  => Reject normality.")

Ausgabe:

Normal sample  — W=0.984, p=0.730
  => Cannot reject normality.
Skewed sample  — W=0.808, p=0.000
  => Reject normality.

Die normalverteilte Stichprobe besteht den Test problemlos (p=0,730). Die schiefe Stichprobe scheitert eindeutig (p≈0).

Wann Normalitätstests wichtig sind

Nicht jeder Algorithmus benötigt normalverteilte Features. Baumbasierte Modelle (Entscheidungsbäume, Random Forests, Gradient Boosting) und neuronale Netze sind vollständig verteilungsunabhängig. Normalverteilung ist am wichtigsten für:

  • Parametrische statistische Tests (t-Test, ANOVA, Pearson-Korrelation) — die p-Werte dieser Tests sind nur gültig, wenn die Daten annähernd normalverteilt sind.
  • Lineare Diskriminanzanalyse (LDA) — setzt voraus, dass jede Klasse normalverteilt ist.
  • Gaussian Naive Bayes — modelliert jedes Feature explizit als Gaußverteilung.
  • Konfidenzintervalle und Prognoseintervalle in der linearen Regression — leiten sich aus der Normalverteilung der Residuen ab.

Wenn Daten nicht normal verteilt sind: Log-Transformation

Ein häufiges Mittel bei rechtsschiefen Daten (z. B. Einkommen, Hauspreise, Transaktionsbeträge) ist die Log-Transformation, die große Werte komprimiert und kleine dehnt. Das Ergebnis ist oft nahezu normalverteilt:

import numpy as np
from scipy import stats

rng = np.random.default_rng(seed=7)

# Simulate log-normally distributed incomes (a realistic pattern)
incomes = rng.lognormal(mean=10.5, sigma=0.5, size=1000)
log_incomes = np.log(incomes)

sk_before = stats.skew(incomes)
sk_after  = stats.skew(log_incomes)

stat_before, p_before = stats.shapiro(incomes[:50])
stat_after,  p_after  = stats.shapiro(log_incomes[:50])

print(f"Before transform — skewness: {sk_before:.2f},  Shapiro p={p_before:.3f}")
print(f"After log transform — skewness: {sk_after:.2f}, Shapiro p={p_after:.3f}")

Ausgabe:

Before transform — skewness: 1.44,  Shapiro p=0.000
After log transform — skewness: 0.01, Shapiro p=0.940

Nach der Log-Transformation sinkt die Schiefe von 1,44 auf nahezu null, und der Shapiro-Wilk-p-Wert steigt von 0,000 auf 0,940 — die transformierten Daten bestehen den Normalitätstest problemlos.

Zu beachten:

  • Die Log-Transformation erfordert, dass alle Werte strikt positiv sind. Wenn Ihre Daten Nullen enthalten, verwenden Sie np.log(x + 1) (Log-plus-Eins-Transformation).
  • Wenn Ihre Daten eine linke Schiefe aufweisen (langer Schwanz nach links), versuchen Sie stattdessen eine Quadrat- oder Reflexionstransformation.
  • Wenden Sie immer dieselbe Transformation sowohl auf den Trainingsdatensatz als auch auf neue Daten zur Inferenzzeit an.

Warum die Normalverteilung im maschinellen Lernen wichtig ist

Die Normalverteilung taucht im maschinellen Lernen überall auf, oft implizit:

  • Zentraler Grenzwertsatz: Der Mittelwert einer großen Zufallsstichprobe ist unabhängig von der ursprünglichen Verteilung annähernd normalverteilt. Dies untermauert Konfidenzintervalle und Hypothesentests für Modellmetriken.
  • Residualanalyse: Die Residuen einer gut angepassten linearen Regression sollten annähernd normalverteilt sein. Abweichungen signalisieren eine Fehlspezifikation des Modells.
  • Gewichtsinitialisierung in neuronalen Netzen: Schemata wie Xavier- und He-Initialisierung ziehen Anfangsgewichte aus Normalverteilungen, um verschwindende oder explodierende Gradienten zu verhindern.
  • Gaußsche Prozesse: Eine Familie probabilistischer Modelle, die eine Normalverteilung über Funktionen legen, verwendet in der Bayes'schen Optimierung und der Quantifizierung von Unsicherheit.
  • Ausreißererkennung: In vielen Bereichen werden Daten jenseits von ±3σ vom Mittelwert als Anomalie markiert.

Zu verstehen, wo Normalverteilung vorausgesetzt wird — und wann diese Annahme nicht hält —, hilft Ihnen, stille Modellierungsfehler zu vermeiden.

Zusammenfassung

  • Die Normalverteilung wird durch ihren Mittelwert (μ) und ihre Standardabweichung (σ) definiert; ihre glockenförmige Kurve ist symmetrisch um den Mittelwert.
  • Die empirische Regel besagt, dass 68%, 95% und 99,7% der Werte innerhalb von 1, 2 bzw. 3 Standardabweichungen vom Mittelwert liegen.
  • Verwenden Sie numpy.random.default_rng().normal(), um normalverteilte Stichproben zu erzeugen, und scipy.stats.norm.pdf() / .cdf(), um Wahrscheinlichkeiten auszuwerten.
  • Z-Scores standardisieren Werte auf eine gemeinsame Skala; sie sind unverzichtbar für Ausreißererkennung und Feature-Skalierung.
  • Verwenden Sie scipy.stats.shapiro(), um formal auf Normalverteilung zu testen — beachten Sie jedoch, dass viele moderne ML-Algorithmen diese nicht voraussetzen.
  • Wenn Daten rechtsschiefe aufweisen, macht eine Log-Transformation sie oft annähernd normalverteilt.

Für einen umfassenderen Vergleich von Verteilungstypen (uniform, schief, multimodal) siehe das Kapitel Datenverteilung. Informationen zur Messung von Streuung und Lagemaß finden Sie in Standardabweichung und Mittelwert, Median und Modus.

Was this page helpful?