Scikit-узнайте: как получить истинный позитив, истинный негатив, ложноположительный и ложноотрицательный
Я новичок в машинном обучении и в scikit-learn.
моя проблема:
(пожалуйста, поправьте любого типа missconception)
у меня есть набор данных, который является большим JSON, я извлекаю его и храню в trainList
переменной.
я предварительно обрабатываю его, чтобы иметь возможность работать с ним.
как только я это сделаю, я начинаю классификацию:
- я использую метод перекрестной проверки kfold для получения средство точность и я тренирую классификатор.
- я делаю предсказания, и я получаю матрицу точности и путаницы этой складки.
- после этого я хотел бы получить истинные положительные(TP), истинные отрицательные(TN), ложноположительные(FP) и ложноотрицательные(FN) значения. Я бы использовал эти параметры для получения чувствительности и специфичности, и я бы их и общее количество TPs в HTML, чтобы показать диаграмму с TPs каждого этикетка.
код:
переменные, которые у меня есть на данный момент:
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
10 ответов
Если у вас есть два списка, которые имеют предсказанные и фактические значения; как представляется, вы можете передать их функции, которая будет вычислять 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)
отсюда я думаю, что вы сможете рассчитать процентные ставки для вас и другие показатели эффективности, такие как специфичность и чувствительность.
для случая с несколькими классами все, что вам нужно, можно найти в матрице путаницы. Например, если ваша матрица путаницы выглядит так:
тогда то, что вы ищете, для каждого класса, можно найти следующим образом:
используя 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)
Вы можете получить все параметры из Матрицы смешения. Структура матрицы путаницы (которая является матрицей 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
согласно документации scikit-learn,
по определению матрица путаницы C такова, что C[i, j] равна числу наблюдений, известных в группе i, но предсказанных в группе j.
таким образом, в двоичной классификации количество истинных негативов равно C[0,0], ложных негативов-C[1,0], true положительные - 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]
в библиотеке scikit-learn "metrics" есть метод 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]]
вы можете попробовать 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
Я думаю, что оба ответа не полностью верны. Например, предположим, что у нас есть следующие массивы;
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 TP: 3 TN: 4
однако, если мы используем первый ответ, результаты даются следующим образом:
FP: 1 FN: 3 TP: 3 ТЕННЕССИ: 4
они неверны, потому что в первом ответе ложноположительный должен быть там, где фактический равен 0, но предсказанный равен 1, а не наоборот. Это также для ложноотрицательный.
и, если мы используем второй ответ, результаты вычисляются следующим образом:
FP: 3 FN: 1 TP: 4 TN: 3
истинные положительные и истинные отрицательные числа неверны, они должны быть противоположными.
Я прав с моими вычислениями? Пожалуйста, дайте мне знать, если я чего-то не хватает.
Если у вас есть более одного класса в вашем классификаторе, вы можете использовать pandas-ml в этой части. Матрица путаницы pandas-ml дает более подробную информацию. проверяем, что
Я написал версию, которая работает, используя только 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
вот исправление для вызова багги-кода (который в настоящее время отображается как принятый ответ):
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)