我对决策树中二元拆分的实际实现感到好奇——因为它与分类预测器的级别有关.
具体来说,在使用决策树构建预测模型时,我经常会使用某种采样方案(例如装袋、过采样等),以提高其预测准确性和稳定性。在这些采样例程中,分类变量有可能呈现给小于完整水平集的树拟合算法。
假设变量 X 具有水平{A,B,C,D,E}
。在样本中,可能只{A,B,C,D}
存在水平。然后,当结果树用于预测时,可能会出现完整集。
继续这个例子,假设一棵树在 X 上分裂并{A,B}
向左和{C,D}
向右发送。我希望二进制拆分的逻辑在面对新数据时会说:“如果 X 具有值 A 或 B,则发送到左侧,否则,将这种情况发送到右侧”。在某些实现中似乎发生的是“如果 X 具有值 A 或 B,则发送到左侧,如果 X 具有值 C 或 D 发送到右侧”。当这种情况取值为 E 时,算法就会崩溃。
处理二进制拆分的“正确”方式是什么?似乎经常实现更健壮的方式,但并非总是如此(参见下面的 Rpart)。
这里有几个例子:
Rpart 失败,其他都正常。
#test trees and missing values
summary(solder)
table(solder$PadType)
# create train and validation
set.seed(12345)
t_rows<-sample(1:nrow(solder),size=360, replace=FALSE)
train_solder<-solder[t_rows,]
val_solder<-solder[-t_rows,]
#look at PadType
table(train_solder$PadType)
table(val_solder$PadType)
#set a bunch to missing
levels(train_solder$PadType)[train_solder$PadType %in% c('L8','L9','W4','W9')] <- 'MISSING'
#Fit several trees, may have to play with the parameters to get them to split on the variable
####RPART
mod_rpart<-rpart(Solder~PadType,data=train_solder)
predict(mod_rpart,val_solder)
#Error in model.frame.default(Terms, newdata, na.action = na.action, xlev = attr(object, :
#factor 'PadType' has new level(s) D6, L6, L7, L8, L9, W4
####TREE
mod_tree<-tree(Solder~PadType,data=train_solder,split="gini")
predict(mod_tree,val_solder) #works fine
####ctree
mod_ctree<-ctree(Solder~PadType,data=train_solder,control = ctree_control(mincriterion = 0.05))
predict(mod_ctree,val_solder) #works fine