Data Science · Klinik Klinische Datenanalyse & Machine Learning
Ansicht
Lerntiefe
Codeansicht
Farbschema

Teil 5 – Machine Learning und KI in der Medizin

27 · Erklärbarkeit von Machine-Learning-Modellen

Dauer~70 min
VoraussetzungModule 24 und 26 (Workflow und Ensembles)
Lernziele
  • Den Unterschied zwischen globaler und lokaler Erklärbarkeit verstehen.
  • Permutation Importance korrekt berechnen und gegen Impurity-basierte Wichtigkeit abgrenzen.
  • Partial Dependence Plots (PDP) und Individual Conditional Expectation (ICE) lesen und interpretieren.
  • SHAP-Werte konzeptuell einordnen und, sofern installiert, für einzelne Patient:innen berechnen.
  • Typische Fallstricke: korrelierte Merkmale, Wichtigkeit ≠ Kausalität.
Auf dieser Seite

Klinischer Aufhänger

Du hast in Modul 26 ein Ensemble trainiert, das verstorben_30d mit guter AUC vorhersagt. Die Stationsleitung fragt: „Warum sagt das Modell bei Patient 42 ein hohes Sterberisiko voraus?" Und der Ethikausschuss: „Welche Variablen treibt das Modell überhaupt?" Erklärbarkeit ist keine Kür, sondern Voraussetzung für Vertrauen, Fehlerdiagnose und regulatorische Akzeptanz (MDR, EU-AI-Act).

1 Globale vs. lokale Erklärbarkeit

Globale Erklärbarkeit beschreibt, welche Merkmale das Modell im Durchschnitt über alle Patient:innen antreiben. Sie beantwortet: „Was hat das Modell gelernt?" Lokale Erklärbarkeit beschreibt, warum das Modell für eine konkrete Person eine bestimmte Vorhersage macht. Sie beantwortet: „Warum bekommt Patient 42 diesen Score?"

Kein Verfahren allein genügt: Globale Methoden überdecken wichtige Einzelfälle, lokale Methoden verzerren das Gesamtbild.

Fallstrick

Bevor du irgendetwas erklärst, prüfe, ob das Modell überhaupt etwas gelernt hat. Ein Modell nahe der Zufallsgrenze (AUC ≈ 0,5) liefert trotzdem plausibel aussehende SHAP-Plots und Permutation-Importance- Balken, nur beschreiben die dann Rauschen, nicht Signal. code/python.py prüft deshalb zuerst die kreuzvalidierte AUC (Abschnitt 0), bevor es irgendeine Erklärungsmethode aufruft:

Hinweis — die Codeblöcke unten sind Auszüge. Sie zeigen die entscheidenden Schritte, nicht jede Import-Zeile. Das vollständige, am Stück lauffähige Skript ist code/python.py (im Browser über den Python-Reiter oben). In Colab führst du das ganze Modul mit einer Zeile aus: !python module/27-erklaerbarkeit/code/python.py — siehe das in Colab öffnen.

Python
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED)
probe = HistGradientBoostingClassifier(random_state=SEED, max_iter=200,
                                        class_weight="balanced")
cv_auc = cross_val_score(probe, X, y, cv=cv, scoring="roc_auc")
print(f"CV-AUC: {cv_auc.mean():.3f} ± {cv_auc.std():.3f}")
# Auf unserer Kohorte: CV-AUC = 0.722 ± 0.048 — klar über der Zufallsgrenze,
# Erklärbarkeit lohnt sich hier.

# Nur wenn die Prädiktivität bestätigt ist: finales Modell trainieren.
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, stratify=y, random_state=SEED)
model = HistGradientBoostingClassifier(random_state=SEED, max_iter=200)
model.fit(X_train, y_train)

In R arbeitest du analog mit ranger (Random Forest) und dem Paket vip für globale Wichtigkeit sowie pdp oder iml für PDP/ICE und lokale Erklärungen.

Fallstrick

Erklärbarkeit erklärt das Modell, nicht die Realität. Ein Merkmal mit hoher Wichtigkeit ist nicht kausal, es könnte ein Proxy für eine versteckte dritte Variable sein.

Für FortgeschritteneVertiefung

Für regulatorische Kontexte (MDR Klasse IIb/III) reicht technische Erklärbarkeit allein nicht; es braucht klinische Validierung und Dokumentation der Entscheidungslogik.

2 Permutation Importance, das ehrliche Maß

Impurity-basierte Wichtigkeit (Standard bei RandomForest) bevorzugt Merkmale mit vielen Ausprägungen und überschätzt hochdimensionale oder kontinuierliche Variablen. Permutation Importance (PI) mischt die Werte eines Merkmals zufällig durch und misst den Leistungsabfall auf dem Testset. So zeigt sie, wie stark das Modell von diesem Merkmal abhängt, unabhängig von Skaleneffekten.

Python
from sklearn.inspection import permutation_importance

