web-dev-qa-db-de.com

Wie wird die Genauigkeit von scikit-learn cross_val_predict berechnet?

Berechnet der cross_val_predict (siehe doc , v0.18) mit der Methode k -fold wie im nachstehenden Code gezeigt die Genauigkeit für jede Faltung und mittelt sie schließlich oder nicht? 

cv = KFold(len(labels), n_folds=20)
clf = SVC()
ypred = cross_val_predict(clf, td, labels, cv=cv)
accuracy = accuracy_score(labels, ypred)
print accuracy
11
hiker

Nein, tut es nicht!

Gemäß cross validation doc page gibt cross_val_predict keine Bewertungen zurück, sondern nur die Labels, die auf einer bestimmten Strategie basieren, die hier beschrieben wird:

Die Funktion cross_val_predict hat eine ähnliche Schnittstelle wie cross_val_score, , gibt jedoch für jedes Element in der Eingabe das .__ zurück. Vorhersage, die für dieses Element erhalten wurde, als es sich im Test befand einstellen. Nur Kreuzvalidierungsstrategien, die alle Elemente einem .__ zuweisen. Testsatz genau einmal verwendet werden kann (andernfalls wird eine Ausnahme ausgelöst).

Wenn Sie also accuracy_score(labels, ypred)aufrufen, berechnen Sie nur die Genauigkeitswerte von Labels, die durch die oben genannte bestimmte Strategie vorhergesagt wurden, im Vergleich zu den True Labels. Dies ist wiederum auf derselben Dokumentationsseite angegeben:

Diese Vorhersage kann dann verwendet werden, um den Klassifizierer auszuwerten:

predicted = cross_val_predict(clf, iris.data, iris.target, cv=10) 
metrics.accuracy_score(iris.target, predicted)

Beachten Sie, dass das Ergebnis dieser Berechnung leicht abweichen kann von denen, die mit cross_val_score erhalten wurden, da die Elemente gruppiert sind auf veschiedenen Wegen.

Wenn Sie Genauigkeitsbewertungen verschiedener Falten benötigen, sollten Sie Folgendes versuchen:

>>> scores = cross_val_score(clf, X, y, cv=cv)
>>> scores                                              
array([ 0.96...,  1.  ...,  0.96...,  0.96...,  1.        ])

und dann für die mittlere Genauigkeit aller Falten scores.mean():

>>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
Accuracy: 0.98 (+/- 0.03)

Bearbeiten:

Für die Berechnung von Cohen Kappa coefficient und der Verwirrungsmatrix habe ich angenommen, dass Sie den Kappa-Koeffizienten und die Verwirrungsmatrix zwischen wahren Bezeichnungen und den vorhergesagten Bezeichnungen jeder Falte bedeuten:

from sklearn.model_selection import KFold
from sklearn.svm.classes import SVC
from sklearn.metrics.classification import cohen_kappa_score
from sklearn.metrics import confusion_matrix

cv = KFold(len(labels), n_folds=20)
clf = SVC()
for train_index, test_index in cv.split(X):
    clf.fit(X[train_index], labels[train_index])
    ypred = clf.predict(X[test_index])
    kappa_score = cohen_kappa_score(labels[test_index], ypred)
    confusion_matrix = confusion_matrix(labels[test_index], ypred)

Edit 2:

Was gibt cross_val_predict zurück?

KFold teilt die Daten in k Parts auf und führt dann für i = 1..k Iterationen Folgendes aus: Nimmt alle Parts mit Ausnahme von i'th als Trainingsdaten an, passt das Modell an sie an und prognostiziert dann Labels für den i-ten Teil (Testdaten ). In jeder Iteration wird die Beschriftung des i-ten Teils der Daten vorhergesagt. Am Ende führt cross_val_predict alle teilweise vorhergesagten Labels zusammen und gibt sie als Ganzes zurück.

Dieser Code zeigt diesen Prozess Schritt für Schritt:

X = np.array([[0], [1], [2], [3], [4], [5]])
labels = np.array(['a', 'a', 'a', 'b', 'b', 'b'])

