XGBoost训练验证AUC接近1 同数据推理AUC仅0.5问题排查
问题排查与修复
1. AUC计算逻辑错误
roc_auc_score接收的输入是模型输出的原始概率值,而非经阈值二值化后的0/1结果。ROC AUC的计算依赖样本预测概率的排序信息,将连续概率转为离散分类结果后,排序信息完全丢失,自然会得到接近0.5的无效得分。
修正方式:直接传入模型预测的原始概率计算AUC:
# 错误写法 # predictions_binary = np.where(holdout_preds > .5, 1, 0) # print(round(roc_auc_score(holdout['target'], predictions_binary) ,4)) # 正确写法 print(round(roc_auc_score(holdout['target'], holdout_preds) ,4))
2. TF-IDF对象保存不完整,推理阶段IDF权重被重新计算
训练阶段仅保存了TF-IDF的词典,没有保存拟合后的IDF权重等参数。推理阶段新建TfidfVectorizer对象时,哪怕指定了旧词典,调用fit_transform时会基于当前输入数据重新计算IDF,生成的TF-IDF特征值和训练阶段的分布完全不一致,模型无法识别特征。
修正方式:训练阶段直接保存整个TF-IDF对象,而非仅保存词典:
# 训练阶段保存逻辑修改 # 错误写法:pickle.dump(tfidf.vocabulary_,open("tfidf_features.pkl","wb")) # 正确写法:保存整个拟合后的tfidf对象 pickle.dump(tfidf,open("tfidf_model.pkl","wb"))
3. 推理阶段TF-IDF错误调用fit_transform
推理阶段不需要对TF-IDF做拟合,直接调用transform处理输入文本即可:
# 推理阶段test_newdata函数修正 def test_newdata(data): # 加载完整的已拟合TF-IDF对象 tfidf = pickle.load(open("tfidf_model.pkl", 'rb')) # 直接用transform,不要fit encoded_body = tfidf.transform(data['body']).toarray() new_cols = tfidf.get_feature_names_out().tolist() new_cols.append('day_of_year') day_of_year = np.array(data['day_of_year']).reshape(-1, 1) formatted_test_data = np.append(encoded_body, day_of_year, axis=1) df= pd.DataFrame(formatted_test_data, columns=new_cols) return xgb.DMatrix(df)
额外注意点
训练完成后需要显式调用best_model.save_model("earn_modelv3.model")完成模型持久化,避免加载的是未训练的空模型。
内容的提问来源于stack exchange,提问作者NickS
相关产品推荐
相关产品推荐

