如何生成以Expire_Day/Rotation_Day为根且按Category过滤的随机森林决策树图
问题描述
我正在用R语言学习机器学习,针对过期产品构建决策树模型,现有如下原始数据:
Product, Category, Temperature, Expire_Day, Rotation_Day, Weight, State Tapa, Pulpa, 0, 30, 21, 4.21, No Tapa, Pulpa, 0, 30, 21, 3.82, Expire Nalga, Pulpa, 0, 30, 25, 6.10, No Nalga, Pulpa, 0, 30, 25, 5, Expire Costeleta, Bife, 7, 5, 3, 1.10, No Costeleta, Bife, 7, 5, 3, 2.25, No Costeleta, Bife, 7, 5, 3, 0.9, Expire Brazuelo, Bife, 7, 5, 3, 2.5, No
我对数据做了如下预处理:
- 用
dummyVars将Product和Category转为哑变量 - 用MinMaxScaler归一化Weight
- Temperature、Expire_Day和Rotation_Day因存在关联未做转换
- 将State转为Factor类型
处理后的最终模型数据如下:
Product.Tapa, Product.Nalga, Product.Costeleta, Product.Brazuelo, Category.Pulpa, Category.Bife, Temperature, Expire_Day, Rotation_Day, Weight, State 1, 0, 0, 0, 1, 0, 0, 30, 21, 0.9, No 1, 0, 0, 0, 1, 0, 0, 30, 21, 0.78, Expire 0, 1, 0, 0, 1, 0, 0, 30, 25, 0.99, No 0, 1, 0, 0, 1, 0, 0, 30, 25, 0.72, Expire 0, 0, 1, 0, 0, 1, 7, 5, 3, 0.12, No 0, 0, 1, 0, 0, 1, 7, 5, 3, 0.22, No 0, 0, 1, 0, 0, 1, 7, 5, 3, 0.88, Expire 0, 0, 0, 1, 0, 1, 7, 5, 3, 0.5, No
随后用以下代码构建随机森林模型:
mtry <- 6 ntree <- 24 rf_model <- randomForest(result ~ ., data = trainData, mtry = mtry, ntree = ntree, trControl = control, varimp = TRUE, importance = TRUE, weight = data_weights, oob_score = FALSE)
目前模型预测精度达0.90,但无法生成满足以下两个条件的决策树可视化图表:
- 条件a:决策树必须以Expire_Day和Rotation_Day列作为起始节点(二者为最重要特征)
- 条件b:能够按Category过滤分类树,例如仅查看"Pulpa"类别对应的树、仅查看"Bife"类别对应的树,或查看完整树
解决方案
满足条件a:强制以指定特征为起始节点
随机森林的单棵树节点选择带有随机性,无法直接强制所有树都以指定特征开头。若要严格控制起始节点,推荐使用单棵决策树模型(如rpart),或者从随机森林中筛选符合要求的单棵树可视化:
方案1:用rpart构建可控的决策树
rpart支持通过参数调整特征分裂优先级,确保目标特征优先作为起始节点:
library(rpart) library(rpart.plot) # 构建决策树,通过control参数强化目标特征的分裂优先级 tree_model <- rpart(State ~ ., data = trainData, control = rpart.control( maxdepth = 5, cp = 0.01, # 确保分裂优先选择信息增益高的特征(Expire_Day/Rotation_Day已被标记为重要特征) parms = list(split = "gini") ), weights = data_weights) # 可视化决策树 rpart.plot(tree_model, main = "决策树(以Expire_Day/Rotation_Day为起始节点)")
方案2:从随机森林中筛选符合条件的单棵树
遍历随机森林的所有树,找到起始节点为Expire_Day或Rotation_Day的树,再可视化:
library(randomForest) library(randomForestExplainer) # 遍历所有树,筛选起始节点为目标特征的树 target_features <- c("Expire_Day", "Rotation_Day") valid_tree_idx <- NULL for (i in 1:rf_model$ntree) { tree <- getTree(rf_model, k = i, labelVar = TRUE) if (tree$split[1] %in% target_features) { valid_tree_idx <- c(valid_tree_idx, i) } } # 可视化第一棵符合条件的树 if (!is.null(valid_tree_idx)) { plot_tree(rf_model, tree_idx = valid_tree_idx[1], main = "随机森林中符合要求的单棵树") }
满足条件b:按Category过滤分类树
最直观的方式是拆分数据集,针对不同Category分别构建子模型后可视化:
步骤1:拆分数据集
# 按Category拆分数据 trainData_pulpa <- trainData[trainData$Category.Pulpa == 1, ] trainData_bife <- trainData[trainData$Category.Bife == 1, ]
步骤2:分别构建并可视化子模型
# Pulpa类别决策树 tree_pulpa <- rpart(State ~ ., data = trainData_pulpa, control = rpart.control(maxdepth = 3)) rpart.plot(tree_pulpa, main = "Pulpa类别过期产品决策树") # Bife类别决策树 tree_bife <- rpart(State ~ ., data = trainData_bife, control = rpart.control(maxdepth = 3)) rpart.plot(tree_bife, main = "Bife类别过期产品决策树") # 全类别决策树 tree_full <- rpart(State ~ ., data = trainData, control = rpart.control(maxdepth = 3)) rpart.plot(tree_full, main = "全类别过期产品决策树")
注意事项
- 随机森林的核心是集成多棵树的结果,单棵树的可视化更多用于解释模型逻辑,若要严格控制节点顺序,单棵决策树是更合适的选择。
- 拆分Category后的数据量较小,需调整
cp(复杂度参数)或maxdepth避免模型过拟合。
内容的提问来源于stack exchange,提问作者Aegis
相关产品推荐
相关产品推荐

