[踩坑记] xgboost预测概率雷同问题分析与解决

关键词:模型预测概率结果总是一样,xgboost predict_proba

1. 问题描述

同事使用xgboot建立分类模型,使用pandas.DataFrame存储数据特征,在推断阶段,传入不同的样本数据,预测的proba结果总是一样,简要代码描述如下:

# 加载模型并使用
model = xgb.XGBClassifier()
model.load_model("models/xgb.model")

# datas为DataFrame格式,待预测数据
res_01 = model.predict_proba(datas.iloc[[0]])
print(res_01)
res_02 = model.predict_proba(datas.iloc[[1]])
print(res_02)

# 输出结果完全一样
[[0.30088782 0.6991122 ]]
[[0.30088782 0.6991122 ]]

2. 分析过程

  1. 验证输入数据是否相同,查看后datas.iloc[[0]]datas.iloc[[1]]并不相同,进一步以datas.iloc[[0]]input_01,datas.iloc[[0]]中的部分字段手动赋值为0,做为input_02, proba结果依然相同;
  2. 是否环境异常,重新conda新的环境后,问题依然存在;
  3. 是否训练与预测的特征顺序不一致,验证过程如下:
# 预测测试集并计算准确率
old_row = copy.deepcopy(X_test.iloc[[0]])
# 打乱特征列,模拟预测特征与训练特征顺序不一致的情况!
new_row = X_test.iloc[[0]].sample(frac=1, axis=1)
y_pred = loaded_model.predict_proba(new_row)
print(y_pred)
# 手动修改输入的特征值,预期proba结果发生变化
new_row.iat[0,0] = 0
new_row.iat[0,1] = 0
y_pred = loaded_model.predict_proba(new_row)
print(y_pred)    ## 实际结果没有发生变化!!

# old_row为与训练特征保持一致的情况
y_pred = loaded_model.predict_proba(old_row)
print(y_pred)

# 手动修改输入的特征值,预期proba结果发生变化
old_row.iat[0,0] = 0
old_row.iat[0,1] = 0
y_pred = loaded_model.predict_proba(old_row)
print(y_pred)  ## 实际结果发生了变化!!

上述代码当调整输入特征顺序后,并修改特征值,proba结果无变化,问题复现!

3. 解决方法

  • 保持预测数据特征与训练数据特征的一致性,复用同一套特征计算代码

  • 或以字典格式保存特征,按字典key进行排序输出特征顺序

  • 树模型可能存在输入特征不同但输出预测概率相同的情况,可通过调整模型参数,增大模型的拟合能力,使不同的输入特征得到有差异的预测概率,在xbg中主要的调节参数有:

    • max_depth:树的最大深度,正整数,默认值为6;
    • learning_rate:学习率,通常设置为0.01到0.2之间的小数,默认值为0.3;
    • n_estimators:使用的弱分类器的数量,正整数,默认值为100;
    • subsample:随机选择训练数据的比例,可以设置为0到1之间的小数,通常设置为0.5到1之间的值,默认为1;
    • colsample_bytree:随机选择特征的比例,可以设置为0到1之间的小数,通常设置为0.5到1之间的值,默认为1;

    Example:

    xgb_model = xgb.XGBClassifier(
    max_depth=6, 
    learning_rate=0.07, 
    n_estimators=100, 
    subsample=0.8, 
    colsample_bytree=0.8)
    

---------------- END ----------------

猜你喜欢

转载自blog.csdn.net/iling5/article/details/130421902