XGBoost中的相同预测

问题描述

过去我使用XGBoost进行回归时,得到了差异化的预测,但是在此数据集上使用XGBClassifier会导致所有情况下的预测值都相同。测试数据的真实值是221个案例为0,49个案例为1。XGBoost似乎正在锁定这种不平衡并预测所有0。我试图弄清楚我可能需要在模型的参数中进行调整以解决此问题。

这是我正在运行的代码

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()时,我的确已设置好;这是输出

{'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。还有一些NaN遇到了麻烦,但是我正在过滤数据以删除NaN

我想知道是否需要其他树方法或弄乱base_score参数?

编辑:根据Dan的评论,我尝试了一些事情:

  1. 我对我的火车/测试分组进行了分层,但没有实质性的变化-219 0和51 1。训练样本具有507 0和120 1,因此它们的分布大致均匀。我认识到这是一个很小的数据集,但是我是一位调查研究人员,所以这就是我所拥有的全部。
  2. 我尝试了逻辑回归,并得出了相同的预测:全为0。代码
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曲线的显示并不多,但是建议查看训练预测是一个很好的建议。逻辑模型具有相同的训练预测:全为0。
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的结果来手动完成此操作,但是有没有办法将其用于估算器呢?

解决方法

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

scale_pos_weight似乎是一个参数,您可以调整以处理此类中的不平衡情况。 Mine设为默认值1,这意味着阴性(0)和阳性(1)情况假设均匀出现。如果我将其更改为4,这是我的负数与正数之比,那么我开始看到预测为1的案例。

我的准确度得分下降了,但这很有意义:您可以通过预测所有人为0来获得此数据的更高%准确度,因为绝大多数情况下均为0,但是我想运行该模型不是为了准确度而是为了有关每个预测变量的重要性/贡献的信息,所以我想要不同的预测。

该链接中的一个答案还建议通过将scale_pos_weight设置为比率的平方倍(在这种情况下为2)来保持保守。我得到的准确度比2高4,这就是我要解决的问题,并且我打算在以后的分类模型中研究此参数。

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...