如何确定并可视化代表性的XGBoost决策树?

4
dtreeviz有一种简单而直观的方法来可视化决策树。当我们使用XGBoost模型进行训练时,通常会创建许多决策树。而测试数据的预测将涉及将所有树的值累加以推导出测试目标值。那么,我们如何可视化这些树中的代表性树?
在尝试回答这个问题时,我使用了sklearn加利福尼亚房屋数据,并使用XGBoost进行了训练。以下是代码:
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
import xgboost as xgb

housing = fetch_california_housing()
X_train, X_valid, y_train, y_valid = train_test_split(housing.data, housing.target, 
                                                   test_size = 0.33, random_state = 11)
dtrain = xgb.DMatrix(data=X_train, label=y_train)
dvalid= xgb.DMatrix(data=X_valid, label=y_valid)

# specify xgboost parameters and train the model
params_reg = {"max_depth":4, "eta":0.3, "objective":"reg:squarederror", "subsample":1}
xgb_model_reg = xgb.train(params=params_reg, dtrain=dtrain, num_boost_round=1000, \
      early_stopping_rounds=50, evals=[(dtrain, "train"),(dvalid, "valid")], verbose_eval=True)

我使用了early_stopping_rounds,它在以下迭代中停止:
[0] train-rmse:1.46031  valid-rmse:1.47189
[1] train-rmse:1.14333  valid-rmse:1.15873
[2] train-rmse:0.93840  valid-rmse:0.95947
[3] train-rmse:0.80224  valid-rmse:0.82699
...
[308]   train-rmse:0.28237  valid-rmse:0.47431
[309]   train-rmse:0.28231  valid-rmse:0.47429

"xgb_model_reg.best_iteration 是260。

使用这棵最佳树,我绘制了以下的dtreeviz树:"

from dtreeviz import trees
from dtreeviz.models.xgb_decision_tree import ShadowXGBDTree

best_tree = xgb_model_reg.best_iteration
xgb_shadow_reg = ShadowXGBDTree(xgb_model_reg, best_tree, housing.data, housing.target, \
                                housing.feature_names, housing.target_names)
trees.dtreeviz(xgb_shadow_reg)

我们得到了这个图像: XGBoost best_iteration tree 如果我使用这个`ShadowXGBDTree`来绘制验证行的预测路径,它返回的值与模型预测的值不同。为了说明,我随机选择了`X_valid[50]`并绘制了其预测路径,如下所示:
# predict
y_pred = xgb_model_reg.predict(dvalid)
# select a sample row and visualize path
X_sample = X_valid[50]
viz = trees.dtreeviz(xgb_shadow_reg,
                    X_valid, 
                    y_valid, 
                    target_name='MedHouseVal', 
                    orientation ='LR',  # left-right orientation
                    feature_names=housing.feature_names,
                    class_names=list(housing.target_names),
                    X=X_sample)            
viz

预测的目标值为2.13,如下所示: Decision Tree prediction path 然而,y_valid[50]的值为1.741,甚至y_pred[50]的值为1.5196749,两者都与图中显示的值不匹配。我猜这是可以预料的,因为我只是使用这个特定的树来进行路径预测。那么我应该如何选择代表性的树呢?
有什么想法可以解决这个问题吗?谢谢。

我在这里做了同样的问题:如何获得最终的树模型? 如果您找到答案,请告诉我! - Chris
有没有进展?我唯一能想到的是功能顺序混乱或被交换了。 - Kevin
@Chris/Kevin,我决定选择一条不同的道路来帮助解释模型预测。 - Heelara
2个回答

3
在探索这个问题数月后,我决定回答采取的方向,因为其他人似乎面临着类似的情况。我提出这个问题的主要目标是找出一种解释XGBoost模型预测的方法。然而,由于XGBoost在理论上的定义方式,获得一个代表性决策树似乎是不可行的。因此,我决定执行SHAP分析来解释其预测。
在继续问题中给出的代码时,以下是执行SHAP分析的要点:
import shap

# Create a tree explainer
xgb_explainer = shap.TreeExplainer(
    xgb_model_reg, X_train, feature_names=list(housing.feature_names)
)
data_dmatrix = xgb.DMatrix(data=X_valid,label=y_valid)
y_pred = xgb_model_reg.predict(data_dmatrix)

shap_explainer_values = xgb_explainer(X_valid, y_pred)

举个例子,如果我们想解释为什么y_pred[50]的值是1.5196749,我们可以用以下代码生成一个瀑布图来说明:
shap.waterfall_plot(shap_explainer_values[50])

这是生成的瀑布图:

enter image description here

从这个图中可以看出,经度和纬度对这个预测有着相反的最大影响。房屋的纬度相对于基准值E[f(x)]增加了2,然而经度却使数值下降了-2.19。这样的表达方式很容易帮助解释模型的预测结果。

0
在 "dtreeviz" 库中,方法是在 XGBOOST 模型的树集合中识别最重要的决策树。他们希望你提供最关键的树(一个单独的决策树),在我们上面的例子中被定义为 "best_tree" 变量。因此,虽然这种可视化方法并不是最糟糕的,但我们必须记住,还有其他数百棵树影响着我们的决策。
Shapley 值是解释机器学习模型中输入对影响的最常见方法之一,无论是针对特定样本还是整个数据集。然而,它是一个通用模型,这意味着它不仅适用于决策树模型。它提供了一种更强大的方式来理解复杂模型中每个数据点的贡献,但它只给我们一个大致的概述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接