Вопрос или проблема
Я хочу использовать LighgbmClassifier для бинарной классификации. Для настройки гиперпараметров я хочу использовать Hyperopt. Набор данных несбалансирован. Использование Sklearns class_weight.compute_class_weight, как показано ниже
clas_wts_arr = class_weight.compute_class_weight('balanced',np.unique(y_trn),y_trn)
self.scale_pos_wt = clas_wts_arr[0] / clas_wts_arr[1]
Следующее – это параметры пространства, которые я передаю в целевую функцию
space = {'objective' : hp.choice('objective', objective_list),
'boosting' : hp.choice('boosting', boosting_list),
'metric' : hp.choice('metric', metric_list),
"max_depth": hp.quniform("max_depth", 1, 15,2),
'min_data_in_leaf': hp.quniform('min_data_in_leaf', 1, 256, 1),
'num_leaves': hp.quniform('num_leaves', 7, 150, 1),
'feature_fraction' : hp.quniform('feature_fraction', 0.5, 1, 0.01),
'min_gain_to_split' : hp.quniform('min_gain_to_split', 0.1, 5, 0.01),
'lambda_l1' : hp.uniform('lambda_l1', 0, 5),
'lambda_l2' : hp.uniform('lambda_l2', 0, 5),
'feature_pre_filter': False}
Мой вопрос: будет ли следующая установка scale_pos_weight корректной в словаре space
#установить scale pos weight явно
space['scale_pos_weight'] = self.scale_pos_wt
Если это неправильно, то какой будет правильный способ установки scale_pos_weight во время выполнения в словаре space, который передается в целевую функцию, которая в свою очередь передается в fmin Hyperopt.
Спасибо за вашу помощь и ответы.
Используйте Sklearns class_weight.compute_class_weight, что вернет массив весов.
Моя проблема здесь бинарная, следовательно, в массиве было два элемента. Нам нужно увеличить вес меньшинства. Целевая переменная 1 была моим классом меньшинства, поэтому я установил максимальный scale_pos_weight равным значению из второго элемента в массиве.
clas_wts_arr = class_weight.compute_class_weight('balanced',np.unique(y_trn),y_trn)
self.scale_pos_wt = clas_wts_arr[1]
В рамках словаря space, который передается в целевую функцию, определенную в fmin, мы включаем scale_pos_weight как показано ниже
'scale_pos_weight' :hp.choice('scale_pos_weight',scl_ps_wt)
если fmin объект был определен следующим образом
best = fmin(fn=objective,
space=space,
algo=tpe.suggest,
max_evals=self.NUM_EVALS,
trials=trials)
Best будет содержать индекс наилучшего значения в массиве. Используя этот индекс, мы получаем фактическое значение scale_pos_weight. Мы используем это значение для установки scale_pos_weight в best.
best['scale_pos_weight'] = scl_ps_wt[best['scale_pos_weight']]
Теперь можно использовать best в качестве параметра для вашего классификатора.
Ответ или решение
Вопрос о том, как правильно задать параметр scale_pos_weight
во время выполнения в Hyperopt при использовании LightGBM для решения задачи бинарной классификации с несбалансированным набором данных, требует внимательного подхода. Ниже приведён пошаговый разбор, как оптимально справиться с этой задачей.
Определение веса класса
Использование функции class_weight.compute_class_weight
из библиотеки Scikit-learn позволяет определить вес класса для несбалансированного набора данных. Параметр scale_pos_weight
используется в LightGBM для того, чтобы сбалансировать важность различных классов в процессе обучения. Для бинарной классификации вы можете вычислить вес описанным ниже способом:
clas_wts_arr = class_weight.compute_class_weight('balanced', np.unique(y_trn), y_trn)
self.scale_pos_wt = clas_wts_arr[1]
Здесь принимается, что целевой переменной 1 является миноритарным классом, что соответствует вашему контексту.
Определение пространства гиперпараметров для Hyperopt
Для корректной настройки scale_pos_weight
в объекте space используйте следующий подход:
space = {
'objective': hp.choice('objective', objective_list),
'boosting': hp.choice('boosting', boosting_list),
'metric': hp.choice('metric', metric_list),
"max_depth": hp.quniform("max_depth", 1, 15, 2),
'min_data_in_leaf': hp.quniform('min_data_in_leaf', 1, 256, 1),
'num_leaves': hp.quniform('num_leaves', 7, 150, 1),
'feature_fraction': hp.quniform('feature_fraction', 0.5, 1, 0.01),
'min_gain_to_split': hp.quniform('min_gain_to_split', 0.1, 5, 0.01),
'lambda_l1': hp.uniform('lambda_l1', 0, 5),
'lambda_l2': hp.uniform('lambda_l2', 0, 5),
'feature_pre_filter': False,
'scale_pos_weight': hp.choice('scale_pos_weight', [self.scale_pos_wt])
}
Оптимизация с использованием метода fmin
Для реализации оптимизации с Hyperopt, параметр scale_pos_weight
наилучшим образом определяется через функцию fmin
. Ваш код будет выглядеть следующим образом:
best = fmin(
fn=objective,
space=space,
algo=tpe.suggest,
max_evals=self.NUM_EVALS,
trials=trials
)
Функция fmin
вернёт индекс оптимального значения из массива, который вы можете преобразовать обратно в значение параметра scale_pos_weight
:
best['scale_pos_weight'] = [self.scale_pos_wt][best['scale_pos_weight']]
Заключение
Теперь, интегрируя это значение с остальными параметрами, вы можете уверенно использовать наилучшие параметры для обучения вашего классификатора LightGBM. Такой подход обеспечивает адаптивность к характеристикам данных и их дисбалансу, особенно критичным в задачах бинарной классификации.
Используйте приведённые шаги для достижения качественных результатов, сохраняя структурированный и методичный подход к настройке гиперпараметров вашей модели машинного обучения.