Подтвердить что ты не робот

Как вычислить точность, отзыв, точность и f1-score для многоклассового футляра с помощью scikit?

Я работаю над проблемой анализа настроений, данные выглядят так:

label instances
    5    1190
    4     838
    3     239
    1     204
    2     127

Таким образом, мои данные не сбалансированы, поскольку 1190 instances помечены 5. Для классификации Im используется scikit SVC. Проблема в том, что я не знаю, как правильно сбалансировать мои данные, чтобы точно вычислить точность, отзыв, точность и f1-оценку для многоклассового случая. Поэтому я пробовал следующие подходы:

Во-первых:

    wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
    wclf.fit(X, y)
    weighted_prediction = wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
                              average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
                                    average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)

Во-вторых:

auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)

print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
                            average='weighted')

print 'Recall:', recall_score(y_test, auto_weighted_prediction,
                              average='weighted')

print 'Precision:', precision_score(y_test, auto_weighted_prediction,
                                    average='weighted')

print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)

print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)

Третье:

clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)


from sklearn.metrics import precision_score, \
    recall_score, confusion_matrix, classification_report, \
    accuracy_score, f1_score

print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)


F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
 0.930416613529

Однако, я получаю предупреждения вроде этого:

/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with 
multiclass or multilabel data or pos_label=None will result in an 
exception. Please set an explicit value for `average`, one of (None, 
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for 
instance, scoring="f1_weighted" instead of scoring="f1"

Как я могу правильно обрабатывать свои несбалансированные данные, чтобы правильно вычислить метрики классификатора?

4b9b3361

Ответ 1

Я думаю, что есть много путаницы в отношении того, какие веса используются для чего. Я не уверен, что точно знаю, что вас беспокоит, поэтому я буду освещать разные темы, неся со мной;).

Вес классов

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

В основном в каждом классификаторе scikit-learn весы класса используются, чтобы сообщить вашей модели, насколько важен класс. Это означает, что во время обучения классификатор будет прилагать дополнительные усилия для правильной классификации классов с большим весом.
Как они это делают, зависит от алгоритма. Если вам нужны подробности о том, как это работает для SVC, и документ не имеет для вас смысла, не стесняйтесь упоминать его.

Показатели

Как только у вас есть классификатор, вы хотите знать, насколько он эффективен. Здесь вы можете использовать упомянутые показатели: accuracy, recall_score, f1_score...

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

Я не буду подробно описывать все эти показатели, но заметьте, что, за исключением accuracy, они естественно применяются на уровне класса: как вы можете видеть в этом print классификационного отчета, они определены для каждого класса, Они полагаются на такие понятия, как true positives или false negative, которые требуют определения того, какой класс является положительным.

             precision    recall  f1-score   support

          0       0.65      1.00      0.79        17
          1       0.57      0.75      0.65        16
          2       0.33      0.06      0.10        17
avg / total       0.52      0.60      0.51        50

Предупреждение

F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The 
default `weighted` averaging is deprecated, and from version 0.18, 
use of precision, recall or F-score with multiclass or multilabel data  
or pos_label=None will result in an exception. Please set an explicit 
value for `average`, one of (None, 'micro', 'macro', 'weighted', 
'samples'). In cross validation use, for instance, 
scoring="f1_weighted" instead of scoring="f1".

Вы получаете это предупреждение, потому что используете f1-score, отзыв и точность, не определяя, как их следует вычислять! Вопрос может быть перефразирован: из приведенного выше отчета о классификации, как вы вывести глобальное число one для f1-score? Вы могли:

  • Возьмите среднее значение f1-score для каждого класса: результат avg / total выше. Это также называется усреднением макросов.
  • Вычислить f1-score, используя глобальный счет истинных положительных/ложных негативов и т.д. (вы суммируете количество истинных положительных/ложных негативов для каждого класса). Ака микроусреднение.
  • Вычислить средневзвешенное значение f1-score. Использование 'weighted' в scikit-learn будет взвешивать f1-score при поддержке класса: чем больше элементов имеет класс, тем важнее значение f1 для этого класса при вычислении.

Это 3 варианта в scikit-learn, предупреждение заключается в том, что вы должны выбрать один. Поэтому вам нужно указать аргумент average для метода оценки.

