0Pricing
R Academy · 课时

决策树:集成模型的基础

使用 rpart 构建并可视化决策树,理解偏差与方差之间的权衡

决策树:集成模型的基础 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

决策树如何进行划分

决策树会递归地将特征空间划分为矩形区域。在每个节点,算法都会搜索所有特征和所有可能的划分点,寻找能够最好地区分目标变量的划分。最终得到的是一棵由 if-else 规则组成的树。

library(rpart)

# Fit a classification tree
tree <- rpart(
  Species ~ .,
  data   = iris,
  method = 'class'  # use 'anova' for regression
)

print(tree)

GINI 与熵划分准则

划分准则用于衡量节点的不纯度。基尼不纯度衡量随机选择的元素被错误分类的概率。熵(信息增益)衡量信息无序程度的减少量。两者通常会生成相似的树;GINI 的计算速度更快,也是 rpart 的默认准则。

# Default: Gini impurity (parms = list(split = 'gini'))
tree_gini <- rpart(Species ~ ., data = iris, method = 'class')

# Using information gain (entropy)
tree_entropy <- rpart(
  Species ~ ., data = iris, method = 'class',
  parms = list(split = 'information')
)

cat('Gini root split:', tree_gini$frame$var[1])
cat('Entropy root split:', tree_entropy$frame$var[1])

printcp() — 复杂度表

printcp(tree) 用于打印复杂度参数(CP)表。每一行显示一个树大小(分裂次数)、该树在训练数据上的相对误差,以及交叉验证误差(xerror)。CP 表用于找出最佳剪枝级别。

tree <- rpart(medv ~ ., data = MASS::Boston, method = 'anova',
              control = rpart.control(minsplit = 5, cp = 0.001))

printcp(tree)

# Identify the CP with minimum cross-validated error
best_cp <- tree$cptable[
  which.min(tree$cptable[, 'xerror']),
  'CP'
]
cat('Best CP:', best_cp)

prune() — 修剪树

prune(tree, cp) 会将树修剪回 cp 指定的复杂度级别。剪枝会合并预测价值很小的分支,从而防止过拟合。标准做法是:先找出使 CV 误差最小的 CP,再进行剪枝。

best_cp <- tree$cptable[
  which.min(tree$cptable[, 'xerror']), 'CP'
]

pruned_tree <- prune(tree, cp = best_cp)

cat('Original tree nodes:', nrow(tree$frame))
cat('Pruned tree nodes:', nrow(pruned_tree$frame))

rpart.plot() — 可视化树

rpart.plot 包中的 rpart.plot(tree) 会生成清晰、带颜色的决策树可视化图。每个内部节点显示分裂规则;每个叶节点显示预测类别和训练样本所占的比例。

library(rpart.plot)

tree <- rpart(Species ~ ., data = iris, method = 'class')
pruned <- prune(tree, cp = 0.02)

rpart.plot(
  pruned,
  type   = 4,     # split labels on branches
  extra  = 104,   # show class + probability
  fallen.leaves = TRUE
)

偏差—方差权衡

深且未经剪枝的树具有较低偏差(几乎可以完美拟合训练数据),但具有较高方差(数据稍有变化就可能生成完全不同的树)。较浅的树或经过剪枝的树偏差较高,但方差较低。最佳树需要在这两种误差来源之间取得平衡。

随机森林和提升等集成方法会直接应对这种权衡。

# Deep tree = low bias, high variance (overfits)
deep_tree <- rpart(medv ~ ., data = MASS::Boston,
                   control = rpart.control(minsplit = 2, cp = 0))

# Shallow tree = high bias, low variance (underfits)
shallow_tree <- rpart(medv ~ ., data = MASS::Boston,
                      control = rpart.control(maxdepth = 2))

cat('Deep nodes:', nrow(deep_tree$frame))
cat('Shallow nodes:', nrow(shallow_tree$frame))

决策树过拟合

未经剪枝的树可以通过记住每个训练样本,将训练误差降为零。当在未见过的数据上评估同一棵树时,其性能会大幅下降。这是监督学习中过拟合的典型例子。

set.seed(42)
train_idx <- sample(nrow(MASS::Boston), 400)
train_bos <- MASS::Boston[train_idx, ]
test_bos  <- MASS::Boston[-train_idx, ]

# Fully grown tree
full <- rpart(medv ~ ., data = train_bos,
              control = rpart.control(cp = 0, minsplit = 2))

train_pred <- predict(full, train_bos)
test_pred  <- predict(full, test_bos)

