如何为随机森林与梯度提升模型绘制决策边界?
嘿,我来帮你搞定这两个模型的决策边界绘制问题!这两个错误本质上都是因为modelr::add_predictions调用模型的预测函数时,没有传递这些模型特有的必要参数导致的。下面是具体的解决办法和解释:
1. 随机森林(Random Forest)的问题解决
为啥会报错?
你的randomForest模型因为把y转成了0/1的数值型,所以默认拟合的是回归模型,但modelr::add_predictions在调用预测函数时,不小心触发了分类模型的参数检查逻辑,导致报错。另外,你之前的代码里还有个小笔误:x2 = modelr::seq_range(testing_set$x1, 50)应该是testing_set$x2,不然网格的x2范围和x1完全一样,画出来的图会变形。
修正方案
有两种处理方式,选哪种取决于你想把问题当成回归还是分类(你的原始数据是二分类,更推荐第二种):
方式一:保持回归模式,手动传递预测参数
library(randomForest) library(modelr) library(tidyverse) # 拟合回归型随机森林 rf_fit <- randomForest(y ~ ., data=training_set, mtry = 2, ntree=500) # 创建网格,注意修正x2的范围,并用...传递预测参数 grid_rf <- crossing( x1 = modelr::seq_range(testing_set$x1, 50), x2 = modelr::seq_range(testing_set$x2, 50) ) %>% modelr::add_predictions(rf_fit, type = "response") # 回归模式下明确指定type更稳妥 # 绘制决策边界 p + geom_contour(data = grid_rf, aes(x1, x2, z = as.numeric(pred)), binwidth = 1)
方式二:转成分类模式(更贴合你的原始问题)
既然你的y本来是二分类标签,不如把它转回因子,用分类随机森林拟合,这样预测概率画边界更直观:
# 把训练/测试集的y转回因子 training_set$y <- as.factor(training_set$y) testing_set$y <- as.factor(testing_set$y) # 拟合分类随机森林 rf_fit_class <- randomForest(y ~ ., data=training_set, mtry = 2, ntree=500) # 添加预测时指定type="prob"获取类别概率,然后展开结果 grid_rf_class <- crossing( x1 = modelr::seq_range(testing_set$x1, 50), x2 = modelr::seq_range(testing_set$x2, 50) ) %>% modelr::add_predictions(rf_fit_class, type = "prob") %>% unnest(pred) # 画0.5概率的等高线(就是分类决策边界) p + geom_contour(data = grid_rf_class, aes(x1, x2, z = `1`), breaks = 0.5, color = "red")
2. 梯度提升(GBM)的问题解决
为啥会报错?
gbm的预测函数必须指定n.trees参数——也就是你要用多少棵训练好的树来做预测,但modelr::add_predictions默认不会帮你传这个参数,所以直接报错说参数缺失了。
修正方案
很简单,用add_predictions的...参数把n.trees传进去就行:
library(gbm) # 拟合GBM模型(建议用训练集而不是整个数据集,符合训练测试拆分的逻辑) fitBoost <- gbm(y ~ ., data=training_set, distribution = "gaussian", n.trees = 1000) # 创建网格并传递n.trees参数 grid_boost <- crossing( x1 = modelr::seq_range(testing_set$x1, 50), x2 = modelr::seq_range(testing_set$x2, 50) ) %>% modelr::add_predictions(fitBoost, n.trees = 1000) # 绘制决策边界 p + geom_contour(data = grid_boost, aes(x1, x2, z = as.numeric(pred)), binwidth = 1)
如果想按二分类来做,把distribution改成"bernoulli",预测时指定type="response"获取概率,画0.5的边界:
fitBoost_class <- gbm(y ~ ., data=training_set, distribution = "bernoulli", n.trees = 1000) grid_boost_class <- crossing( x1 = modelr::seq_range(testing_set$x1, 50), x2 = modelr::seq_range(testing_set$x2, 50) ) %>% modelr::add_predictions(fitBoost_class, n.trees = 1000, type = "response") p + geom_contour(data = grid_boost_class, aes(x1, x2, z = pred), breaks = 0.5, color = "green")
小总结
modelr::add_predictions的...参数是关键,它能让你传递模型预测函数需要的任何额外参数;- 区分模型是回归还是分类模式,对应传递正确的
type参数; - 记得检查代码里的小笔误,比如之前的x2范围错误,不然画出来的图会不对。
内容的提问来源于stack exchange,提问作者Derek Adams
相关产品推荐
相关产品推荐

