Я хочу вычислить показатели производительности для многоклассового классификатора, в частности, точности, отзыва и F-показателя.
Особенность моих классов в том, что есть некоторые прогнозируемые метки, которые не отображаются в истинном наборе меток.
Модуль metrics
в sklearn
испытывает затруднения при работе с прогнозируемыми меткамикоторые не отображаются в истинном наборе меток при вычислении отзыва и F-счета. Вопреки советам в других постах, предоставление явного инвентарного ярлыка не решает проблему.
Это несоответствие может возникнуть, например, при оценке производительности подмножества данных. Например, в системах распознавания именованных сущностей у вас есть именованные метки сущностей (например, "PERSON"
, "ORGANIZATION"
, "LOCATION"
) и метка для обозначения неименованных сущностей (например, "O"
). Для оценки вас обычно интересует только производительность именованных объектов (т. Е. Строк в вашем наборе данных, где истинная метка не "O"
). Но, как это часто бывает, некоторые из предсказанных ярлыков будут "O"
, что приведет к несоответствию между запасами ярлыков в предсказанном и истинном наборе.
Рассмотрим этот игрушечный пример. У вас есть проблема классификации нескольких классов с 3 классами: "a"
, "b"
и "c"
. В истинном наборе меток встречаются только "a"
и "b"
, но в одном из случаев классификатор прогнозирует "c"
.
import pandas as pd
import numpy as np
from sklearn import metrics
from prettytable import PrettyTable
data = pd.DataFrame(np.array([["a", "a"], ["b", "a"], ["b", "b"], ["c", "b"]]),
columns=['pred', 'true'])
> pred true
> 0 a a
> 1 b a
> 2 b b
> 3 c b
Матрица путаницы производительности выглядит следующим образом:
t = PrettyTable(['', 'a', 'b', 'c'])
t.add_row(['a', 1, 0, 0])
t.add_row(['b', 1, 1, 0])
t.add_row(['b', 0, 1, 0])
print(t)
> +---+---+---+---+
> | | a | b | c |
> +---+---+---+---+
> | a | 1 | 0 | 0 |
> | b | 1 | 1 | 0 |
> | c | 0 | 1 | 0 |
> +---+---+---+---+
Из приведенной выше матрицы путаницы ожидаемые метрики должны быть следующими:
PRECISION:
a: 1/1 = 1.0
b: 1/2 = 0.5
c: 0/1 = 0.0
overall => 0.5
RECALL:
a: 1/2 = 0.5
b: 1/2 = 0.5
c: 0/0 = NaN -> 0.0
overall => 0.(3)
Обратите внимание, что при вызове агрегированной функции metrics
в sklearn
Я явно указываю истинный инвентарь меток в аргументе labels
для вызова функции: list(set(data['pred']))
, чтобы он включал все метки, даже если они не видны в столбце истинной метки (здесь "c"
). Это решение, предложенное в следующем сообщении:
UndefinedMetricWarning: F-оценка неправильно определена и имеет значение 0,0 в метках без прогнозируемых выборок
Примечание такжечто я хочу установить average
на 'weighted'
, потому что в реальном мире мои классы обычно сильно разбалансированы.
metrics.precision_recall_fscore_support(data['true'],
data['pred'],
average='weighted',
labels=list(set(data['pred'])))[:-1]
Я получаю предупреждение и следующий результат:
# If you call the function more than once,
# it will automatically suppress the warning,
# so if you no longer see the warning, this is probably the reason.
UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0 in labels with no true samples.
'recall', 'true', average, warn_for)
(0.75, 0.5, 0.5833333333333333)
Как видите, точность и отзыв отличаются от моих расчетов. Оценка имеет смысл, если вы предполагаете, что функция не включала производительность для "c"
при вычислении среднего значения в обеих метриках.
Очевидно, что предоставление функции явным списком истинных меток не устраняет проблему. Что можно сделать, чтобы sklearn
включил "c"
в расчеты?