Какой из выбранных вами вариантов зависит от того, как вы хотите измерить производительность классификатора: например, макро-усреднение не учитывает дисбаланс класса, а f1-оценка класса 1 будет столь же важна, как и f1- оценка класса 5. Если вы используете взвешенное усреднение, тем более вы получите большее значение для класса 5.

Вся спецификация аргумента в этих метриках не очень понятна в scikit-learn прямо сейчас, она будет лучше в версии 0.18 в соответствии с документами. Они устраняют некоторые неочевидные стандартные действия, и они выдают предупреждения, чтобы разработчики замечали это.

Вычисление баллов

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

Вот способ сделать это с помощью StratifiedShuffleSplit, который дает вам случайные разбиения ваших данных (после перетасовки), которые сохраняют распространение меток.

from sklearn.datasets import make_classification
from sklearn.cross_validation import StratifiedShuffleSplit
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix

# We use a utility to generate artificial classification data.
X, y = make_classification(n_samples=100, n_informative=10, n_classes=3)
sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0)
for train_idx, test_idx in sss:
    X_train, X_test, y_train, y_test = X[train_idx], X[test_idx], y[train_idx], y[test_idx]
    svc.fit(X_train, y_train)
    y_pred = svc.predict(X_test)
    print(f1_score(y_test, y_pred, average="macro"))
    print(precision_score(y_test, y_pred, average="macro"))
    print(recall_score(y_test, y_pred, average="macro"))    

Надеюсь, что это поможет.

Ответ 2

Много очень подробных ответов здесь, но я не думаю, что вы отвечаете на правильные вопросы. Насколько я понимаю, есть две проблемы:

  • Как забить многоклассовую проблему?
  • Как мне работать с несбалансированными данными?

1.

Вы можете использовать большинство функций подсчета очков в scikit-learn как с проблемой многоклассов, так и с проблемами с одним классом. Пример:.

from sklearn.metrics import precision_recall_fscore_support as score

predicted = [1,2,3,4,5,1,2,1,1,4,5] 
y_test = [1,2,3,4,5,1,2,1,1,4,1]

precision, recall, fscore, support = score(y_test, predicted)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(fscore))
print('support: {}'.format(support))

Таким образом, вы получаете осязаемые и интерпретируемые числа для каждого из классов.

| Label | Precision | Recall | FScore | Support |
|-------|-----------|--------|--------|---------|
| 1     | 94%       | 83%    | 0.88   | 204     |
| 2     | 71%       | 50%    | 0.54   | 127     |
| ...   | ...       | ...    | ...    | ...     |
| 4     | 80%       | 98%    | 0.89   | 838     |
| 5     | 93%       | 81%    | 0.91   | 1190    |

Тогда...

2.

... вы можете определить, является ли неуравновешенная информация проблемой. Если подсчет для менее представленных классов (класс 1 и 2) ниже, чем для классов с большим количеством учебных образцов (классы 4 и 5), то вы знаете, что неуравновешенные данные на самом деле являются проблемой, и вы можете действовать соответственно, поскольку описанных в некоторых других ответах в этой теме. Однако, если в данных, которые вы хотите предсказать, присутствует то же распределение классов, ваши данные о несбалансированном тренинге являются хорошим представителем данных, и, следовательно, дисбаланс - это хорошая вещь.

Ответ 3

Заданный вопрос

Отвечая на вопрос "какая метрика должна использоваться для классификации нескольких классов с несбалансированными данными": макро-F1-мера. Также могут использоваться макросы Precision и Macro Recall, но они не так легко интерпретируются, как бинарная классификация, они уже включены в F-меру, а избыточные показатели усложняют сравнение методов, настройку параметров и т.д.

Микроусреднение чувствительно к дисбалансу класса: если ваш метод, например, работает хорошо для наиболее распространенных меток и полностью беспорядочен, другие микро-усредненные показатели показывают хорошие результаты.

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

Соколова, Марина и Гай Лапальме. "Систематический анализ показатели эффективности для задач классификации". Обработка информации и Управление 45.4 (2009): 427-437.

Вопрос, специфичный для приложения

