У меня много проблем с пониманием того, как работает class_weight
параметр в логистической регрессии scikit-learn.
Ситуация
Я хочу использовать логистическую регрессию для двоичной классификации очень несбалансированного набора данных. Классы помечены 0 (отрицательный) и 1 (положительный), а наблюдаемые данные находятся в соотношении примерно 19: 1, причем большинство образцов имеют отрицательный результат.
Первая попытка: подготовка данных обучения вручную
Я разделил данные, которые у меня были, на отдельные наборы для обучения и тестирования (примерно 80/20). Затем я произвольно произвел выборку обучающих данных вручную, чтобы получить обучающие данные в пропорциях, отличных от 19: 1; от 2: 1 до 16: 1.
Затем я обучил логистическую регрессию на этих различных подмножествах обучающих данных и построил график отзыва (= TP / (TP + FN)) в зависимости от различных пропорций обучения. Конечно, отзыв был рассчитан на непересекающихся образцах TEST, которые имели наблюдаемые пропорции 19: 1. Обратите внимание: хотя я обучал разные модели на разных обучающих данных, я вычислил отзыв для всех из них на одних и тех же (непересекающихся) тестовых данных.
Результаты были такими, как ожидалось: отзыв составил около 60% при тренировочных пропорциях 2: 1 и довольно быстро упал к тому времени, когда он достиг 16: 1. Было несколько соотношений 2: 1 -> 6: 1, где отзыв был прилично выше 5%.
Вторая попытка: поиск по сетке
Затем я хотел протестировать различные параметры регуляризации, поэтому я использовал GridSearchCV и сделал сетку из нескольких значений C
параметра, а также class_weight
параметра. Чтобы перевести мои пропорции n: m отрицательных: положительных обучающих выборок на язык словарей, class_weight
я думал, что просто указываю несколько словарей следующим образом:
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
и я также включил None
и auto
.
На этот раз результаты были совершенно потрясающими. Все мои отзывы были крошечными (<0,05) для всех значений, class_weight
кроме auto
. Так что я могу только предположить, что мое понимание того, как установить class_weight
словарь, неверно. Интересно, что class_weight
значение «авто» при поиске по сетке составляло около 59% для всех значений C
, и я предположил, что оно уравновешивается 1: 1?
Мои вопросы
Как правильно использовать данные
class_weight
для тренировки, чтобы добиться баланса, отличного от того, что вы им фактически даете? В частности, в какой словарь мне перейти, чтобыclass_weight
использовать n: m пропорций отрицательных: положительных обучающих выборок?Если вы передадите различные
class_weight
словари в GridSearchCV, во время перекрестной проверки будет ли он перебалансировать данные обучающей свертки в соответствии со словарем, но будет ли использовать истинные заданные пропорции выборки для вычисления моей функции скоринга в тестовой свертке? Это очень важно, поскольку любая метрика полезна для меня только в том случае, если она исходит из данных в наблюдаемых пропорциях.Какое
auto
значение имеет значениеclass_weight
пропорций? Я читал документацию и полагаю, что «балансирует данные обратно пропорционально их частоте» просто означает, что получается 1: 1. Это верно? Если нет, может кто уточнить?
источник
Ответы:
Во-первых, может быть нехорошо просто исходить из одного отзыва. Вы можете просто добиться 100% отзыва, классифицируя все как положительный. Обычно я предлагаю использовать AUC для выбора параметров, а затем найти порог для рабочей точки (скажем, заданного уровня точности), который вас интересует.
Как
class_weight
работает: он наказывает ошибки в образцахclass[i]
с помощьюclass_weight[i]
вместо 1. Таким образом, более высокий вес класса означает, что вы хотите уделять больше внимания классу. Из того, что вы говорите, кажется, что класс 0 в 19 раз чаще, чем класс 1. Поэтому вам следует увеличитьclass_weight
класс 1 по сравнению с классом 0, скажем {0: .1, 1: .9}. Еслиclass_weight
сумма не равна 1, это в основном изменит параметр регуляризации.Чтобы узнать
class_weight="auto"
, как работает, вы можете посмотреть это обсуждение . В версии для разработчиков вы можете использоватьclass_weight="balanced"
, что легче понять: это в основном означает репликацию меньшего класса, пока у вас не будет столько же образцов, сколько в более крупном, но неявным образом.источник
Первый ответ хорош для понимания того, как это работает. Но я хотел понять, как мне следует использовать это на практике.
РЕЗЮМЕ
class_weight="balanced"
работает достойно, если вы не хотите оптимизировать вручнуюclass_weight="balanced"
вами захватить больше истинные события (выше ИСТИНА вспоминания) , но и вы, скорее всего , чтобы получить ложные сигналы (понизить ИСТИНУ точности)NB
Результат может отличаться при использовании RF или GBM. sklearn не поддерживает
class_weight="balanced"
GBM, но lightgbm имеетLGBMClassifier(is_unbalance=False)
КОД
источник