使用xgboost分类器进行多类分类?

时间:2019-09-18 06:23:13

标签: python machine-learning scikit-learn xgboost

我正在尝试使用xgboost进行多类分类,并且已经使用此代码构建了它,

clf = xgb.XGBClassifier(max_depth=7, n_estimators=1000)

clf.fit(byte_train, y_train)
train1 = clf.predict_proba(train_data)
test1 = clf.predict_proba(test_data)

这给了我一些不错的结果。我的案例的对数损失低于0.7。但是在浏览了几页之后,我发现我们必须在XGBClassifier中使用另一个目标来解决多类问题。这是从这些页面推荐的内容。

clf = xgb.XGBClassifier(max_depth=5, objective='multi:softprob', n_estimators=1000, 
                        num_classes=9)

clf.fit(byte_train, y_train)  
train1 = clf.predict_proba(train_data)
test1 = clf.predict_proba(test_data)

此代码也可以正常工作,但是与我的第一个代码相比,要花很多时间才能完成。

为什么我的第一个代码也适用于多类情况?我已经检查过它的默认目标是binary:logistic用于二进制分类,但是对于多类来说真的很好用吗?如果两者都正确,我应该使用哪一个?

3 个答案:

答案 0 :(得分:11)

实际上,即使XGBClassifier的默认obj参数为binary:logistic,它也会在内部判断标签y的类数。当类号大于2时,它将obj参数修改为multi:softmax

https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/sklearn.py

class XGBClassifier(XGBModel, XGBClassifierBase):
    # pylint: disable=missing-docstring,invalid-name,too-many-instance-attributes
    def __init__(self, objective="binary:logistic", **kwargs):
        super().__init__(objective=objective, **kwargs)

    def fit(self, X, y, sample_weight=None, base_margin=None,
            eval_set=None, eval_metric=None,
            early_stopping_rounds=None, verbose=True, xgb_model=None,
            sample_weight_eval_set=None, callbacks=None):
        # pylint: disable = attribute-defined-outside-init,arguments-differ

        evals_result = {}
        self.classes_ = np.unique(y)
        self.n_classes_ = len(self.classes_)

        xgb_options = self.get_xgb_params()

        if callable(self.objective):
            obj = _objective_decorator(self.objective)
            # Use default value. Is it really not used ?
            xgb_options["objective"] = "binary:logistic"
        else:
            obj = None

        if self.n_classes_ > 2:
            # Switch to using a multiclass objective in the underlying
            # XGB instance
            xgb_options['objective'] = 'multi:softprob'
            xgb_options['num_class'] = self.n_classes_

答案 1 :(得分:1)

默认情况下,XGBClassifier使用objective='binary:logistic'。使用此目标时,它采用以下两种策略之一:one-vs-rest(也称为“一对多”)和one-vs-one。对于您遇到的问题,这可能不是正确的选择。

使用objective='multi:softprob'时,输出是数据点数量*类数的向量。结果,代码的时间复杂度增加了。

尝试在代码中设置objective=multi:softmax。更适合多类分类任务。

答案 2 :(得分:1)

默认情况下,XGBClassifier或许多Classifier将目标用作 binary ,但它在内部所做的是对目标进行分类(一个vs其余),即,如果您有3个类,它将得出结果(0 vs 1&2)。如果要处理2个以上的类,则应始终使用 softmax 。Softmax将logits转换为概率之和,该概率总计为1。在此基础上,它可以预测哪些类别具有最高的概率。如您所见, Saurabh 在他的回答中提到了复杂性的增加,因此将花费更多时间。