result = permutation_importance(
    model, X_test_df, y_test,
    n_repeats=10, random_state=SEED, scoring="roc_auc"
)
importances_mean = result.importances_mean   # shape: (n_features,)
importances_std  = result.importances_std

Die Ausgabe enthält für jedes Merkmal den mittleren AUC-Abfall und seine Standardabweichung über die 10 Wiederholungen. Merkmale mit kleinem Abfall und großer Streuung nutzt das Modell kaum oder sie sind austauschbar.

Permutation Importance: mittlerer AUC-Abfall je Merkmal mit Fehlerbalken (Testset, 10 Wiederholungen). SOFA-Score und Alter führen; Merkmale, deren Fehlerbalken die Null-Linie überdecken, sind für das Modell nicht eindeutig relevant.
Abb. 1 · Permutation Importance: mittlerer AUC-Abfall je Merkmal mit Fehlerbalken (Testset, 10 Wiederholungen). SOFA-Score und Alter führen; Merkmale, deren Fehlerbalken die Null-Linie überdecken, sind für das Modell nicht eindeutig relevant. · Code ansehen
Fallstrick

Bei korrelierten Merkmalen wird die PI unterschätzt, das Modell kann das gemischte Merkmal durch sein Korrelat kompensieren. Dann sind beide Variablen scheinbar unwichtig, obwohl sie zusammen viel tragen.

Für FortgeschritteneVertiefung

n_repeats=10 (wie in code/python.py) ist ein guter Kompromiss zwischen Laufzeit und Stabilität für die Kursbeispiele. Für Veröffentlichungen empfiehlt sich mindestens 30 Wiederholungen.

3 Partial Dependence und ICE

Partial Dependence Plots (PDP) zeigen, wie sich die mittlere Modellvorhersage ändert, wenn du ein Merkmal variierst und alle anderen konstant halten (marginalisieren). Sie sind globale Aussagen über den durchschnittlichen Effekt.

Individual Conditional Expectation (ICE): dieselbe Variation je Patient:in, aber ohne Mittelung der Kurven. Kreuzen sich die ICE-Kurven, gibt es eine Interaktion, der Effekt des Merkmals hängt vom Wert anderer Variablen ab.

Python
from sklearn.inspection import PartialDependenceDisplay

# PDP + ICE for sofa_score and alter (two panels in one figure)
PartialDependenceDisplay.from_estimator(
    model, X_test_df,
    features=["sofa_score", "alter"],
    kind="both",           # "average" = PDP only; "both" = PDP + ICE
    subsample=100,
    random_state=SEED,
    ax=axes,
)
Partial Dependence und ICE für sofa_score (links) und Alter (rechts). Die fette Linie zeigt den PDP (Durchschnitt), dünne Linien einzelne Patient:innen. Kreuzende ICE-Linien weisen auf Interaktionen hin.
Abb. 2 · Partial Dependence und ICE für sofa_score (links) und Alter (rechts). Die fette Linie zeigt den PDP (Durchschnitt), dünne Linien einzelne Patient:innen. Kreuzende ICE-Linien weisen auf Interaktionen hin. · Code ansehen
Fallstrick

PDPs mit Merkmalen, die stark korreliert sind (z. B. bmi und gewicht_kg), erzeugen beim Marginalisieren unrealistische Datenpunkte und werden dann irreführend. Prüfe immer die Merkmalskorrelation.

Für FortgeschritteneVertiefung

kind="both" kann bei großen Datensätzen langsam sein. subsample=100 beschleunigt die ICE-Linien auf Kosten von etwas Genauigkeit. Für Veröffentlichungen alle Patient:innen nutzen.

4 SHAP, lokale Erklärungen

SHAP (SHapley Additive exPlanations) weist jeder Variable für jede einzelne Vorhersage einen spieltheoretisch begründeten Beitrag zu: Wie viel trägt ein Merkmal bei, verglichen mit dem Fall, dass es fehlt?

  • Beeswarm-Plot: Alle Patient:innen auf einen Blick, Farbe = Merkmalswert, x-Position = SHAP-Wert (Beitrag zur Vorhersage).

  • Force-Plot / Waterfall: Einzelne Person, zeigt, welche Merkmale den Score nach oben oder unten verschieben.

Python
# Try shap; fall back to permutation importance if not installed.
try:
    import shap
    explainer = shap.Explainer(model, X_train_df)
    # check_additivity=False: HistGradientBoostingClassifier + class_weight=
    # "balanced" can trip shap's strict floating-point additivity check by a
    # tiny margin without the explanation being wrong (known interaction, see
    # code/python.py for details).
    shap_values = explainer(X_test_df[:100], check_additivity=False)  # first 100 patients for speed
    print("SHAP summary (mean |SHAP|):")
    mean_abs = np.abs(shap_values.values).mean(axis=0)
    for feat, val in sorted(zip(FEATURES, mean_abs), key=lambda x: -x[1]):
        print(f"  {feat:<30} {val:.4f}")
    SHAP_AVAILABLE = True
