Как указать значение scale_pos_weight во время выполнения в Hyperopt?

Вопрос или проблема

Я хочу использовать 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. Такой подход обеспечивает адаптивность к характеристикам данных и их дисбалансу, особенно критичным в задачах бинарной классификации.

Используйте приведённые шаги для достижения качественных результатов, сохраняя структурированный и методичный подход к настройке гиперпараметров вашей модели машинного обучения.

Оцените материал
Добавить комментарий

Капча загружается...