Jestem ciekawy praktycznej implementacji podziału binarnego w drzewie decyzyjnym - ponieważ dotyczy on poziomów predyktora jakościowego .
W szczególności często będę używał pewnego rodzaju schematu próbkowania (np. Tworzenie worków, nadpróbkowanie itp.) Podczas budowania modelu predykcyjnego przy użyciu drzewa decyzyjnego - w celu poprawy jego dokładności i stabilności predykcyjnej. Podczas tych procedur próbkowania możliwe jest przedstawienie zmiennej kategorialnej algorytmowi dopasowania drzewa z mniej niż pełnym zestawem poziomów.
Powiedzmy, że zmienna X przyjmuje poziomy {A,B,C,D,E}
. W próbce mogą występować tylko poziomy {A,B,C,D}
. Następnie, gdy powstałe drzewo jest używane do przewidywania, może być obecny pełny zestaw.
Kontynuując ten przykład, powiedz, że drzewo dzieli się na X i wysyła {A,B}
w lewo i {C,D}
w prawo. Oczekiwałbym, że logika podziału binarnego powie, kiedy w obliczu nowych danych: „Jeśli X ma wartość A lub B, wyślij w lewo, w przeciwnym razie wyślij tę skrzynkę w prawo”. W niektórych implementacjach wydaje się, że „jeśli X ma wartość A lub B, wyślij w lewo, jeśli X ma wartość C lub D, wyślij w prawo”. Gdy ten przypadek przyjmuje wartość E, algorytm ulega awarii.
Jaki jest „właściwy” sposób obsługi podziału binarnego? Wydaje się, że znacznie bardziej niezawodny sposób jest wdrażany często, ale nie zawsze (patrz Rpart poniżej).
Oto kilka przykładów:
Rpart zawiedzie, pozostałe są w porządku.
#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
źródło