Zum Inhalt

Explorative Datenanalyse: Statistische Diagnostik & Feature-Profiling

Erstellt: 2026-11-08  ·  Zuletzt aktualisiert: 2026-11-08  ·  Nejat Hakan

Management Summary: Unerfahrene Data Scientists neigen dazu, ungesehene Rohdaten unmittelbar in komplexe Machine-Learning-Modelle zu speisen, ohne grundlegende Verteilungsannahmen zu prüfen. Bimodale Latenzspitzen, schwere Verteilungsränder (Heavy Tails) und ausgeprägte Multikollinearität führen in der Praxis zum Scheitern von Regressoren und Klassifikatoren. Dieser Leitfaden beschreibt die methodische Durchführung explorativer Datenanalysen (EDA) unter Debian: Analyse von Wahrscheinlichkeitsverteilungen via ECDF (Empirical Cumulative Distribution Function), Ausreißer-Isolation mit dem robusten Interquartilsabstand (IQR), Rangkorrelationen nach Spearman und Kollinearitäts-Prüfung mittels Variance Inflation Factor (VIF).

  • Verteilungs-Diagnostik


    Über den Mittelwert hinausblicken: Schiefe, Wölbung und Bimodalität quantifizieren, um Log-Transformationen oder Median-Nutzung fundiert zu begründen.

  • ECDF vs. Histogramm-Binning


    Willkürliche Klassengrenzen vermeiden: Die empirische Verteilungsfunktion visualisiert 100 % aller Messpunkte ohne Informationsverlust.

  • Multikollinearität & VIF


    Modellinstabilitäten verhindern: Identifikation redundanter, stark gekoppelter Features über den Variance Inflation Factor (VIF > 5).

  • Robuste Ausreißer-Isolation


    Hardware-Anomalien von statistischem Rauschen trennen mittels nicht-parametrischer IQR-Grenzen (Interquartile Range) und Quantilsschwellen.


1. Die Täuschung durch Mittelwerte: Anscombe & Bimodalität

Sich ausschließlich auf Kennzahlen wie Mittelwert und Standardabweichung zu verlassen, führt in Produktionsumgebungen zu fatalen Fehlschlüssen. Völlig unterschiedliche Datenverteilungen können identische Kennzahlen aufweisen:

%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
    RAW["Rohe Server-Telemetrie<br/>(1.000.000 Latenzen)"]

    subgraph Deception ["Die Mittelwert-Falle"]
        direction TB
        MEAN["Mittelwert = 125 ms | Std = 45 ms<br/>(Versteckt die reale Ursache!)"]
    end

    subgraph Reality ["Verteilungs-Realitaet"]
        direction TB
        BIMODAL["Bimodale Verteilung<br/>A (Cache Hits): 15 ms<br/>B (Lock-Blockaden): 450 ms"]
    end

    RAW --> Deception
    Deception -->|"Verteilung analysieren"| Reality

Warum klassische Histogramme verzerren:

Ein Standard-Histogramm teilt kontinuierliche Werte in diskrete Boxen (Bins, z. B. 20 Klassen). Wird die Klassenbreite nur minimal verändert, wandelt sich die optische Form des Diagramms drastisch.

Die mathematisch überlegene Methode ist die Empirische Kumulative Verteilungsfunktion (ECDF):

Fn(t) = 1/n · ∑i=1..n 𝟏(xi ≤ t)

Eine ECDF trägt jeden einzelnen Datenpunkt entlang der Perzentil-Achse (0.0 → 1.0) auf und legt wichtige Grenzwerte (p50, p95, p99) exakt offen.


2. Robuste Ausreißererkennung: IQR vs. Z-Score

Parametrische Methoden wie der Z-Score (Z = (x - μ) / σ) setzen eine normale Gaußsche Glockenkurve voraus. Treten extreme Ausreißer auf, verzerren diese den Mittelwert (μ) und blähen die Standardabweichung (σ) künstlich auf – der Z-Score wird blind für reale Spitzen!

Der Interquartilsabstand (IQR) ist nicht-parametrisch und resistent gegen Extremwerte:

%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
    Q1["25. Perzentil (Q1)"]
    Q3["75. Perzentil (Q3)"]
    IQR["IQR = Q3 - Q1<br/>(Mittlere 50% der Daten)"]

    LOWER["Untere Grenze:<br/>Q1 - 1,5 x IQR"]
    UPPER["Obere Grenze:<br/>Q3 + 1,5 x IQR"]

    Q1 --> IQR
    Q3 --> IQR
    IQR --> LOWER
    IQR --> UPPER

