Несбалансированные мультиклассовые данные с XGBoost

20

У меня есть 3 класса с этим распределением:

Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163

И я использую xgboostдля классификации. Я знаю, что есть параметр с именем scale_pos_weight.

Но как это обрабатывается для случая «мультикласса», и как я могу правильно установить его?

shda
источник

Ответы:

18

scale_pos_weightиспользуется для бинарной классификации, как вы заявили. Это более обобщенное решение для обработки несбалансированных классов. Хороший подход при назначении значения scale_pos_weight:

sum(negative instances) / sum(positive instances)

Для вашего конкретного случая есть другая опция, позволяющая взвешивать отдельные точки данных и учитывать их веса при работе с бустером, и позволить оптимизации происходить относительно их весов, чтобы каждая точка была представлена ​​одинаково. Вам просто нужно просто использовать:

xgboost.DMatrix(..., weight = *weight array for individual weights*)

Вы можете определять веса по своему усмотрению, и, таким образом, вы можете даже обрабатывать дисбалансы внутри классов, а также дисбалансы между различными классами.

Керем Т
источник
> Хороший подход при назначении значения scale_pos_weight: sum (отрицательные экземпляры) / sum (положительные экземпляры)
lcrmorin
1
Я вижу этот совет повсюду, и имеет смысл присвоить больший вес менее представленному классу. Однако мне трудно найти источник, обсуждающий это точное значение. Я получаю интуицию за этим конкретным значением (сделайте выборку сбалансированной), но я подозреваю, что где-то есть компромиссное отклонение, которое заставит вас задуматься о снижении веса.
lcrmorin
7

Этот ответ @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
Esmailian
источник
5

Все сталкиваются с этим вопросом, когда сталкиваются с проблемой несбалансированной классификации мультиклассов с использованием XGBoost в R. Я тоже!

Я искал пример, чтобы лучше понять, как его применять. Потратил почти час, чтобы найти ссылку, указанную ниже. Для всех тех, кто ищет пример, здесь идет -

/datascience//a/9493/37156

Спасибо вакс

Krithi07
источник
0

Просто присвойте каждому экземпляру ваших данных поезда вес своего класса. Сначала получите вес класса с помощью class_weight.compute_class_weightsklearn, затем присвойте каждому ряду данных поезда соответствующий вес.

Здесь я предполагаю, что данные поезда имеют столбец «класс», содержащий номер класса. Я также предположил, что существуют 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)
Firas Omrane
источник