Ответы:
scale_pos_weight
используется для бинарной классификации, как вы заявили. Это более обобщенное решение для обработки несбалансированных классов. Хороший подход при назначении значения scale_pos_weight
:
sum(negative instances) / sum(positive instances)
Для вашего конкретного случая есть другая опция, позволяющая взвешивать отдельные точки данных и учитывать их веса при работе с бустером, и позволить оптимизации происходить относительно их весов, чтобы каждая точка была представлена одинаково. Вам просто нужно просто использовать:
xgboost.DMatrix(..., weight = *weight array for individual weights*)
Вы можете определять веса по своему усмотрению, и, таким образом, вы можете даже обрабатывать дисбалансы внутри классов, а также дисбалансы между различными классами.
Этот ответ @KeremT правильный. Я приведу пример для тех, у кого все еще есть проблемы с точной реализацией.
weight
параметр в XGBoost для каждого экземпляра не для класса. Поэтому нам нужно присвоить вес каждого класса его экземплярам, что является одним и тем же.
Например, если у нас есть три несбалансированных класса с соотношениями
class A = 10%
class B = 30%
class C = 60%
Их вес будет (деление наименьшего класса на другие)
class A = 1.000
class B = 0.333
class C = 0.167
Затем, если данные обучения
index class
0 A
1 A
2 B
3 C
4 B
мы строим weight
вектор следующим образом:
index class weight
0 A 1.000
1 A 1.000
2 B 0.333
3 C 0.167
4 B 0.333
Все сталкиваются с этим вопросом, когда сталкиваются с проблемой несбалансированной классификации мультиклассов с использованием XGBoost в R. Я тоже!
Я искал пример, чтобы лучше понять, как его применять. Потратил почти час, чтобы найти ссылку, указанную ниже. Для всех тех, кто ищет пример, здесь идет -
Спасибо вакс
Просто присвойте каждому экземпляру ваших данных поезда вес своего класса. Сначала получите вес класса с помощью class_weight.compute_class_weight
sklearn, затем присвойте каждому ряду данных поезда соответствующий вес.
Здесь я предполагаю, что данные поезда имеют столбец «класс», содержащий номер класса. Я также предположил, что существуют nb_classes от 1 до nb_classes.
from sklearn.utils import class_weight
class_weights = list(class_weight.compute_class_weight('balanced',
np.unique(train['class']),
train['class']))
w_array = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
w_array[i] = class_weights[val-1]
xgb_classifier.fit(X, y, sample_weight=w_array)