Незбалансовані багатокласові дані з XGBoost


20

У мене є 3 класи з цим розподілом:

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

І я використовую xgboostдля класифікації. Я знаю, що є параметр, який називається scale_pos_weight.

Але як це обробляється для "багатокласового" випадку і як я можу його правильно встановити?

Відповіді:


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

5

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

Я шукав приклад, щоб краще зрозуміти, як його застосувати. Інвестували майже годину, щоб знайти посилання, згадане нижче. Для всіх, хто шукає приклад, ось:

/datascience//a/9493/37156

Спасибі воскові


1

Просто призначте кожен екземпляр даних вагона з його вагою класу. Спочатку отримайте ваги класу з 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.