Рассчитать кривую RO C, отчет о классификации и матрицу путаницы для задачи классификации с несколькими метками - PullRequest
2 голосов
/ 26 марта 2020

Я пытаюсь понять, как создать матрицу путаницы и кривую RO C для моей задачи классификации с несколькими метками. Я строю нейронную сеть. Вот мои уроки:

mlb = MultiLabelBinarizer()
ohe = mlb.fit_transform(as_list)
# loop over each of the possible class labels and show them
for (i, label) in enumerate(mlb.classes_):
    print("{}. {}".format(i + 1, label))

[INFO] class labels:
1. class1
2. class2
3. class3
4. class4
5. class5
6. class6

Мои метки преобразованы:

ohe
array([[0, 1, 0, 0, 1, 1],
       [0, 1, 1, 1, 1, 0],
       [1, 1, 1, 0, 1, 0],
       [0, 1, 1, 1, 0, 1],...]]

Данные обучения:

array([[[[ 1.93965047e+04,  8.49532852e-01],
         [ 1.93965047e+04,  8.49463479e-01],
         [ 1.93965047e+04,  8.49474722e-01],
         ...,

Модель:

model.compile(loss="binary_crossentropy", optimizer=opt,metrics=["accuracy"])
H = model.fit(trainX, trainY, batch_size=BS,
    validation_data=(testX, testY),
    epochs=EPOCHS, verbose=1)

Я могу получить предварительные оценки, но я немного не понимаю, как рассчитать матрицу путаницы или кривую RO C, или получить отчет о классификации ... вот эти преимущества:

proba = model.predict(testX)
idxs = np.argsort(proba)[::-1][:2]

for i in proba:
    print ('\n')
    for (label, p) in zip(mlb.classes_, i):
        print("{}: {:.2f}%".format(label, p * 100))

class1: 69.41%
class2: 76.41%
class3: 58.02%
class4: 63.97%
class5: 48.91%
class6: 58.28%

class1: 69.37%
class2: 76.42%
class3: 58.01%
class4: 63.92%
class5: 48.88%
class6: 58.26%

Если у кого-то есть Советы о том, как это сделать или пример, я был бы очень признателен! Заранее спасибо!

1 Ответ

2 голосов
/ 26 марта 2020

Начиная с версии 0.21, scikit-learn включает в себя матрицу путаницы с несколькими метками; адаптируя пример из документов для 6 классов:

import numpy as np
from sklearn.metrics import multilabel_confusion_matrix
y_true = np.array([[1, 0, 1, 0, 0],
                   [0, 1, 0, 1, 1],
                   [1, 1, 1, 0, 1]])
y_pred = np.array([[1, 0, 0, 0, 1],
                   [0, 1, 1, 1, 0],
                   [1, 1, 1, 0, 0]])

multilabel_confusion_matrix(y_true, y_pred)
# result:
array([[[1, 0],
        [0, 2]],

       [[1, 0],
        [0, 2]],

       [[0, 1],
        [1, 1]],

       [[2, 0],
        [0, 1]],

       [[0, 1],
        [2, 0]]])

Обычный classification_report также отлично работает:

from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred))
# result
              precision    recall  f1-score   support

           0       1.00      1.00      1.00         2
           1       1.00      1.00      1.00         2
           2       0.50      0.50      0.50         2
           3       1.00      1.00      1.00         1
           4       0.00      0.00      0.00         2

   micro avg       0.75      0.67      0.71         9
   macro avg       0.70      0.70      0.70         9
weighted avg       0.67      0.67      0.67         9
 samples avg       0.72      0.64      0.67         9

Что касается RO C, вы Можно взять некоторые идеи из кривых График RO C для задачи с несколькими метками * Пример 1011 * в документации (хотя не совсем уверен, что сама концепция очень полезна).

Матрица путаницы и отчет о классификации требуют жестких предсказаний класса (как в примере); RO C требует прогнозирования как вероятности.

Чтобы преобразовать ваши вероятностные c прогнозы в сложные классы, вам нужен порог. Теперь обычно (и неявно) этот порог принимается равным 0,5, т. Е. Прогнозировать 1, если y_pred > 0.5, иначе прогнозировать 0. Тем не менее, это не всегда так, и это зависит от конкретной проблемы. После того, как вы установили такой порог, вы можете легко преобразовать ваши вероятностные c прогнозы в сложные классы с пониманием списка; Вот простой пример:

import numpy as np

y_prob = np.array([[0.9, 0.05, 0.12, 0.23, 0.78],
                   [0.11, 0.81, 0.51, 0.63, 0.34],
                   [0.68, 0.89, 0.76, 0.43, 0.27]])

thresh = 0.5

y_pred = np.array([[1 if i > thresh else 0 for i in j] for j in y_prob])

y_pred
# result:
array([[1, 0, 0, 0, 1],
       [0, 1, 1, 1, 0],
       [1, 1, 1, 0, 0]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...