Відповіді:
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)