sklearn中随机森林单棵决策树绘图样本数异常问题
问题:RandomForest启用Bootstrap后决策树根节点样本数异常
我在sklearn中绘制决策树时遇到了异常情况:原本希望对比含单个估计器、分别启用和不启用Bootstrapping的Random Forest模型,使用样本量n=5的玩具数据集,代码如下:
tree_model = RandomForestRegressor( n_estimators=1, max_features=2, max_depth=None, min_samples_split=2, min_samples_leaf=1, random_state=42, bootstrap=True # (or False) ) tree_model.fit(X_train, y_train) single_tree = tree_model.estimators_[0] fig = plt.figure(figsize=(14, 14), facecolor="white", dpi=300) ax = fig.add_subplot(111) plot_tree(single_tree, feature_names=["X1", "X2"], filled=True, impurity=False, rounded=False, ax=ax)
不启用Bootstrapping时,绘图显示根节点样本数为5,符合预期;但启用Bootstrapping时,根节点样本数变为4。我对此感到困惑:无论是否使用Bootstrapping,训练集都是5个样本,根节点样本数应该始终为5才对,这是怎么回事?
原因分析与解释
这是两个机制共同作用的结果:
- Bootstrap抽样的特性:Bootstrap是有放回抽样,当样本量n=5时,抽样过程中可能出现部分样本被重复抽取、部分样本完全未被抽到的情况。你的代码中
random_state=42固定了抽样结果,恰好有1个原样本未被选中,另外4个样本中有1个被重复抽取了一次,最终生成的Bootstrap样本集总大小仍是5(与原训练集一致)。 - plot_tree的样本数统计逻辑:
plot_tree默认显示的是节点内的独特样本数量(对应决策树的tree_.n_node_samples属性),而非考虑重复抽样后的总样本数。总样本数可以通过tree_.weighted_n_node_samples属性查看,这个值才是5,符合你对训练集大小的预期。
验证方法
你可以通过以下代码查看两个关键数值:
# 打印根节点的独特样本数和加权总样本数 print("根节点独特样本数:", single_tree.tree_.n_node_samples[0]) print("根节点加权总样本数:", single_tree.tree_.weighted_n_node_samples[0])
运行后会发现,加权总样本数确实是5,和原训练集大小一致。
如何显示总样本数
如果希望在决策树图中显示总样本数,可以自定义节点文本,修改plot_tree的参数,例如:
plot_tree( single_tree, feature_names=["X1", "X2"], filled=True, impurity=False, rounded=False, ax=ax ) # 手动替换节点文本中的样本数为加权总样本数 for text in ax.texts: original_text = text.get_text() # 提取节点索引 node_idx = int(original_text.split('\n')[0].split(' ')[1]) weighted_samples = int(single_tree.tree_.weighted_n_node_samples[node_idx]) new_text = original_text.replace( f'samples = {single_tree.tree_.n_node_samples[node_idx]}', f'samples = {weighted_samples}' ) text.set_text(new_text)
内容的提问来源于stack exchange,提问作者EleniSop
相关产品推荐
相关产品推荐

