Scikit-aprender: Cómo obtener Verdadero Positivo, Verdadero Negativo, Falso Positivo y Falso Negativo


Soy nuevo en aprendizaje automático y en scikit-learn.

Mi problema:

(Por favor, corrija cualquier tipo de malentendido)

Tengo un conjunto de datos que es un JSON GRANDE, lo recupero y lo almaceno en una variable trainList.

Lo preproceso para poder trabajar con él.

Una vez hecho esto, comienzo la clasificación:

  1. Utilizo el método de validación cruzada de kfold para obtener la media precisión y entreno a clasificador.
  2. Hago las predicciones y obtengo la precisión y la matriz de confusión de ese pliegue.
  3. Después de esto, me gustaría obtener los valores de Verdadero Positivo(TP), Verdadero Negativo(TN), Falso Positivo(FP) y Falso Negativo(FN). Usaría estos parámetros para obtener la Sensibilidad y la especificidad y los usaría y el total del TPs a un HTML para mostrar un gráfico con el TPs de cada etiqueta.

Código:

Las variables que tengo para el momento:

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 Mayor parte del método:

#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
Author: Euskalduna, 2015-07-09

10 answers

Si tiene dos listas que tienen los valores predichos y reales; como parece que lo hace, puede pasarlos a una función que calculará TP, FP, TN, FN con algo como esto:

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)

A partir de aquí creo que usted será capaz de calcular las tasas de interés para usted, y otras medidas de rendimiento como la especificidad y la sensibilidad.

 11
Author: invoketheshell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 22:52:29

Para el caso multi-clase, todo lo que necesita se puede encontrar en la matriz de confusión. Por ejemplo, si su matriz de confusión se ve así:

matriz de confusión

Entonces lo que estás buscando, por clase, se puede encontrar así:

superposición

Usando pandas / numpy, puede hacer esto para todas las clases a la vez de la siguiente manera:

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)
 54
Author: lucidv01d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-10 19:28:13

Puede obtener todos los parámetros de la matriz de confusión. La estructura de la matriz de confusión(que es la matriz 2X2) es la siguiente

TP|FP
FN|TN

So

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

Más detalles en https://en.wikipedia.org/wiki/Confusion_matrix

 17
Author: Akshat Harit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-09 17:50:02

De acuerdo con la documentación de scikit-learn,

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

Por definición, una matriz de confusión C es tal que C [i, j] es igual al número de observaciones conocidas por estar en el grupo i pero predichas por estar en el grupo j.

Así, en la clasificación binaria, el recuento de negativos verdaderos es C [0,0], negativos falsos es C [1,0], positivos verdaderos es C [1,1] y falsos positivos es 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]
 12
Author: gruangly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-29 22:09:28

En la biblioteca 'metrics' de scikit-learn hay un método confusion_matrix que le da la salida deseada.

Puede utilizar cualquier clasificador que desee. Aquí usé los rodilleros como ejemplo.

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]]

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

 3
Author: Joseloman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-31 14:40:48

Puedes probar sklearn.metrics.classification_report de la siguiente manera:

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)

Salida:

         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
Author: daniel.kaifeng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 09:43:23

Creo que ambas respuestas no son totalmente correctas. Por ejemplo, supongamos que tenemos los siguientes arrays;
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 calculamos los valores FP, FN, TP y TN manualmente, deben ser los siguientes:

PF: 3 FN: 1 TP: 3 TN: 4

Sin embargo, si usamos la primera respuesta, los resultados se dan de la siguiente manera:

PF: 1 FN: 3 TP: 3 TN: 4

No son correctos, porque en la primera respuesta, el Falso positivo debe ser donde real es 0, pero el predicho es 1, no lo contrario. También es lo mismo para el Falso Negativo.

Y, si usamos la segunda respuesta, los resultados se calculan de la siguiente manera:

PF: 3 FN: 1 TP: 4 TN: 3

Los números Verdaderos Positivos y Verdaderos Negativos no son correctos, deben ser opuestos.

¿Estoy en lo correcto con mis cálculos? Por favor, hágamelo saber si me estoy perdiendo algo.

 0
Author: ykorkmaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-12 15:19:19

Si tiene más de una clase en su clasificador, es posible que desee usar pandas-ml en esa parte. La matriz de confusión de pandas-ml proporciona información más detallada. compruebe que

RESULTADO

 0
Author: enterbutton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-16 19:31:01

Escribí una versión que funciona usando solo numpy. Espero que te ayude.

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
 0
Author: Julio Cárdenas-Rodríguez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-08 18:29:16

Aquí hay una solución al código de error de invoketheshell (que actualmente aparece como la respuesta aceptada):

def performance_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] == 0:
            FP += 1
        if y_hat[i] == y_actual[i] == 0:
            TN +=1
        if y_hat[i] == 0 and y_actual[i] == 1:
            FN +=1

    return(TP, FP, TN, FN)
 -1
Author: andandandand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-05 18:17:03