XGBoost用于多分类和不平衡数据的处理

14

我正在处理一个包含3个类别[0,1,2]的分类问题,类别分布不平衡,如下所示。

enter image description here

我想使用Python中的XGBClassifier来解决这个分类问题,但是模型不响应class_weight的调整,而是偏向于多数类0,而忽略少数类1,2。除了class_weight以外,还有哪些超参数可以帮助我?

我尝试了以下方法:1)使用sklearn的compute_class_weight计算类别权重;2)根据类别的相对频率设置权重;3)手动调整极端值的类别,例如{0:0.5,1:100,2:200}。但是在任何情况下,都不能帮助分类器考虑到少数类别。

观察:

  • 我可以在二元分类问题中解决这个问题:通过识别类别[1,2],将问题变成二元分类,然后通过调整scale_pos_weight使分类器正常工作(即使在这种情况下,单独使用class_weight也无法帮助)。 但是,据我所知,scale_pos_weight只适用于二元分类。对于多分类问题,是否有类似的参数?

  • 使用RandomForestClassifier替代XGBClassifier,我可以通过设置class_weight='balanced_subsample'和调整max_leaf_nodes来解决问题。但是由于某些原因,这种方法在XGBClassifier上不起作用。

  • 备注:我知道有平衡技术,比如过/欠采样或SMOTE。但是尽可能地避免它们,并优先考虑使用模型的超参数调整来解决问题。

    我的观察结果表明,在二元情况下,这种方法是可行的。


    2
    首先,尝试使用“过采样”和“欠采样”技术平衡数据,然后可以在平衡的数据上使用正常分布进行分类。 - Pooya Chavoshi
    @PooyaChavoshi 感谢您的评论。我应该补充一下,我尽可能避免使用过/欠采样技术和SMOTE等方法。虽然我已经尝试过它们。 - Pooyan Moradifar
    2个回答

    13

    sample_weight参数在使用XGBoost训练数据时,处理不平衡数据非常有用。您可以使用sklearn库中的compute_sample_weight()计算样本权重。

    此代码适用于多类数据:

    from sklearn.utils.class_weight import compute_sample_weight
    sample_weights = compute_sample_weight(
        class_weight='balanced',
        y=train_df['class'] #provide your own target name
    )
    
    xgb_classifier.fit(X, y, sample_weight=sample_weights)
    

    1
    谢谢您的建议。它确实起作用了!我之前忽略的关键点是在拟合时应传递参数 sample_weight - Pooyan Moradifar
    3
    scale_pos_weight和sample_weight有什么区别? - skan

    1

    您可以像@Prakash Dahal建议的那样使用sample_weight,但是要计算自己的权重。我发现不同的权重会产生巨大的差异(我有12个类和非常不平衡的数据)。 如果您计算自己的权重,则需要为每个条目分配相关权重,并以相同的方式将参数传递给分类器: xgb_class.fit(X_train, y_train, sample_weight=weights)


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接