except ImportError:
    print("SHAP not installed — using permutation importance for local explanation proxy.")
    print("Install with: uv pip install shap")
    SHAP_AVAILABLE = False
Abbildung: SHAP-Beeswarm-Plot für 150 zufällige Testpatient:innen (HistGradientBoosting). Jeder Punkt ist ein/e Patient:in, x-Position = SHAP-Wert (Beitrag zum log-odds-Score), Farbe = Merkmalswert (rot = hoch, blau = niedrig). SOFA-Score, Alter und CRP haben den größten Streubereich und damit den größten Einfluss auf einzelne Vorhersagen.
Abb. 3 · SHAP-Beeswarm-Plot für 150 zufällige Testpatient:innen (HistGradientBoosting). Jeder Punkt ist ein/e Patient:in, x-Position = SHAP-Wert (Beitrag zum log-odds-Score), Farbe = Merkmalswert (rot = hoch, blau = niedrig). SOFA-Score, Alter und CRP haben den größten Streubereich und damit den größten Einfluss auf einzelne Vorhersagen. · Code ansehen

Ohne SHAP bleibt die Permutation Importance als globales Ersatzmaß gültig; die lokale Erklärung eines Einzelfalls lässt sich über Koeffizienten (bei linearen Modellen) oder LIME approximieren.

Fallstrick

SHAP-Werte für baumbasierte Modelle (TreeSHAP) sind exakt und schnell. Für neuronale Netze oder Kernel-SHAP steigt der Rechenaufwand stark an.

Stolperstein — korrelierte Merkmale: Wie bei Permutation Importance (Abschnitt 2) können zwei korrelierte Merkmale (z. B. Alter und SOFA-Score, beide Marker für Schwere) sich den SHAP-Beitrag teilen. Ein kleiner mittlerer |SHAP|-Wert bedeutet dann nicht zwingend „unwichtig", sondern eventuell nur „das Signal steckt teilweise im korrelierten Partner". Prüfe Merkmalskorrelationen, bevor du ein Merkmal aufgrund niedriger SHAP-Werte als irrelevant einstufst.

Für FortgeschritteneVertiefung

SHAP-Interaktionswerte (shap_values.values bei TreeExplainer) erklären Wechselwirkungen zwischen Merkmalen, wichtig, wenn PDP-Kreuzungen aufgefallen sind.

Wann du Hilfe holst. Sobald jemand SHAP- oder Importance-Werte kausal deutet („Variable X senkt das Risiko“), stark korrelierte Merkmale die Zuschreibung verzerren, oder eine Erklärung regulatorisch (MDR, EU-AI-Act) belastbar sein muss, hol methodische Beratung — Wichtigkeit ist nicht Kausalität.

Fallstricke und Merksätze

  • Erst Prädiktivität prüfen, dann erklären. Ein Modell nahe der Zufallsgrenze (CV-AUC ≈ 0,5) liefert plausibel aussehende, aber bedeutungslose Erklärungen.

  • Wichtigkeit ≠ Kausalität. Ein Merkmal kann wichtig sein, weil es mit dem wahren Treiber korreliert, nicht weil es selbst kausal ist.

  • Korrelierte Merkmale schlagen sich die Wichtigkeit gegenseitig weg (PI) oder erzeugen unrealistische Extrapolationen (PDP).

  • Lokale Erklärungen variieren von Patient:in zu Patient:in, eine einzelne Erklärung repräsentiert nicht das Modellverhalten allgemein.

  • Modell erklären, nicht Daten. Erklärbarkeit zeigt, was das Modell gelernt hat, nicht, was in der Realität gilt.

  • SHAP ist nicht universell. Bei nicht-baumbasierten Modellen oder sehr großen Datensätzen kostet SHAP erheblich Rechenzeit.

Selbstcheck

Impurity-Splits wählen häufiger aus vielen Schwellwerten; PI misst dagegen den tatsächlichen Leistungsabfall auf dem Testset und ist damit maßstabsunabhängig.
Den durchschnittlichen Effekt eines Merkmals; irreführend bei stark korrelierten Merkmalen, da dann unrealistische Merkmalskombinationen marginalisiert werden.
Globale SHAP-Zusammenfassungen mitteln |SHAP|-Werte über alle Patient:innen; lokale Erklärungen (Force/Waterfall) zeigen den Beitrag für einen einzelnen Fall.
Weil Erklärbarkeitsmethoden für jedes Modell ein Ergebnis liefern, auch für eines, das nicht besser als der Zufall ist. Ohne diesen Prädiktivitäts-Check könnte man Rauschen als „wichtige Merkmale" fehlinterpretieren; auf unserer Kohorte liegt die CV-AUC bei 0,722, klar über der Zufallsgrenze 0,5.