首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XGBoost中的相同预测

XGBoost中的相同预测
EN

Stack Overflow用户
提问于 2020-08-12 17:36:05
回答 1查看 1.3K关注 0票数 1

当我在过去使用XGBoost进行回归时,我得到了不同的预测,但是在这个数据集上使用XGBClassifier会导致所有情况下的预测都具有相同的值。测试数据的真实值是: 221例为0,49例为1。XGBoost似乎正锁定这种不平衡,并预测所有的0。我正在试图找出我可能需要在模型的参数中调整什么来修正这个问题。

下面是我正在运行的代码:

代码语言:javascript
复制
import pyreadstat
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Get data
dfloc = r"C:\Users\me\Desktop\Python practice\GBM_data.sav"
df, meta = pyreadstat.read_sav(dfloc, metadataonly=False)

# Filter data
df = df.dropna(subset=["Q31ar1"])
df = df.query("hgroup2==3")
IVs = ["Q35r1", "Q35r2", "Q35r3", "Q35r4", "Q35r5", "Q35r6", "Q35r7", "Q35r8", "Q35r9", "Q35r10", "Q35r11", "Q35r13", "Q35r14", "Q35r15", "Q35r16"]

# Separate samples
train, test = train_test_split(df, test_size=0.3, random_state=410)

train_features = train[IVs]
train_labels = train["Q31ar1"]
train_weight = train["WeightStack"]

test_features = test[IVs]
test_labels = test["Q31ar1"]
test_weight = test["WeightStack"]

# Set up model & params
model = XGBClassifier(objective = 'binary:logistic',
                     n_estimators = 1000,
                     learning_rate = .005,
                     subsample = .5,
                     max_depth = 4,
                     min_child_weight = 10,
                     tree_method = 'hist',
                     colsample_bytree = .5,
                     random_state = 410)

# Model
model.fit(train_features, train_labels, sample_weight = train_weight)
test_pred = model.predict(test_features)

通过一些相关的问题,似乎有些人遇到了麻烦,他们的模型没有经过足够的推进迭代。我正在运行1000,这已经足够倒退在过去。其他人没有正确设置参数,但是当我运行model.get_params()时,我的参数似乎已经设置好了;下面是输出:

代码语言:javascript
复制
{'base_score': 0.5,
 'booster': 'gbtree',
 'colsample_bylevel': 1,
 'colsample_bynode': 1,
 'colsample_bytree': 0.5,
 'gamma': 0,
 'learning_rate': 0.005,
 'max_delta_step': 0,
 'max_depth': 4,
 'min_child_weight': 10,
 'missing': None,
 'n_estimators': 1000,
 'n_jobs': 1,
 'nthread': None,
 'objective': 'binary:logistic',
 'random_state': 410,
 'reg_alpha': 0,
 'reg_lambda': 1,
 'scale_pos_weight': 1,
 'seed': None,
 'silent': None,
 'subsample': 0.5,
 'verbosity': 1,
 'tree_method': 'hist'}

其他人则对扩大规模存在问题。我的预测器都是按相同的方式缩放的--它们是序数等级,值为1、2、3、4和5。还有一些人对NaNs有困难,但我正在过滤我的数据以删除NaNs。

我想知道我是否需要一个不同的树方法,还是处理base_score参数?

编辑:根据丹的评论,我尝试了几件事:

  1. I将我的训练/测试分组进行了分层,没有发生实质性的变化-2190s和51s,训练样本有5070s和1201s,它们的分布大致相当。我认识到这是一个小数据集,但我是一名调查研究员,所以这就是我所拥有的全部。
  2. ,我尝试过逻辑回归,我得到了相同的预测:所有的0。代码:

代码语言:javascript
复制
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(random_state=0).fit(train_features, train_labels)
test_pred_log = clf.predict(test_features)
accuracy_log = clf.score(test_features, test_labels)

  1. 我看了一看来自XGBoost模型的训练数据的预测,它们也都是0,所以ROC曲线没有显示多少,但是看看训练预测是一个很好的建议。logistic模型具有相同的训练预测: all 0.

代码语言:javascript
复制
train_pred = model.predict(train_features)
fpr, tpr, thresholds = roc_curve(train_labels, train_pred, pos_label=1)

  1. 我不知道我能得到概率估计,所以谢谢你在pred_proba上的提示。我的概率估计是有区别的,所以这太好了!属于1类的概率都很低--平均在20%左右,这是有道理的,因为大约20%的样本确实属于第1类。问题是,我不知道如何调整预测的阈值。我想我可以使用pred_proba的结果手动完成,但是是否有一种方法可以用它来代替估计器呢?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-13 15:34:38

在stats部分找到答案:https://stats.stackexchange.com/questions/243207/what-is-the-proper-usage-of-scale-pos-weight-in-xgboost-for-imbalanced-datasets

scale_pos_weight似乎是一个参数,您可以调整它来处理此类类中的不平衡。我的设置为默认值1,这意味着负(0)和正(1)的情况被假定是均匀地显示。如果我把这个改为4,这是我的负数和正数的比率,我开始看到预测为1的情况。

我的准确度分数下降了,但这是有道理的:通过预测每个人都是0,你可以获得更高的准确率,因为绝大多数情况都是0,但我想运行这个模型不是为了精确,而是为了每个预测器的重要性/贡献的信息,所以我想要不同的预测。

链接中的一个答案还建议通过将scale_pos_weight设置为比例的sqrt (在本例中为2 ),从而更加保守。我得到了更高的精度,比4,所以这就是我要做的,我计划在未来的分类模型中研究这个参数。

对于多类模型,您最好调整用例级别的权重,以使类均匀表示,如下所示:https://datascience.stackexchange.com/questions/16342/unbalanced-multiclass-data-with-xgboost

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63381937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档