Я работаю над проблемой анализа настроений, данные выглядят так:
label instances
5 1190
4 838
3 239
1 204
2 127
Таким образом, мои данные несбалансированы, поскольку 1190 instances
помечены значком 5
. Для классификации я использую SVC scikit . Проблема в том, что я не знаю, как правильно сбалансировать мои данные, чтобы точно вычислить точность, отзыв, точность и показатель 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"
Как я могу правильно обработать мои несбалансированные данные, чтобы правильно вычислить метрики классификатора?
python
machine-learning
nlp
artificial-intelligence
scikit-learn
new_with_python
источник
источник
average
параметр в третьем случае?Ответы:
Я думаю, что существует большая путаница относительно того, какие веса используются для чего. Я не уверен, что точно знаю, что вас беспокоит, поэтому я собираюсь затронуть разные темы, терпите меня;).
Вес класса
Веса из
class_weight
параметра используются для обучения классификатора . Они не используются при вычислении каких-либо показателей, которые вы используете : с разными весами классов числа будут разными просто потому, что классификатор другой.По сути, в каждом классификаторе scikit-learn веса классов используются, чтобы сообщить вашей модели, насколько важен класс. Это означает, что во время обучения классификатор приложит дополнительные усилия, чтобы правильно классифицировать классы с большим весом.
Как они это делают, зависит от алгоритма. Если вам нужны подробности о том, как это работает для SVC, и документ не имеет для вас смысла, не стесняйтесь упомянуть об этом.
Метрики
Если у вас есть классификатор, вы хотите знать, насколько хорошо он работает. Здесь вы можете использовать метрики вы упомянули:
accuracy
,recall_score
,f1_score
...Обычно, когда распределение классов несбалансировано, точность считается плохим выбором, поскольку она дает высокие баллы моделям, которые просто предсказывают наиболее частый класс.
Я не буду подробно описывать все эти показатели, но отмечу, что, за исключением
accuracy
, они естественно применяются на уровне класса: как вы можете видеть в этомprint
отчете о классификации, они определены для каждого класса. Они полагаются на такие концепции, какtrue positives
илиfalse negative
которые требуют определения того, какой класс является положительным .Предупреждение
Вы получаете это предупреждение, потому что используете f1-score, отзыв и точность, не определяя, как они должны быть вычислены! Вопрос можно перефразировать: как вывести одно глобальное число для оценки f1 из приведенного выше отчета о классификации ? Ты мог:
avg / total
результат выше. Это также называется макро- усреднением.'weighted'
в scikit-learn будет взвешивать оценку f1 с помощью поддержки класса: чем больше элементов имеет класс, тем важнее оценка f1 для этого класса в вычислениях.Это 3 варианта в scikit-learn, предупреждение говорит о том, что вам нужно выбрать один . Таким образом, вы должны указать
average
аргумент для метода оценки.Какой из них вы выберете, зависит от того, как вы хотите измерить производительность классификатора: например, при макро-усреднении не учитывается дисбаланс классов, и оценка f1 класса 1 будет так же важна, как и оценка класса f1 5. Однако, если вы используете взвешенное усреднение, вы получите большее значение для класса 5.
Вся спецификация аргументов в этих метриках не очень ясна в scikit-learn прямо сейчас, она улучшится в версии 0.18, согласно документации. Они удаляют некоторые неочевидные стандартные действия и выдают предупреждения, чтобы разработчики это заметили.
Вычисление оценок
Последнее, что я хочу упомянуть (не стесняйтесь пропустить, если вы об этом знаете), это то, что оценки имеют смысл только в том случае, если они вычисляются на основе данных, которые классификатор никогда не видел . Это чрезвычайно важно, поскольку любая оценка, которую вы получите по данным, которые использовались при подборе классификатора, совершенно не имеет значения.
Вот способ сделать это, используя
StratifiedShuffleSplit
, который дает вам случайные части ваших данных (после перетасовки), которые сохраняют распределение меток.Надеюсь это поможет.
источник
class_weight={1:10}
означает данные, имеющие 3 класса?ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.
. Он отлично работает с разделением поезд-тест, но может ли кто-нибудь мне помочь, почему я получаю эту ошибку с SSS? Спасибо.Здесь много очень подробных ответов, но я не думаю, что вы отвечаете на правильные вопросы. Насколько я понимаю вопрос, есть две проблемы:
1.
Вы можете использовать большинство функций оценки в scikit-learn как с проблемой мультикласса, так и с задачами одного класса. Например:
Таким образом, вы получите осязаемые и интерпретируемые числа для каждого из классов.
Затем...
2.
... вы можете сказать, являются ли несбалансированные данные проблемой. Если оценка для менее представленных классов (класс 1 и 2) ниже, чем для классов с большим количеством обучающих выборок (класс 4 и 5), то вы знаете, что несбалансированные данные на самом деле являются проблемой, и вы можете действовать соответственно, как описано в некоторых других ответах в этой теме. Однако, если в данных, которые вы хотите прогнозировать, присутствует то же распределение классов, ваши несбалансированные данные обучения являются хорошим представителем данных, и, следовательно, дисбаланс - это хорошо.
источник
precision_recall_fscore_support
? Этикетки напечатаны по заказу?average=None
и определите метки, а затем вы получите метрику, которую ищете, для каждой из указанных вами меток.Поставленный вопрос
Ответ на вопрос «какую метрику следует использовать для мультиклассовой классификации с несбалансированными данными»: Макро-F1-мера. Также можно использовать Macro Precision и Macro Recall, но их не так легко интерпретировать, как для двоичной классификации, они уже включены в F-меру, а избыточные метрики усложняют сравнение методов, настройку параметров и т. Д.
Микро-усреднение чувствительно к дисбалансу классов: если ваш метод, например, хорошо работает для наиболее распространенных ярлыков и полностью портит другие, микро-усредненные показатели показывают хорошие результаты.
Усреднение с взвешиванием не очень хорошо подходит для несбалансированных данных, поскольку оно взвешивается по количеству меток. Более того, оно слишком трудно интерпретируемое и непопулярное: например, в следующем очень подробном обзоре, который я настоятельно рекомендую просмотреть, нет упоминания о таком усреднении :
Вопрос по конкретному приложению
Однако, возвращаясь к вашей задаче, я бы исследовал 2 темы:
Часто используемые метрики. Изучив литературу, я могу сделать вывод, что есть 2 основных показателя оценки:
( ссылка ) - обратите внимание, что авторы работают практически с одинаковым распределением оценок, см. рисунок 5.
( ссылка )
( ссылка ) - они исследуют как точность, так и MSE, считая последнее лучше
( ссылка ) - они используют scikit-learn для оценки и базового подхода и заявляют, что их код доступен; однако я не могу его найти, поэтому, если вам это нужно, напишите письмо авторам, работа довольно новая и, похоже, написана на Python.
Стоимость разных ошибок . Если вы больше заботитесь о том, чтобы избежать грубых ошибок, например, присвоить обзор от 1 до 5 или что-то в этом роде, посмотрите MSE; если разница имеет значение, но не так уж и много, попробуйте MAE, так как она не квадратирует разницу; в противном случае оставайтесь с точностью.
О подходах, а не о показателях
Попробуйте подходы регрессии, например SVR , поскольку они обычно превосходят классификаторы Multiclass, такие как SVC или OVA SVM.
источник
Во-первых, немного сложнее использовать простой подсчетный анализ, чтобы определить, являются ли ваши данные несбалансированными или нет. Например: 1 из 1000 положительных наблюдений - это просто шум, ошибка или прорыв в науке? Никогда не знаешь.
Так что всегда лучше использовать все имеющиеся у вас знания и выбирать свой статус со всей мудростью.
Ладно, а если он действительно неуравновешенный?
Еще раз - посмотрите на свои данные. Иногда можно найти одно или два наблюдения, умноженных в сотни раз. Иногда бывает полезно создать фальшивые одноклассные наблюдения.
Если все данные чистые, следующим шагом будет использование весов классов в модели прогнозирования.
Так что насчет метрик мультикласса?
По моему опыту, ни одна из ваших метрик обычно не используется. Есть две основные причины.
Во-первых: всегда лучше работать с вероятностями, чем с твердым прогнозом (потому что как еще вы могли бы разделить модели с прогнозом 0,9 и 0,6, если они обе дают вам один и тот же класс?)
И во-вторых: гораздо проще сравнивать модели прогнозирования и создавать новые те, которые зависят только от одной хорошей метрики.
По моему опыту, я мог бы порекомендовать logloss или MSE (или просто среднеквадратичную ошибку).
Как исправить предупреждения sklearn?
Просто (как заметил Янцзе) перезапишите
average
параметр одним из следующих значений:'micro'
(вычислить показатели глобально),'macro'
(вычислить показатели для каждой метки) или'weighted'
(так же, как макрос, но с автоматическими весами).Все ваши предупреждения пришли после вызова функций метрик со
average
значением по умолчанию,'binary'
которое не подходит для мультиклассового прогнозирования.Удачи и получайте удовольствие от машинного обучения!
Изменить:
я нашел еще одну рекомендацию респондента переключиться на подходы регрессии (например, SVR), с которой я не могу согласиться. Насколько я помню, нет даже такой вещи, как мультиклассовая регрессия. Да, есть многозначная регрессия, которая сильно отличается, и да, в некоторых случаях возможно переключение между регрессией и классификацией (если классы каким-то образом отсортированы), но это довольно редко.
Что я бы порекомендовал (в рамках scikit-learn), так это попробовать другие очень мощные инструменты классификации: повышение градиента , случайный лес (мой любимый), KNeighbors и многие другие.
После этого вы можете рассчитать среднее арифметическое или геометрическое между прогнозами, и в большинстве случаев вы получите еще лучший результат.
источник