Интерпретация AU C, точности и показателя f1 для несбалансированного набора данных - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь понять, почему AU C является лучшим показателем c, чем точность классификации в случае, когда набор данных несбалансирован.
Предположим, что набор данных содержит 1000 примеров трех классов следующим образом:

a = [[1.0, 0, 0]]*950 + [[0, 1.0, 0]]*30 + [[0, 0, 1.0]]*20

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

b = [[0.7, 0.1, 0.2]]*1000

С истинными метками в списке a и прогнозами в списке b точность классификации составляет 0,95.
Таким образом, можно подумать, что модель действительно хорошо справляется с задачей классификации, но это не так. потому что модель предсказывает каждую точку в одном классе.
Следовательно, AU C metri c предлагается для оценки несбалансированного набора данных.
Если мы прогнозируем AU C с помощью TF Keras AU C метри c, получаем ~ 0,96.
Если мы прогнозируем f1-score с помощью sklearn f1-score metri c, установив b=[[1,0,0]]*1000, мы получаем в 0.95.

Теперь я немного сбит с толку, потому что все метрики (Точность, AU C и f1-score) показывают высокое значение, что означает, что модель действительно хороша в задаче прогнозирования (что не является случай здесь).

Какой момент мне здесь не хватает и как мы должны интерпретировать эти значения?
Спасибо.

1 Ответ

2 голосов
/ 19 июня 2020

Вы, скорее всего, используете параметр average='micro' для расчета F1-балла. Согласно docs , указание 'micro' в качестве стратегии усреднения будет:

Глобальное вычисление показателей путем подсчета общего количества истинных положительных, ложных отрицательных и ложных срабатываний.

В задачах классификации, где каждый тестовый пример гарантированно относится к одному классу, вычисление микро F1-оценки эквивалентно вычислению оценки точности. Просто проверьте:

from sklearn.metrics import accuracy_score, f1_score

y_true = [[1, 0, 0]]*950 + [[0, 1, 0]]*30 + [[0, 0, 1]]*20
y_pred = [[1, 0, 0]]*1000

print(accuracy_score(y_true, y_pred)) # 0.95

print(f1_score(y_true, y_pred, average='micro')) # 0.9500000000000001

Вы в основном вычисляли одни и те же метри c дважды. Если вместо этого указать average='macro', оценка F1 будет сначала вычисляться для каждой метки независимо, а затем усредняться:

print(f1_score(y_true, y_pred, average='macro')) # 0.3247863247863248

Как видите, общая оценка F1 зависит от стратегии усреднения и Макро F1-оценка менее 0,33 является четким индикатором недостатка модели в задаче прогнозирования.


РЕДАКТИРОВАТЬ:

Поскольку OP спрашивал, когда выбрать, какую стратегию, и я думаю, что это может быть полезно и для других, я постараюсь немного подробнее остановиться на этом вопросе.

scikit-learn фактически реализует четыре разные стратегии для показателей, которые поддерживают средние значения для задач классификации с несколькими классами и метками. Удобно, что classification_report вернет все те, которые применяются для данной задачи классификации для Precision , Recall и F1-score :

from sklearn.metrics import classification_report

# The same example but without nested lists. This avoids sklearn to interpret this as a multilabel problem.
y_true = [0 for i in range(950)] + [1 for i in range(30)] + [2 for i in range(20)]
y_pred = [0 for i in range(1000)]

print(classification_report(y_true, y_pred, zero_division=0))

######################### output ####################

              precision    recall  f1-score   support

           0       0.95      1.00      0.97       950
           1       0.00      0.00      0.00        30
           2       0.00      0.00      0.00        20

    accuracy                           0.95      1000
   macro avg       0.32      0.33      0.32      1000
weighted avg       0.90      0.95      0.93      1000

Все они дают разную перспективу в зависимости от того, сколько внимания уделяется распределению классов.

  1. micro среднее - это глобальная стратегия, которая в основном игнорирует наличие различие между классами. Это может быть полезно или оправдано, если кого-то действительно интересуют общие разногласия с точки зрения истинных положительных, ложноотрицательных и ложноположительных результатов, и его не беспокоят различия внутри классов. Как указывалось ранее, если основная проблема не заключается в задаче классификации с несколькими метками, это фактически соответствует оценке точности. (Вот почему функция classification_report вернула accuracy вместо micro avg).

  2. macro среднее значение в качестве стратегии будет вычислять каждый метри c для каждой метки отдельно и вернуть их невзвешенное среднее значение. Это подходит, если каждый класс имеет одинаковую важность и результат не должен искажаться в пользу какого-либо из классов в наборе данных.

  3. weighted среднее значение также сначала вычислит каждый метрич. c для каждой этикетки отдельно. Но среднее значение взвешивается в соответствии с поддержкой классов. Это желательно, если важность классов пропорциональна их важности, т. Е. Недопредставленный класс считается менее важным.

  4. samples среднее значение имеет значение только для классификации с несколькими ярлыками и, следовательно, не возвращается classification_report в этом примере и также здесь не обсуждается;)

Таким образом, выбор стратегии усреднения и полученного числа, которому можно доверять, действительно зависит от важности классов. Я вообще забочусь о различиях классов (если нет -> микро-среднее), и если да, то все ли классы одинаково важны (если да -> среднее макро) или более важен класс с более высокой поддержкой (-> средневзвешенное значение) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...