当我在过去使用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。还有一些人对NaNs有困难,但我正在过滤我的数据以删除NaNs。
我想知道我是否需要一个不同的树方法,还是处理base_score参数?
编辑:根据丹的评论,我尝试了几件事:
。
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)。
train_pred = model.predict(train_features)
fpr, tpr, thresholds = roc_curve(train_labels, train_pred, pos_label=1)pred_proba上的提示。我的概率估计是有区别的,所以这太好了!属于1类的概率都很低--平均在20%左右,这是有道理的,因为大约20%的样本确实属于第1类。问题是,我不知道如何调整预测的阈值。我想我可以使用pred_proba的结果手动完成,但是是否有一种方法可以用它来代替估计器呢?发布于 2020-08-13 15:34:38
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
https://stackoverflow.com/questions/63381937
复制相似问题