cv = KFold(len(labels), n_folds=3)
clf = SVC()
ypred_all = np.chararray((labels.shape))
i = 1
for train_index, test_index in cv.split(X):
    print("iteration", i, ":")
    print("train indices:", train_index)
    print("train data:", X[train_index])
    print("test indices:", test_index)
    print("test data:", X[test_index])
    clf.fit(X[train_index], labels[train_index])
    ypred = clf.predict(X[test_index])
    print("predicted labels for data of indices", test_index, "are:", ypred)
    ypred_all[test_index] = ypred
    print("merged predicted labels:", ypred_all)
    i = i+1
    print("=====================================")
y_cross_val_predict = cross_val_predict(clf, X, labels, cv=cv)
print("predicted labels by cross_val_predict:", y_cross_val_predict)

Das Ergebnis ist:

iteration 1 :
train indices: [2 3 4 5]
train data: [[2] [3] [4] [5]]
test indices: [0 1]
test data: [[0] [1]]
predicted labels for data of indices [0 1] are: ['b' 'b']
merged predicted labels: ['b' 'b' '' '' '' '']
=====================================
iteration 2 :
train indices: [0 1 4 5]
train data: [[0] [1] [4] [5]]
test indices: [2 3]
test data: [[2] [3]]
predicted labels for data of indices [2 3] are: ['a' 'b']
merged predicted labels: ['b' 'b' 'a' 'b' '' '']
=====================================
iteration 3 :
train indices: [0 1 2 3]
train data: [[0] [1] [2] [3]]
test indices: [4 5]
test data: [[4] [5]]
predicted labels for data of indices [4 5] are: ['a' 'a']
merged predicted labels: ['b' 'b' 'a' 'b' 'a' 'a']
=====================================
predicted labels by cross_val_predict: ['b' 'b' 'a' 'b' 'a' 'a']
36
Omid

Wie Sie dem Code von cross_val_predict on github entnehmen können, berechnet die Funktion für jede Falz die Vorhersagen und verkettet sie. Die Vorhersagen basieren auf einem Modell, das aus anderen Falten gewonnen wurde.

Hier ist eine Kombination aus Ihrem Code und dem im Code enthaltenen Beispiel

from sklearn import datasets, linear_model
from sklearn.model_selection import cross_val_predict, KFold
from sklearn.metrics import accuracy_score

diabetes = datasets.load_diabetes()
X = diabetes.data[:400]
y = diabetes.target[:400]
cv = KFold(n_splits=20)
lasso = linear_model.Lasso()
y_pred = cross_val_predict(lasso, X, y, cv=cv)
accuracy = accuracy_score(y_pred.astype(int), y.astype(int))

print(accuracy)
# >>> 0.0075

Schließlich, um Ihre Frage zu beantworten: "Nein, die Genauigkeit wird nicht für jede Falte gemittelt"

5
BloodyD

Ich möchte eine Option für eine schnelle und einfache Antwort hinzufügen, die über den früheren Entwicklern liegt. 

Wenn Sie den Mikro-Durchschnitt von F1 nehmen, erhalten Sie im Wesentlichen die Genauigkeitsrate. Das wäre zum Beispiel:

from sklearn.model_selection import cross_val_score, cross_val_predict
from sklearn.metrics import precision_recall_fscore_support as score    

y_pred = cross_val_predict(lm,df,y,cv=5)
precision, recall, fscore, support = score(y, y_pred, average='micro') 
print(fscore)

Dies funktioniert mathematisch, da der Mikromittelwert den gewichteten Durchschnitt der Verwirrungsmatrix angibt.

Viel Glück. 

0
Shlomo Koppel

Wie in der Dokumenation sklearn.model_selection.cross_val_predict geschrieben

Es ist nicht angemessen, diese Vorhersagen in eine Bewertung zu übernehmen metrisch. Benutzen cross_validate um den Generalisierungsfehler zu messen.

0
Enrico Damini