Подтвердить что ты не робот

Scikit-learn: как получить True Positive, True Negative, False Positive и False Negative

Моя проблема:

У меня есть набор данных, который представляет собой большой файл JSON. Я читаю его и сохраняю в переменной trainList.

Затем я предварительно обработал его - чтобы иметь возможность работать с ним.

После этого я начинаю классификацию:

  1. Я использую kfold перекрестной проверки kfold, чтобы получить среднюю точность и обучить классификатор.
  2. Я делаю прогнозы и получаю матрицу точности и путаницы в этом сгибе.
  3. После этого я хотел бы получить значения True Positive(TP), True Negative(TN), False Positive(FP) и False Negative(FN). Я буду использовать эти параметры для получения чувствительности и специфичности.

Наконец, я бы использовал это, чтобы вставить HTML, чтобы показать диаграмму с TP каждой метки.

Код:

Переменные у меня на данный момент:

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 

Большая часть метода:

#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
4b9b3361

Ответ 1

Если у вас есть два списка, которые имеют прогнозные и фактические значения; как вам кажется, вы можете передать их в функцию, которая будет вычислять TP, FP, TN, FN примерно так:

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)

Отсюда, я думаю, вы сможете рассчитать процентные ставки для вас и другие показатели эффективности, такие как специфичность и чувствительность.

Ответ 2

Для случая с несколькими классами все, что вам нужно, можно найти из матрицы путаницы. Например, если ваша матрица замешательства выглядит так:

матрица замешательства

Затем то, что вы ищете для каждого класса, можно найти следующим образом:

overlay

Используя pandas/numpy, вы можете сделать это для всех классов одновременно:

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)

Ответ 3

Согласно документации scikit-learn,

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

По определению матрица путаницы C такова, что C [i, j] равна числу наблюдений, которые, как известно, находятся в группе i, но предсказано, что они находятся в группе j.

Таким образом, в двоичной классификации количество истинных негативов - C [0,0], ложные отрицательные значения - C [1,0], истинными значениями являются C [1,1], а ложные срабатывания - 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]

Ответ 4

Вы можете получить все параметры из матрицы путаницы. Структура матрицы путаницы (матрица 2X2) выглядит следующим образом

TP|FP
FN|TN

So

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

Подробнее на https://en.wikipedia.org/wiki/Confusion_matrix

Ответ 5

Единственный вкладыш, который извлекает истинные позитивные и т.д. Из матрицы путаницы, заключается в том, чтобы рассмешить это:

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

Ответ 6

В библиотеке метрик scikit-learn есть метод confusion_matrix, который дает желаемый результат.

Вы можете использовать любой классификатор, который вы хотите. Здесь я использовал KNeighbors в качестве примера.

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

Документы: http://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html#sklearn.metrics.confusion_matrix

Ответ 7

Вы можете попробовать sklearn.metrics.classification_report как sklearn.metrics.classification_report ниже:

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)

выход:

         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

Ответ 8

Если в вашем классификаторе имеется более одного класса, вы можете использовать pandas -ml в этой части. Матрица замешательства pandas -ml дает более подробную информацию. проверьте, что

РЕЗУЛЬТАТЫ

Ответ 9

Я написал версию, которая работает, используя только NumPy. Я надеюсь, что это поможет вам.

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

Ответ 10

Я думаю, что оба ответа не совсем корректны. Например, предположим, что у нас есть следующие массивы:
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]

Если мы вычисляем значения FP, FN, TP и TN вручную, они должны быть следующими:

FP: 3 FN: 1 ТП: 3 TN: 4

Однако, если мы используем первый ответ, результаты даются следующим образом:

FP: 1 FN: 3 ТП: 3 TN: 4

Они неправильны, потому что в первом ответе False Positive должен быть где фактическое 0, но предсказано 1, а не наоборот. Это также то же самое для False Negative.

И, если мы используем второй ответ, результаты вычисляются следующим образом:

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

Истинные положительные и истинные отрицательные числа неверны, они должны быть противоположными.

Правильно ли я с моими вычислениями? Пожалуйста, дайте мне знать, если я что-то упустил.

Ответ 11

Я попробовал некоторые ответы и обнаружил, что они не работают.

Это работает для меня:

from sklearn.metrics import classification_report

print(classification_report(y_test, predicted)) 

Ответ 12

На всякий случай, если кто-то ищет то же самое в MULTI-CLASS Примере

def perf_measure(y_actual, y_pred):
    class_id = set(y_actual).union(set(y_pred))
    TP = []
    FP = []
    TN = []
    FN = []

    for index ,_id in enumerate(class_id):
        TP.append(0)
        FP.append(0)
        TN.append(0)
        FN.append(0)
        for i in range(len(y_pred)):
            if y_actual[i] == y_pred[i] == _id:
                TP[index] += 1
            if y_pred[i] == _id and y_actual[i] != y_pred[i]:
                FP[index] += 1
            if y_actual[i] == y_pred[i] != _id:
                TN[index] += 1
            if y_pred[i] != _id and y_actual[i] != y_pred[i]:
                FN[index] += 1


    return class_id,TP, FP, TN, FN

Ответ 13

Здесь исправляется код ошибки invoketheshell (который в настоящее время отображается как принятый ответ):

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)