web-dev-qa-db-fra.com

utiliser la matrice de confusion comme métrique de notation dans la validation croisée dans scikit learn

Je crée un pipeline dans scikit learn,

pipeline = Pipeline([
    ('bow', CountVectorizer()),  
    ('classifier', BernoulliNB()), 
])

et calculer la précision en utilisant la validation croisée

scores = cross_val_score(pipeline,  # steps to convert raw messages      into models
                     train_set,  # training data
                     label_train,  # training labels
                     cv=5,  # split data randomly into 10 parts: 9 for training, 1 for scoring
                     scoring='accuracy',  # which scoring metric?
                     n_jobs=-1,  # -1 = use all cores = faster
                     )

Comment puis-je signaler une matrice de confusion au lieu de "précision"?

12
user128751

Vous pouvez utiliser cross_val_predict ( Voir les documents scikit-learn ) au lieu de cross_val_score.

au lieu de faire:

from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, x, y, cv=10)

tu peux faire :

from sklearn.model_selection import cross_val_predict
from sklearn.metrics import confusion_matrix
y_pred = cross_val_predict(clf, x, y, cv=10)
conf_mat = confusion_matrix(y, y_pred)
32
Xema

La réponse courte est "vous ne pouvez pas".

Vous devez comprendre la différence entre cross_val_score et la validation croisée comme méthode de sélection du modèle. cross_val_score comme son nom l'indique, ne fonctionne que sur scores. La matrice de confusion n'est pas un score, c'est une sorte de résumé de ce qui s'est passé pendant l'évaluation. Une distinction majeure est qu'une partition est censée retourner n objet ordonnable, en particulier dans scikit-learn - a float. Ainsi, en fonction du score, vous pouvez dire si la méthode b est meilleure à partir de a en comparant simplement si b a un score plus élevé. Vous ne pouvez pas faire cela avec une matrice de confusion qui, comme son nom l'indique, est une matrice.

Si vous voulez obtenir des matrices de confusion pour plusieurs cycles d'évaluation (comme la validation croisée), vous devez le faire à la main, ce qui n'est pas si mal dans scikit-learn - c'est en fait quelques lignes de code.

kf = cross_validation.KFold(len(y), n_folds=5)
for train_index, test_index in kf:

   X_train, X_test = X[train_index], X[test_index]
   y_train, y_test = y[train_index], y[test_index]

   model.fit(X_train, y_train)
   print confusion_matrix(y_test, model.predict(X_test))
13
lejlot

Ce que vous pouvez faire est de définir un marqueur qui utilise certaines valeurs de la matrice de confusion. Voir ici [lien] . Citant simplement le code:

def tp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 0]
def tn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 1]
def fp(y_true, y_pred): return confusion_matrix(y_true, y_pred)[1, 0]
def fn(y_true, y_pred): return confusion_matrix(y_true, y_pred)[0, 1]
scoring = {'tp' : make_scorer(tp), 'tn' : make_scorer(tn),
           'fp' : make_scorer(fp), 'fn' : make_scorer(fn)}
cv_results = cross_validate(svm.fit(X, y), X, y, scoring=scoring)

Cela effectuera la validation croisée pour chacun de ces quatre correcteurs et retournera le dictionnaire de notation cv_results, par exemple, avec les touches test_tp, test_tn, etc. contenant les valeurs des matrices de confusion de chaque division de validation croisée.

A partir de cela, vous pourriez reconstruire une matrice de confusion moyenne, mais le cross_val_predict of Xema semble plus élégant pour cela.

Notez que cela ne fonctionnera pas avec cross_val_score; tu auras besoin cross_validate (introduit dans scikit-learn v0.19).

Remarque: vous pouvez utiliser un de ces marqueurs (c'est-à-dire un élément de la matrice) pour l'optimisation hyperparamétrique via la recherche dans la grille.

* EDIT: les vrais négatifs sont retournés à [1, 1], pas à [0, 0]

2
BottleNick