Jeder Messwert außerhalb von [Q1 - 1,5 × IQR, Q3 + 1,5 × IQR] wird als statistischer Ausreißer isoliert.


3. Redundanzen aufdecken: VIF & Rangkorrelation

Messen mehrere Variablen im Kern dasselbe Phänomen (z. B. cpu_user_pct, cpu_system_pct und cpu_total_pct), entsteht Multikollinearität: Die Koeffizienten linearer Modelle schwanken unkontrolliert, und Feature-Importances verlieren jede Gültigkeit.

3.1. Pearson (r) vs. Spearman (ρ)

  • Pearson-Korrelation: Misst strikt lineare Zusammenhänge. Extrem anfällig für Ausreißer.
  • Spearman-Rangkorrelation: Prüft, ob zwei Variablen monoton steigen oder fallen, unabhängig von der Linearität:

ρ = 1 - (6 · ∑ di2) / (n · (n2 - 1))

3.2. Variance Inflation Factor (VIF)

Der VIF regrediert jedes Merkmal gegen alle übrigen Merkmale:

VIFj = 1 / (1 - Rj2)

  • VIF = 1: Vollständig unabhängig.
  • VIF > 5: Kritische Kollinearität. Mindestens eines der abhängigen Features muss entfernt werden.

4. Telemetrie-Diagnostik-Lab im Produktivbetrieb

Führen Sie dieses Diagnoseskript auf Ihrem Linux-System aus, um reale Infrastruktur-Metriken zu analysieren:

#!/usr/bin/env python3
# Datei: /opt/ds-ops/eda_diagnostics.py
import numpy as np
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor

# 1. Realistische Server-Telemetriedaten generieren
np.random.seed(42)
n_records = 250_000

# Bimodale Latenz: 90% schnelle Cache-Hits + 10% langsame Lock-Blockaden
latencies = np.concatenate([
    np.random.exponential(scale=12.0, size=int(n_records * 0.9)),
    np.random.normal(loc=350.0, scale=40.0, size=int(n_records * 0.1))
])

cpu_util = np.random.uniform(10.0, 95.0, size=n_records)
# Kollineares Feature: load_avg hängt direkt von cpu_util ab
load_avg = (cpu_util * 0.15) + np.random.normal(0, 0.5, size=n_records)
network_rx_mb = np.random.gamma(shape=2.0, scale=15.0, size=n_records)

df = pd.DataFrame({
    "latency_ms": latencies,
    "cpu_util": cpu_util,
    "load_avg": load_avg,
    "network_rx_mb": network_rx_mb
})

print("=== 1. Nicht-parametrische Quantil-Verteilung ===")
quantiles = [0.25, 0.50, 0.75, 0.90, 0.95, 0.99]
print(df.quantile(quantiles).T)

print("\n=== 2. Robuste IQR-Ausreißer-Isolation (latency_ms) ===")
q25, q75 = df["latency_ms"].quantile(0.25), df["latency_ms"].quantile(0.75)
iqr = q75 - q25
upper_bound = q75 + (1.5 * iqr)
outliers = df[df["latency_ms"] > upper_bound]
print(f"IQR: {iqr:.2f} ms | Obere Grenze: {upper_bound:.2f} ms")
print(f"{len(outliers):,} Ausreißer isoliert ({len(outliers)/len(df)*100:.2f}%)")

print("\n=== 3. Spearman-Rangkorrelationsmatrix ===")
print(df.corr(method="spearman").round(3))

print("\n=== 4. Multikollinearitäts-Diagnostik (Variance Inflation Factor) ===")
features = df[["cpu_util", "load_avg", "network_rx_mb"]]
vif_data = pd.DataFrame({
    "feature": features.columns,
    "VIF": [variance_inflation_factor(features.values, i) for i in range(features.shape[1])]
})
print(vif_data.sort_values(by="VIF", ascending=False))

Typische Diagnose-Ausgabe:

=== 4. Multikollinearitäts-Diagnostik (Variance Inflation Factor) ===
         feature       VIF
0       cpu_util  18.42104   <-- KRITISCHE KOLLINEARITÄT (Entfernen!)
1       load_avg  17.98101   <-- KRITISCHE KOLLINEARITÄT (Entfernen!)
2  network_rx_mb   2.14012   <-- Unbedenklich

Durch das Identifizieren hoher VIF-Werte im Vorfeld verhindern Sie, dass fehlerhafte, redundant gekoppelte Features das Training instabil machen.