如何用DecisionTreeRegressor复现RandomForestRegressor中的特定决策树?
如何用DecisionTreeRegressor复现RandomForestRegressor中的特定决策树?
兄弟,我之前也踩过这个一模一样的坑!明明参数、bootstrap样本都对齐了,结果训练出来的树结构和预测结果还是不一样,折腾了半天才揪出问题所在——RandomForestRegressor在训练单棵树时,自动处理了重复采样样本的权重,但你手动训练DecisionTreeRegressor的时候忽略了这一点!
下面给你拆解问题和修正方案:
1. 核心问题:重复采样的样本权重
RandomForest的bootstrap是有放回采样,所以有些原始样本会被多次选中(比如sample_indices里可能有重复的索引)。sklearn的RandomForestRegressor在训练每棵树时,会给这些重复出现的样本赋予对应次数的权重(出现2次权重就是2,相当于这个样本在训练时被“用了2次”)。但你直接用Xs[sample_indices]得到的数据集,训练DecisionTreeRegressor时默认每个样本权重都是1,这就导致树的分裂逻辑完全不一样了!
2. 修正步骤:计算并传入样本权重
你需要先统计每个样本在bootstrap样本里的出现次数,生成权重数组,然后在训练DecisionTreeRegressor时传入sample_weight参数。
完整修正后的复现代码
#%% # 修正后的复现1号树代码 # Get the bootstrapped samples sample_indices = rf.estimators_samples_[0] bootstrap_Xs = Xs[sample_indices, :] bootstrap_y = y[sample_indices] # 计算样本权重:统计每个原始样本在bootstrap中的出现次数 unique_indices, counts = np.unique(sample_indices, return_counts=True) sample_weights = np.zeros(len(y)) # 初始化和原始样本长度一致的权重数组 for idx, cnt in zip(unique_indices, counts): sample_weights[idx] = cnt # 给每个原始样本赋值出现次数作为权重 bootstrap_weights = sample_weights[sample_indices] # 取bootstrap样本对应的权重 # 初始化决策树,完全对齐参数 decision_tree = DecisionTreeRegressor( random_state=tree.random_state, max_features=None, max_depth=max_depth, min_samples_leaf=min_samples_leaf, min_samples_split=min_samples_split, criterion="squared_error" # 和RandomForestRegressor默认准则保持一致 ) # 传入样本权重训练 decision_tree.fit(bootstrap_Xs, bootstrap_y, sample_weight=bootstrap_weights) # 验证预测结果是否一致 y_pred_original_tree = tree.predict(Xs_test) y_pred_replica = decision_tree.predict(Xs_test) print(np.allclose(y_pred_original_tree, y_pred_replica)) # 应该输出True
3. 其他需要确认的细节
- 你已经正确传递了
tree.random_state,这点确保了决策树分裂时的随机一致性,没问题。 - 你设置的
max_features=None(使用所有特征)和RandomForest的参数一致,这点也没问题。 - 另外,你之前的绘图代码有个小bug:
plt.figure(figsize=(20, 10)少了右括号,修正后才能正常显示树结构哦。
现在再运行代码,你会发现复现的树结构和原始树完全一致,预测结果也完全匹配了!
内容来源于stack exchange
相关产品推荐
相关产品推荐

