使用Scikit-Learn API时如何在XGBoost分类器中调整概率阈值

时间:2019-04-10 16:17:21

标签: python-3.x scikit-learn xgboost

我对使用sklearn API的xgboost分类器有疑问。看来它有一个参数可以告诉您应返回多少概率为True,但我找不到它。

通常,xgb.predict返回布尔值,xgb.predict_proba返回区间[0,1]内的概率。我认为结果是相关的。应该有一个概率阈值来确定样本的类别。

dtrain, dtest = train_test_split(data, test_size=0.1, random_state=22)

param_dict={'base_score': 0.5,
 'booster': 'gbtree',
 'colsample_bylevel': 1,
 'colsample_bytree': 1,
 'gamma': 0,
 'learning_rate': 0.1,
 'max_delta_step': 0,
 'max_depth': 4,
 'min_child_weight': 6,
 'missing': None,
 'n_estimators': 1000,
 'objective': 'binary:logistic',
 'reg_alpha': 0,
 'reg_lambda': 1,
 'scale_pos_weight': 1,
 'subsample': 1}

xgb = XGBClassifier(**param_dict,n_jobs=2)

xgb.fit(dtrain[features], dtrain['target'])

result_boolean = xgb.predict(dtest[features])
print(np.sum(result_boolean))
Output:936

result_proba = xgb.predict_proba(dtest[features])
result_boolean2= (result_proba[:,1] > 0.5) 
print(np.sum(result_boolean2))
Output:936

看起来默认的概率阈值为0.5,因此结果数组的True量相同。但是我找不到在代码中进行调整的地方。 predict(data, output_margin=False, ntree_limit=None, validate_features=True)另外,我已经测试过base_score,但这并没有影响结果。

我想更改概率阈值的主要原因是我想通过XGBClassifier方法以不同的概率阈值测试GridSearchCVxgb.predict_proba似乎无法合并到GridSearchCV中。如何更改XGBClassifier中的概率阈值?

2 个答案:

答案 0 :(得分:1)

我认为您应该查看源代码以了解。我很难找到它,但是我发现它可以在lightgbm中工作,我想xgboost应该也可以工作。

转到此处(https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMClassifier.html#lightgbm.LGBMClassifier.predict)并查看方法“预测”:

def predict(self, X, raw_score=False, num_iteration=None,
            pred_leaf=False, pred_contrib=False, **kwargs):
    """Docstring is inherited from the LGBMModel."""
    result = self.predict_proba(X, raw_score, num_iteration,
                                pred_leaf, pred_contrib, **kwargs)
    if callable(self._objective) or raw_score or pred_leaf or pred_contrib:
        return result
    else:
        class_index = np.argmax(result, axis=1)
        return self._le.inverse_transform(class_index)


predict.__doc__ = LGBMModel.predict.__doc__

实际上,每次将分类器训练为多分类器,并且选择具有较高概率的分类。 Predict_proba的输出是:

predicted_probability(类似数组的形状= [n_samples,n_classes]个)–每个样本的每个类别的预测概率。

您会看到该方法说:

class_index = np.argmax(result, axis=1)

其中“结果”是predict_proba的输出。 现在,如果您有许多类的predict_proba,它们的总和是否为1?我猜是这样,但是我想我们应该进入分类器损失函数以真正了解正在发生的事情...

这就是我接下来要读的内容! http://wiki.fast.ai/index.php/Log_Loss

答案 1 :(得分:0)

当您使用ROC AUC(ROC =接收器工作特性,AUC =曲线下面积)作为评分功能时,将使用predict_proba()进行网格搜索。选择的分类器超参数将是在所有可能的决策阈值范围内具有最佳整体性能的分类器。

GridSearchCV(scoring='roc_auc', ....)

然后,您可以绘制ROC曲线,以确定决定阈值,该阈值可为您提供所需的精确度与召回率/真阳性与假阴性之间的平衡。

enter image description here

scikit-learn documentation on ROC中的更多信息