如何在不重训的情况下基于XGBoost最佳迭代次数计算特征重要性?
问题
使用带早停(early stopping)的XGBRegressor训练回归模型后,发现model.feature_importances_是基于所有迭代历史(包括early_stopping_rounds指定的“耐心”迭代)计算的特征重要性,但实际需要仅基于**最佳迭代次数(best_iteration)**的特征重要性。由于重训会使运行时间近乎翻倍,无法通过重新设置n_estimators=best_iteration训练新模型,且.feature_importances_没有iteration_range参数,请问有无无需重训的实现方法?
示例代码:
from xgboost import XGBRegressor from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split # 准备数据 X, y = make_regression(n_samples=1000, n_features=20, noise=0.1) X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42) # 带早停训练模型 xgb_model = XGBRegressor(n_estimators=1000, early_stopping_rounds=100, eval_metric="rmse") xgb_model.fit(X_train, y_train, eval_set=[(X_val, y_val)], verbose=False) # 当前得到的是全迭代历史的特征重要性 xgb_model.feature_importances_
其中best_iteration = xgb_model.best_iteration
无需重训的实现方法
可以借助XGBoost原生的Booster对象实现需求:sklearn接口的XGBRegressor可通过get_booster()获取原生Booster,而Booster的get_score()方法支持指定iteration_range参数,限定计算特征重要性的迭代范围。
具体实现代码:
import numpy as np # 获取最佳迭代次数 best_iter = xgb_model.best_iteration # 获取原生Booster对象 booster = xgb_model.get_booster() # 计算仅基于最佳迭代的特征重要性(默认weight类型,和feature_importances_逻辑一致) importance_dict = booster.get_score(iteration_range=(0, best_iter + 1)) # 转换为和feature_importances_一致的数组格式(按特征顺序排列) feature_importances_best_iter = np.zeros(xgb_model.n_features_in_) for feat_name, importance in importance_dict.items(): # 特征名格式为f0、f1...,提取索引 feat_idx = int(feat_name[1:]) feature_importances_best_iter[feat_idx] = importance # 归一化对齐feature_importances_的输出格式(总和为1) feature_importances_best_iter /= feature_importances_best_iter.sum() print(feature_importances_best_iter)
补充说明
get_score()默认计算的是weight类型的特征重要性,和feature_importances_逻辑完全一致:统计特征在所有树中被用作分裂节点的次数- 若需要其他类型的重要性(如gain、cover),可在
get_score()中指定importance_type参数,例如importance_type='gain' - 最后一步的归一化是为了和
feature_importances_的输出格式对齐
内容的提问来源于stack exchange,提问作者Sunyz
相关产品推荐
相关产品推荐

