Я работаю с несбалансированной классификационной проблемой, в которой целевая переменная содержит:
np.bincount(y_train)
array([151953, 13273])
т.е. 151953
нули и 13273
единицы.
Для решения этой проблемы Я использую параметр XGBoost
weight
при определении DMatrix:
dtrain = xgb.DMatrix(data=X_train,
label=y_train,
weight=weights)
Для весов, которые я использовал:
bc = np.bincount(y_train)
n_samples = bc.sum()
n_classes = len(bc)
weights = n_samples / (n_classes * bc)
w = weights[y_train.values]
Где weights
array([0.54367469, 6.22413923])
, и с последней строкой кода я просто индексирую ее, используя двоичные значения в y_train
. Это похоже на правильный подход к определению весов, поскольку он представляет фактическое соотношение между количеством значений одного класса по сравнению с другим. Однако это, кажется, благоприятствует классу меньшинства, что можно увидеть, проверив матрицу путаницы:
array([[18881, 19195],
[ 657, 2574]])
Так что, просто попробовав различные значения веса, я понял, что с довольно близким отношением веса, в частности array([1, 7])
, результаты кажутся гораздо более разумными:
array([[23020, 15056],
[ 837, 2394]])
Поэтому мой вопрос:
- Почему использование фактических весов каждого класса дает плохие показатели?
- Как правильно установить вес для несбалансированной задачи?