cat('Train RMSE:', sqrt(mean((train_pred - train_bos$medv)^2)))
cat('Test  RMSE:', sqrt(mean((test_pred  - test_bos$medv)^2)))

来自 rpart 的变量重要性

rpart 会为每个预测变量记录 variable.importance:该变量在所有分裂中带来的分裂准则总改进量。这可以快速显示哪些特征主导了模型的决策。

tree <- rpart(medv ~ ., data = MASS::Boston, method = 'anova')

# Variable importance (sorted)
imp <- sort(tree$variable.importance, decreasing = TRUE)
print(imp)

# Quick barplot
barplot(imp, las = 2, main = 'Variable Importance',
        col = 'steelblue', cex.names = 0.8)

从树到集成

单棵决策树并不稳定:对数据重新采样会生成差异很大的树。集成方法利用了这种不稳定性:

  • 装袋法 / 随机森林:在自助采样样本上训练许多树,然后取平均值。
  • 提升法:按顺序构建树,每棵树都纠正前一棵树的误差。
  • 这两种方法都能降低方差,同时保留树的表达能力。
# Demonstrating instability of a single tree
set.seed(1); t1 <- rpart(medv ~ ., data = MASS::Boston[sample(506, 400), ])
set.seed(2); t2 <- rpart(medv ~ ., data = MASS::Boston[sample(506, 400), ])

# Root split may differ between trees
cat('Tree 1 root split:', t1$frame$var[1])
cat('Tree 2 root split:', t2$frame$var[1])

rpart 控制参数

rpart.control() 控制树的生长方式。主要参数包括:cp(复杂度惩罚)、minsplit(尝试分裂所需的最少观测数)、minbucket(叶节点的最小大小)以及 maxdepth。理解这些参数对于调节基于树的模型至关重要。

ctrl <- rpart.control(
  cp        = 0.005,  # complexity penalty
  minsplit  = 20,     # min obs to try a split
  minbucket = 7,      # min obs in any leaf
  maxdepth  = 10      # max tree depth
)

tree <- rpart(medv ~ ., data = MASS::Boston,
              method = 'anova', control = ctrl)

printcp(tree)

评估树的性能

剪枝后,在留出的测试集上评估这棵树。对于回归,计算 RMSE 和 R 平方;对于分类,计算准确率和混淆矩阵。将这些指标与基准模型进行比较,以了解单棵树所带来的价值。

pruned_tree <- prune(tree, cp = best_cp)

test_pred <- predict(pruned_tree, newdata = test_bos)

rmse <- sqrt(mean((test_pred - test_bos$medv)^2))
ss_res <- sum((test_pred - test_bos$medv)^2)
ss_tot <- sum((test_bos$medv - mean(test_bos$medv))^2)
r2 <- 1 - ss_res / ss_tot

cat('RMSE:', round(rmse, 3))
cat('R2:', round(r2, 3))

快速检查

以下哪项最准确地描述了调用 prune(tree, cp = best_cp) 的目的?

决策树回顾

《决策树——集成方法的基础》要点:

  • 树会递归地划分特征空间;分裂使用基尼或熵准则。
  • rpart(y ~ ., data, method) 用于拟合树;printcp() 显示复杂度表。
  • 找出交叉验证误差最小的 CP,然后执行 prune(tree, cp)。
  • rpart.plot() 用于可视化树的结构。
  • 深树会过拟合(低偏差、高方差);浅树会欠拟合。
  • tree$variable.importance 根据预测变量带来的分裂总改进量对其排序。
  • 集成方法(随机森林、提升法)可以克服单棵树的不稳定性。
# Standard rpart workflow
tree <- rpart(y ~ ., data = train, method = 'anova',
              control = rpart.control(cp = 0.001))

best_cp <- tree$cptable[which.min(tree$cptable[, 'xerror']), 'CP']
pruned  <- prune(tree, cp = best_cp)

test_pred <- predict(pruned, newdata = test)
rmse <- sqrt(mean((test_pred - test$y)^2))
cat('Pruned Tree RMSE:', rmse)

常见问题解答

「决策树:集成模型的基础」课时是免费的吗?

是的 — 「决策树:集成模型的基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「决策树:集成模型的基础」这节课中我会学到什么?

使用 rpart 构建并可视化决策树,理解偏差与方差之间的权衡 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「决策树:集成模型的基础」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 决策树:集成模型的基础
  2. 使用 ranger 构建随机森林
  3. 使用 xgboost 进行梯度提升
  4. 特征重要性与模型解读
← 返回 R Academy