Sono curioso dell'implementazione pratica di una divisione binaria in un albero decisionale, in quanto si riferisce ai livelli di un predittore categorico .
Nello specifico, spesso userò una sorta di schema di campionamento (ad es. Insaccamento, sovracampionamento, ecc.) Quando creerò un modello predittivo usando un albero decisionale, al fine di migliorarne l'accuratezza e la stabilità predittive. Durante queste routine di campionamento, è possibile che una variabile categoriale venga presentata a un algoritmo di adattamento ad albero con un set di livelli inferiore al set completo.
Supponiamo che una variabile X assuma livelli {A,B,C,D,E}
. In un campione, forse {A,B,C,D}
sono presenti solo i livelli . Quindi, quando l'albero risultante viene utilizzato per la previsione, potrebbe essere presente l'intero set.
Continuando da questo esempio, supponiamo che un albero si divida su X e mandi {A,B}
a sinistra ea {C,D}
destra. Mi aspetterei che la logica della divisione binaria dicesse, di fronte a nuovi dati: "Se X ha valore A o B, invia a sinistra, altrimenti invia questo caso a destra". Ciò che sembra accadere in alcune implementazioni è "se X ha valore A o B, invia a sinistra, se X ha valore C o D invia a destra". Quando questo caso assume il valore E, l'algoritmo si interrompe.
Qual è il modo "giusto" per gestire una divisione binaria? Sembra che il modo molto più robusto sia implementato spesso, ma non sempre (vedi Rpart sotto).
Ecco un paio di esempi:
Rpart fallisce, gli altri sono ok.
#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