Durchschnittlicher ROC für die wiederholte 10-fache Kreuzvalidierung mit Wahrscheinlichkeitsschätzungen

15

Ich plane, eine wiederholte (10-mal) geschichtete 10-fache Kreuzvalidierung für etwa 10.000 Fälle mithilfe eines Algorithmus für maschinelles Lernen durchzuführen. Jedes Mal wird die Wiederholung mit verschiedenen zufälligen Samen durchgeführt.

In diesem Prozess erstelle ich 10 Instanzen von Wahrscheinlichkeitsschätzungen für jeden Fall. 1 Instanz der Wahrscheinlichkeitsschätzung für jede der 10 Wiederholungen der 10-fachen Kreuzvalidierung

Kann ich für jeden Fall einen Durchschnitt von 10 Wahrscheinlichkeiten bilden und dann eine neue durchschnittliche ROC-Kurve erstellen (die die Ergebnisse eines wiederholten 10-fachen CV darstellt), die durch paarweise Vergleiche mit anderen ROC-Kurven verglichen werden kann?

user97953
quelle

Antworten:

13

Nach Ihrer Beschreibung scheint es vollkommen sinnvoll zu sein: Sie können nicht nur die mittlere ROC-Kurve berechnen, sondern auch die Varianz um sie herum, um Konfidenzintervalle zu bilden. Es sollte Ihnen eine Vorstellung davon geben, wie stabil Ihr Modell ist.

Zum Beispiel so:

Bildbeschreibung hier eingeben

Hier setze ich einzelne ROC-Kurven sowie die Mittelwertkurve und die Konfidenzintervalle. Es gibt Bereiche, in denen Kurven übereinstimmen, sodass wir weniger Varianz haben, und Bereiche, in denen sie nicht übereinstimmen.

Für einen wiederholten Lebenslauf können Sie ihn einfach mehrmals wiederholen und den Gesamtdurchschnitt über alle einzelnen Falten erhalten:

Bildbeschreibung hier eingeben

Es ist dem vorherigen Bild ziemlich ähnlich, bietet jedoch stabilere (dh zuverlässigere) Schätzungen des Mittelwerts und der Varianz.

Hier ist der Code, um den Plot zu erhalten:

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

from sklearn.datasets import make_classification
from sklearn.cross_validation import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve

X, y = make_classification(n_samples=500, random_state=100, flip_y=0.3)

kf = KFold(n=len(y), n_folds=10)

tprs = []
base_fpr = np.linspace(0, 1, 101)

plt.figure(figsize=(5, 5))

for i, (train, test) in enumerate(kf):
    model = LogisticRegression().fit(X[train], y[train])
    y_score = model.predict_proba(X[test])
    fpr, tpr, _ = roc_curve(y[test], y_score[:, 1])

    plt.plot(fpr, tpr, 'b', alpha=0.15)
    tpr = interp(base_fpr, fpr, tpr)
    tpr[0] = 0.0
    tprs.append(tpr)

tprs = np.array(tprs)
mean_tprs = tprs.mean(axis=0)
std = tprs.std(axis=0)

tprs_upper = np.minimum(mean_tprs + std, 1)
tprs_lower = mean_tprs - std


plt.plot(base_fpr, mean_tprs, 'b')
plt.fill_between(base_fpr, tprs_lower, tprs_upper, color='grey', alpha=0.3)

plt.plot([0, 1], [0, 1],'r--')
plt.xlim([-0.01, 1.01])
plt.ylim([-0.01, 1.01])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.axes().set_aspect('equal', 'datalim')
plt.show()

Für wiederholten Lebenslauf:

idx = np.arange(0, len(y))

for j in np.random.randint(0, high=10000, size=10):
    np.random.shuffle(idx)
    kf = KFold(n=len(y), n_folds=10, random_state=j)

    for i, (train, test) in enumerate(kf):
        model = LogisticRegression().fit(X[idx][train], y[idx][train])
        y_score = model.predict_proba(X[idx][test])
        fpr, tpr, _ = roc_curve(y[idx][test], y_score[:, 1])

        plt.plot(fpr, tpr, 'b', alpha=0.05)
        tpr = interp(base_fpr, fpr, tpr)
        tpr[0] = 0.0
        tprs.append(tpr)

Inspirationsquelle: http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc_crossval.html

Alexey Grigorev
quelle
3

Es ist nicht korrekt, die Wahrscheinlichkeiten zu mitteln, da dies nicht den Vorhersagen entspricht, die Sie validieren möchten, und eine Kontamination über Validierungsproben hinweg beinhaltet.

Es ist zu beachten, dass 100 Wiederholungen der 10-fachen Kreuzvalidierung erforderlich sein können, um eine angemessene Präzision zu erzielen. Oder verwenden Sie den Efron-Gong-Optimismus-Bootstrap, der bei gleicher Genauigkeit weniger Iterationen erfordert (siehe z. B. R- rmsPaketfunktionen validate).

ROC-Kurven sind für dieses Problem in keiner Weise aufschlussreich. Verwenden Sie eine korrekte Punktzahl und begleiten Sie diese mit demc-Index (Konkordanzwahrscheinlichkeit; AUROC), der viel einfacher zu handhaben ist als die Kurve, da er mit der Wilcoxon-Mann-Whitney-Statistik einfach und schnell berechnet werden kann.

Frank Harrell
quelle
Könnten Sie bitte näher erläutern, warum die Mittelwertbildung nicht korrekt ist?
DataD'oh
Schon gesagt. Sie müssen die Maßnahme validieren, die Sie im Feld verwenden werden.
Frank Harrell