Однако, возвращаясь к вашей задаче, я бы исследовал 2 темы:

  • показатели, обычно используемые для вашей конкретной задачи - это позволяет (a) сравните свой метод с другими и поймите, если вы что-то сделаете неправильно, и (б) не исследовать это самостоятельно и повторно использовать кого-то другие выводы;
  • стоимость различных ошибок ваших методов - для Например, прецедент вашего приложения может опираться на 4- и 5-звездочные только в обзорах - в этом случае хорошая метрика должна учитывать только эти 2 этикетки.

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

  • Accuracy, который используется, например. в

Ю, Апрель и Дэрил Чанг. "Прогнозирование настроений многоклассов Yelp Business."

(ссылка) - обратите внимание, что авторы работают с почти одинаковым распределением рейтингов, см. рисунок 5.

Панг, Бо и Лилиан Ли. "Наблюдение за звездами: Эксплуатация класса отношения для категоризации предложений в отношении рейтинга масштабов". Труды 43-го Ежегодного совещания по Вычислительная лингвистика. Ассоциация вычислительной лингвистики, 2005.

(ссылка)

  1. MSE (или, реже, средняя абсолютная ошибка - MAE) - см., например,

Ли, Моонте и Р. Граф. "Анализ многоклассовых настроений с помощью обзоры ресторанов". Заключительные проекты от CS N 224 (2010).

(ссылка) - они исследуют как точность, так и MSE, считая последнее лучше

Паппас, Николаос, Рю Маркони и Андрей Попеску-Белис. "Разъяснение Звезд: взвешенное многоуровневое обучение для аспектных Анализ настроений". Материалы конференции 2014 года по эмпирическим Методы обработки естественного языка. № EPFL-CONF-200899. 2014.

(ссылка) - они используют scikit-learn для оценки и базовых подходов и заявляют, что их код доступен; однако я не могу его найти, поэтому, если вам это нужно, напишите письмо авторам, работа довольно новая и, кажется, написана на Python.

Стоимость различных ошибок. Если вам больше не нужно избегать грубых ошибок, например. осматривая 1-звездочный 5-звездный обзор или что-то в этом роде, посмотрите на MSE; если разница имеет значение, но не так много, попробуйте MAE, так как это не квадратный diff; иначе оставайтесь с точностью.

О подходах, а не метриках

Попробуйте подходы к регрессии, например. SVR, поскольку они обычно превосходят классификаторы многоклассов, такие как SVC или OVA SVM.

Ответ 4

Прежде всего, это немного сложнее, используя только подсчет анализа, чтобы определить, неудовлетворены ли ваши данные или нет. Например: 1 из 1000 положительных наблюдений - это просто шум, ошибка или прорыв в науке? Вы никогда не знаете. Поэтому всегда лучше использовать все имеющиеся знания и выбирать свой статус со всеми мудрыми.

Хорошо, что, если это действительно неуравновешено?
Еще раз - посмотрите на свои данные. Иногда вы можете найти одно или два наблюдения, умноженное на сто раз. Иногда полезно создавать эти поддельные одноклассные наблюдения.
Если все данные чисты, следующий шаг - использовать веса классов в модели прогнозирования.

А как насчет мультиклассических показателей?
По моему опыту, ни один из ваших показателей обычно не используется. Есть две основные причины.
Во-первых: всегда лучше работать с вероятностями, чем с надежным предсказанием (потому что иначе вы могли бы отделить модели с прогнозом 0,9 и 0,6, если они оба дадут вам тот же класс?)
И второе: гораздо проще сравнить ваши модели прогнозирования и построить новые, в зависимости от только одной хорошей метрики.
По моему опыту я мог бы рекомендовать logloss или MSE (или просто средняя квадратичная ошибка).

Как исправить предупреждения sklearn?
Просто (как заметил Янцзе) перезапишите параметр average одним из этих значения: 'micro' (вычислять метрики глобально), 'macro' (вычислять метрики для каждой метки) или 'weighted' (такие же, как макрос, но с автоматическими весами).

f1_score(y_test, prediction, average='weighted')

Все ваши предупреждения появились после вызова функций метрик со значением по умолчанию average 'binary', который не подходит для прогнозирования многоклассов.
Удачи и получайте удовольствие от машинного обучения!

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

Я бы рекомендовал (в рамках scikit-learn) попробовать другие очень мощные инструменты классификации: повышение градиента, случайный лес (мой любимый), KNeighbors и многие другие.

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

final_prediction = (KNNprediction * RFprediction) ** 0.5