繁体   English   中英

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

[英]Multiclass classification with xgboost classifier?

我正在尝试使用 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 用于二进制分类,但它对多类工作真的很好吗? 如果两者都正确,我应该使用哪一个?

实际上,即使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_

默认情况下, XGBClassifier 使用objective='binary:logistic' 当您使用此目标时,它会采用以下任一策略: one-vs-rest (也称为 one-vs-all)和one-vs-one 它可能不是您手头问题的正确选择。

当您使用objective='multi:softprob' ,输出是数据点数 * 类数的向量。 因此,代码的时间复杂度会增加。

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

默认情况下,XGBClassifier 或许多分类器使用目标作为二进制,但它内部所做的是分类(一个与其余),即如果你有 3 个类,它会给出结果(0 vs 1&2)。如果你处理超过 2 个类您应该始终使用softmax .Softmax 将 logits 转换为总和为 1 的概率。在此基础上,它预测哪些类具有最高的概率。正如您所看到的,正如Saurabh在他的回答中提到的,复杂性增加了,因此需要更多时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM