15

Я новичок в обучении машинам и в scikit-learn.Scikit-learn: Как получить True Positive, True Negative, False Positive и False Negative

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

(Пожалуйста, исправьте любой тип missconception)

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

Я предварительно обрабатываю его, чтобы иметь возможность работать с ним.

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

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

Код:

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

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 

ответ

9

Если у вас есть два списка, которые предсказанные и реальные значения; как это кажется, что Вы делаете вы можете передать их в функцию, которая будет вычислять 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) 

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

+0

Мне любопытно, почему вы поставили сравнение с 1 и 0. Это класс по умолчанию? –

+0

Класс sklearn.preprocessing.LabelBinarizer (neg_label = 0, pos_label = 1, sparse_output = False) См.: Http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelBinarizer.html Это самый распространенный схема Я видел через пакеты, которые я использовал и бизнес я работал в. – invoketheshell

+0

Я думаю, вы должны INTER с переменой FP, FN https://en.wikipedia.org/wiki/False_positives_and_false_negatives «The ложноположительная ставка - это доля истинных негативов, которые по-прежнему дают положительные результаты теста, т. е. условную вероятность положительного результата теста при отсутствии события, которое не было ». –

15

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

TP|FP 
FN|TN 

Так

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

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

+0

В моем случае матрица смешения не 2x2, а 3x3 или 4x4. Например, я могу получить эти два массива: 'y_predicted: [0 0 0 0 0 1 1 2 0 2 2 3 2 2 2 2] y_true: [0 0 0 0 0 1 1 2 2 2 2 2 2 2 2 2] ' И я получить эту путаницу матрицу: ' [[5 0 0 0] [0 2 0 0] [1 0 7 1] [0 0 0 0]] ' – Euskalduna

+0

Я предположил двоичное классификация. По-видимому, для вашего классификатора есть 3 или 4 класса. –

+1

Для этого, если вы посмотрите на ссылку в Википедии, есть пример, рассказывающий о кошках, собаках и лошадях. Понятие истинного положительного, истинного отрицательного и т. Д. Имеет больше смысла для меня в присутствии двух классов, т.е. положительных и отрицательных. Для вашего случая я не уверен, что означает TP, FP. Вы можете поставить TP как сумму диагональных элементов, но я не уверен. Вы можете считать, что одна классификация является положительной, а все остальные - отрицательной для вычисления TP, FP и т. Д., Но я еще не уверен. –

0

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

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

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

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

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

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

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

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

+0

Я думаю, что лучший ответ для этого вопроса следующий: https://stackoverflow.com/questions/31345724/scikit-learn-how-to-calculate-the-true-negative?rq = 1 – ykorkmaz

+0

Я извиняюсь за этот глупый вопрос, но является ли истинная позиция матрицы замешательства scikit следующим образом? Верхний ряд 'TN | FP' и нижняя строка 'FN | TP'? Я пытался выяснить, что есть. Может быть, документация может быть написана для идиотов, подобных мне? :-) – salvu

7

В соответствии с scikit-узнать документация,

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

По определению путаница матрица С такой, что С [I, J] равно числу наблюдений, как известно, в группе я, но предсказал быть в группе 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] 
0

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

RESULT

28

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

confusion matrix

Тогда то, что вы ищете, в классе, можно найти так:

overlay

Использование панд/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) 
+1

, когда я хочу рассчитать значение TN, я получаю эту ошибку: «numpy.ndarray» объект не имеет атрибутов «values» Я использую python 3. – Aizzaac

+0

Такая же ошибка при использовании python 2.7 – user3184877

+2

Предполагается, что вы используя экземпляр DataFrame pandas здесь для матрицы путаницы. Если вы используете массив numpy, просто удалите часть '.values'. – macKaiver

0

В scikit освоения библиотеки «Метрика» есть confusio n_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

0

Вот исправление, чтобы 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) 
0

Я написал версию, которая работает с использованием только 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