XGboost python - classifier class 权重选项?

XGboost python - classifier class weight option?

有没有办法为 xgboost classifier 设置不同的 class 权重?例如,在 sklearn RandomForestClassifier 中,这是由 "class_weight" 参数完成的。

使用 sklearn wrapper 时,有一个权重参数。

示例:

import xgboost as xgb
exgb_classifier = xgboost.XGBClassifier()
exgb_classifier.fit(X, y, sample_weight=sample_weights_data)

其中参数应该是数组,长度N,等于目标长度

我最近 运行 遇到了这个问题,所以想到会留下我试过的解决方案

from xgboost import XGBClassifier

# manually handling imbalance. Below is same as computing float(18501)/392318 
on the trainig dataset.
# We are going to inversely assign the weights
weight_ratio = float(len(y_train[y_train == 0]))/float(len(y_train[y_train == 
1]))
w_array = np.array([1]*y_train.shape[0])
w_array[y_train==1] = weight_ratio
w_array[y_train==0] = 1- weight_ratio

xgc = XGBClassifier()
xgc.fit(x_df_i_p_filtered, y_train, sample_weight=w_array)

不确定,但结果非常令人失望。希望这对某人有所帮助。

[引用link]https://www.programcreek.com/python/example/99824/xgboost.XGBClassifier

对于 sklearn 版本 < 0.19

只需为火车数据的每个条目分配 class 权重。首先使用 sklearn 的 class_weight.compute_class_weight 获得 class 权重,然后为训练数据的每一行分配适当的权重。

我在这里假设火车数据的列 class 包含 class 数字。我还假设有 nb_classes 从 1 到 nb_classes

from sklearn.utils import class_weight
classes_weights = list(class_weight.compute_class_weight('balanced',
                                             np.unique(train_df['class']),
                                             train_df['class']))

weights = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
    weights[i] = classes_weights[val-1]

xgb_classifier.fit(X, y, sample_weight=weights)

sklearn 版本更新 >= 0.19

有更简单的解决方案

from sklearn.utils import class_weight
classes_weights = class_weight.compute_sample_weight(
    class_weight='balanced',
    y=train_df['class']
)

xgb_classifier.fit(X, y, sample_weight=classes_weights)

您也可以使用 scale_pos_weight 超参数,如 XGBoost docs 中所述。这种做法的好处是不用构造样本权重向量,也不用在fit时传入样本权重向量。

from sklearn.utils.class_weight import compute_sample_weight
xgb_classifier.fit(X, y, sample_weight=compute_sample_weight("balanced", y))

此处的答案已过时。不再支持 sample_weight 参数。替换为 scale_pos_weight

而只是 scale_pos_weight = sum(negative instances) / sum(positive instances)

类似于@Firas Omrane 和@Pramit 的回答,但我认为它更像 pythonic


    from sklearn.utils import class_weight
    class_weights = dict(
            zip(
                [0,1],
                class_weight.compute_class_weight(
                    'balanced', classes=np.unique(train['class']), y=train['class']
                ),
            )
        ) 
    
    xgb_classifier.fit(X, train['class'], sample_weight=class_weights)