web-dev-qa-db-fra.com

Scikit-learn: Comment obtenir un vrai positif, un vrai négatif, un faux positif et un faux négatif

Je suis nouveau en apprentissage machine et en scikit-learn.

Mon problème:

(S'il vous plaît, corrigez tout type de missconception)

J'ai un jeu de données qui est un gros JSON, je le récupère et le stocke dans une variable trainList.

Je le prétraite pour pouvoir travailler avec.

Une fois que j'ai fait cela, je commence le classement:

  1. J'utilise la méthode de validation croisée kfold pour obtenir la précision moyenne et un classifieur.
  2. Je fais les prédictions et j'obtiens la matrice de précision et de confusion de ce pli.
  3. Après cela, j'aimerais obtenir les valeurs True Positive (TP), True Negative (TN), False Positive (FP) et False Negative (FN). Je voudrais utiliser ces paramètres pour obtenir la sensibilité et la spécificité et je voudrais eux et le total des TP à un code HTML afin d'afficher un graphique avec les TP de chaque étiquette.

Code:

Les variables que j'ai pour le moment:

trainList #It is a list with all the data of my dataset in JSON form
labelList #It is a list with all the labels of my data 

La plus grande partie de la méthode:

#I transform the data from JSON form to a numerical one
X=vec.fit_transform(trainList)

#I scale the matrix (don't know why but without it, it makes an error)
X=preprocessing.scale(X.toarray())

#I generate a KFold in order to make cross validation
kf = KFold(len(X), n_folds=10, indices=True, shuffle=True, random_state=1)

#I start the cross validation
for train_indices, test_indices in kf:
    X_train=[X[ii] for ii in train_indices]
    X_test=[X[ii] for ii in test_indices]
    y_train=[listaLabels[ii] for ii in train_indices]
    y_test=[listaLabels[ii] for ii in test_indices]

    #I train the classifier
    trained=qda.fit(X_train,y_train)

    #I make the predictions
    predicted=qda.predict(X_test)

    #I obtain the accuracy of this fold
    ac=accuracy_score(predicted,y_test)

    #I obtain the confusion matrix
    cm=confusion_matrix(y_test, predicted)

    #I should calculate the TP,TN, FP and FN 
    #I don't know how to continue
30
Euskalduna

Si vous avez deux listes qui ont les valeurs prédites et réelles; comme il semble que vous le fassiez, vous pouvez les transmettre à une fonction qui calculera TP, FP, TN, FN avec quelque chose comme ceci:

def perf_measure(y_actual, y_hat):
    TP = 0
    FP = 0
    TN = 0
    FN = 0

    for i in range(len(y_hat)): 
        if y_actual[i]==y_hat[i]==1:
           TP += 1
        if y_hat[i]==1 and y_actual[i]!=y_hat[i]:
           FP += 1
        if y_actual[i]==y_hat[i]==0:
           TN += 1
        if y_hat[i]==0 and y_actual[i]!=y_hat[i]:
           FN += 1

return(TP, FP, TN, FN)

À partir de là, je pense que vous pourrez calculer les taux d’intérêt pour vous et d’autres mesures de performance telles que la spécificité et la sensibilité.

14
invoketheshell

Pour le cas multi-classes, tout ce dont vous avez besoin peut être trouvé dans la matrice de confusion. Par exemple, si votre matrice de confusion ressemble à ceci:

 confusion matrix

Ensuite, ce que vous recherchez, par classe, peut être trouvé comme ceci:

 overlay

En utilisant pandas/numpy, vous pouvez le faire pour toutes les classes à la fois, comme ceci:

FP = confusion_matrix.sum(axis=0) - np.diag(confusion_matrix)  
FN = confusion_matrix.sum(axis=1) - np.diag(confusion_matrix)
TP = np.diag(confusion_matrix)
TN = confusion_matrix.values.sum() - (FP + FN + TP)

# Sensitivity, hit rate, recall, or true positive rate
TPR = TP/(TP+FN)
# Specificity or true negative rate
TNR = TN/(TN+FP) 
# Precision or positive predictive value
PPV = TP/(TP+FP)
# Negative predictive value
NPV = TN/(TN+FN)
# Fall out or false positive rate
FPR = FP/(FP+TN)
# False negative rate
FNR = FN/(TP+FN)
# False discovery rate
FDR = FP/(TP+FP)

# Overall accuracy
ACC = (TP+TN)/(TP+FP+FN+TN)
66
lucidv01d

Vous pouvez obtenir tous les paramètres de la matrice de confusion. La structure de la matrice de confusion (qui est une matrice 2X2) est la suivante

TP|FP
FN|TN

Alors 

TP = cm[0][0]
FP = cm[0][1]
FN = cm[1][0]
TN = cm[1][1]

Plus de détails sur https://en.wikipedia.org/wiki/Confusion_matrix

17
Akshat Harit

Selon la documentation scikit-learn,

http://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html#sklearn.metrics.confusion_matrix

Par définition, une matrice de confusion C est telle que C [i, j] est égal au nombre d'observations connues pour appartenir au groupe i mais prévues pour appartenir au groupe j.

Ainsi, dans la classification binaire, le nombre de vrais négatifs est C [0,0], les faux négatifs est C [1,0], les vrais positifs est C [1,1] et les faux positifs est C [0,1].

CM = confusion_matrix(y_true, y_pred)

TN = CM[0][0]
FN = CM[1][0]
TP = CM[1][1]
FP = CM[0][1]
15
gruangly

Dans la bibliothèque 'metrics' de scikit-learn, il existe une méthode confusion_matrix qui vous donne le résultat souhaité.

Vous pouvez utiliser n'importe quel classificateur que vous voulez. Ici, j'ai utilisé l'exemple des KNeinges.

from sklearn import metrics, neighbors

clf = neighbors.KNeighborsClassifier()

X_test = ...
y_test = ...

expected = y_test
predicted = clf.predict(X_test)

conf_matrix = metrics.confusion_matrix(expected, predicted)

>>> print conf_matrix
>>>  [[1403   87]
     [  56 3159]]

Les documents: http://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html#sklearn.metrics.confusion_matrix

3
Joseloman

J'ai écrit une version qui fonctionne uniquement avec numpy . J'espère que cela vous aidera.

import numpy as np

def perf_metrics_2X2(yobs, yhat):
    """
    Returns the specificity, sensitivity, positive predictive value, and 
    negative predictive value 
    of a 2X2 table.

    where:
    0 = negative case
    1 = positive case

    Parameters
    ----------
    yobs :  array of positive and negative ``observed`` cases
    yhat : array of positive and negative ``predicted`` cases

    Returns
    -------
    sensitivity  = TP / (TP+FN)
    specificity  = TN / (TN+FP)
    pos_pred_val = TP/ (TP+FP)
    neg_pred_val = TN/ (TN+FN)

    Author: Julio Cardenas-Rodriguez
    """
    TP = np.sum(  yobs[yobs==1] == yhat[yobs==1] )
    TN = np.sum(  yobs[yobs==0] == yhat[yobs==0] )
    FP = np.sum(  yobs[yobs==1] == yhat[yobs==0] )
    FN = np.sum(  yobs[yobs==0] == yhat[yobs==1] )

    sensitivity  = TP / (TP+FN)
    specificity  = TN / (TN+FP)
    pos_pred_val = TP/ (TP+FP)
    neg_pred_val = TN/ (TN+FN)

    return sensitivity, specificity, pos_pred_val, neg_pred_val

Le seul moyen pour obtenir de vrais positifs, etc., de la matrice de confusion est de voyager it:

from sklearn.metrics import confusion_matrix

y_true = [1, 1, 0, 0]
y_pred = [1, 0, 1, 0]   

tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
print(tn, fp, fn, tp)  # 1 1 1 1
1
Jarno

vous pouvez essayer sklearn.metrics.classification_report comme ci-dessous:

import sklearn
y_true = [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0]
y_pred = [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0]

print sklearn.metrics.classification_report(y_true, y_pred)

sortie:

         precision    recall  f1-score   support

      0       0.80      0.57      0.67         7
      1       0.50      0.75      0.60         4

      avg / total       0.69      0.64      0.64        11
1
daniel.kaifeng

si vous avez plus d'une classe dans votre classificateur, vous pouvez utiliser pandas-ml à cette partie. La matrice de confusion de pandas-ml donne des informations plus détaillées. regarde ça

 RESULT

0
enterbutton

Je pense que les deux réponses ne sont pas tout à fait correctes. Par exemple, supposons que nous ayons les tableaux suivants;
y_actual = [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0]

y_predic = [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0]

Si nous calculons les valeurs FP, FN, TP et TN manuellement, elles devraient être les suivantes:

FP: 3 FN: 1TP: 3TN: 4

Cependant, si nous utilisons la première réponse, les résultats sont donnés comme suit:

FP: 1 FN: 3TP: 3TN: 4

Ils ne sont pas corrects, car dans la première réponse, Faux positif devrait être où la valeur réelle est 0, mais la prédiction est 1, et non l'inverse. Il en va de même pour False Negative.

Et, si nous utilisons la deuxième réponse, les résultats sont calculés comme suit:

FP: 3 FN: 1TP: 4TN: 3

Vrai Positif et Vrai Négatif Les chiffres ne sont pas corrects, ils devraient être opposés.

Suis-je correct avec mes calculs? S'il vous plaît laissez-moi savoir si je manque quelque chose.

0
ykorkmaz