Пакет R caret (rpart): построение дерева классификации

Я несколько дней пытаюсь создать дерево классификации с помощью пакета каретки. Проблема в моих факторных переменных. Я генерирую дерево, но когда я пытаюсь использовать лучшую модель для прогнозов на тестовой выборке, это терпит неудачу, потому что функция поезда создает фиктивные переменные для моих факторных переменных, а затем функция предсказания не может найти эти вновь созданные фиктивные фигуры в тестовом наборе. . Как мне решить эту проблему?

Мой код выглядит следующим образом:

install.packages("caret", dependencies = c("Depends", "Suggests"))      
library(caret)                                      
db=data.frame(read.csv ("db.csv", head=TRUE, sep=";", na.strings ="?"))     
fix(db)
db$defaillance=factor(db$defaillance)
db$def=ifelse(db$defaillance==0,"No","Yes") 
db$def=factor(db$def)
db$defaillance=NULL
db$canal=factor(db$canal)
db$sect_isodev=factor(db$sect_isodev)
db$sect_risq=factor(db$sect_risq)       

#delete zero variance predictors                                
nzv <- nearZeroVar(db[,-78])
db_new <- db[,-nzv]

inTrain <- createDataPartition(y = db_new$def, p = .75, list = FALSE)                               
training <- db_new[inTrain,]
testing <- db_new[-inTrain,]
str(training)
str(testing)
dim(training)
dim(testing)

Ниже приведен пример функции str () для обучения / тестирования:

 $ FDR        : num  1305 211 162 131 143 ...
 $ FCYC       : num  0.269 0.18 0.154 0.119 0.139 ...
 $ BFDR       : num  803 164 108 72 76 63 100 152 188 80 ...
 $ TRES       : num  502 47 54 59 67 49 53 -7 -103 -109 ...
 $ sect_isodev: Factor w/ 9 levels "1","2","3","4",..: 4 3 3 3 3 3 3 3 3 3 ...
 $ sect_risq  : Factor w/ 6 levels "0","1","2","3",..: 6 6 6 6 6 6 6 6 6 6 ...
 $ def        : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
> dim(training)
[1] 14553    42
> dim(testing)
[1] 4850   42

Тогда мой код выглядит так:

fitControl <- trainControl(method = "repeatedcv",
                           number = 10,
                           repeats = 10,
                   classProbs = TRUE,
                   summaryFunction = twoClassSummary)

#CART1
set.seed(1234)
tree1 = train (def~.,
           training,
           method = "rpart",
           tuneLength=20,
           metric="ROC",
           trControl = fitControl)

Образец

summary(tree1$finalModel)

здесь

RNTB          38.397731
sect_isodev1   6.742289
sect_isodev3   4.005016
sect_isodev8   2.520850
sect_risq3     9.909127
sect_risq4     6.737908
sect_risq5     3.085714
SOLV          73.067539
TRES          47.906884
sect_isodev2   0.000000
sect_isodev4   0.000000
sect_isodev5   0.000000
sect_isodev6   0.000000
sect_isodev7   0.000000
sect_isodev9   0.000000
sect_risq0     0.000000
sect_risq1     0.000000
sect_risq2     0.000000

И вот ошибка:

model.tree1 ‹- предсказать (tree1 $ finalModel, testing) Ошибка в eval (expr, envir, enclos): объект 'sect_isodev1' не найден

Мне интересно еще кое-что. Я нашел в книге Макса Куна «Прогнозное моделирование с помощью R» следующий синтаксис:

predict(rpartTune$finalModel, newdata, type = "class")

где rpartTune$finalModel - дерево классификации, идентичное моему (или мое, идентичное его). Теперь R не принимает type = "class". Только type = "prob". Я обеспокоен этим.

Заранее спасибо за ваши ответы


person lorelai    schedule 18.12.2014    source источник


Ответы (2)


Насколько я могу судить, есть две проблемы:

  • R не может найти подходящую predict функцию для tree1$finalModel, которая должна быть predict.rpart, поскольку tree1$finalModel относится к классу rpart. Я тоже получаю эту ошибку и, к сожалению, не знаю основной причины. По этой же причине R не принимает type = "class". predict.rpart примет это.
  • Использование функции train с формулой вместо объектов x и y приводит к тому, что переменные типа sect_isodev1 не могут быть найдены позже.

После воспроизведения вашей ошибки со случайными данными (похожими на ваш str) с использованием объектов x и y и явным вызовом predict.rpart из rpart у меня сработало:

tree1 = train (y = training$def,
               x = training[, -which(colnames(training) == "def")],
               method = "rpart",
               tuneLength=20,
               metric="ROC",
               trControl = fitControl)
summary(tree1$finalModel)
# This still results in Error: could not find function "predict.rpart":
model.tree1 <- predict.rpart(tree1$finalModel, newdata = testing)
# Explicitly calling predict.rpart from the rpart package works:
rpart:::predict.rpart(object = tree1$finalModel, 
                      newdata = testing, 
                      type = "class") 

Кстати, predict(tree1, testing), что означает использование predict.train с объектом train, также работает и возвращает предсказанные классы. Изменить: как указал Макс, обычно лучше просто использовать этот подход, чем заставлять работать другую predict функцию.

person thie1e    schedule 18.12.2014

Не используйте predict.rpart с train$finalModel, если у вас нет действительно веской причины. Объект rpart ничего не знает о том, что train делал, включая предварительную обработку. Это может не дать вам правильный ответ. В конце концов, вы могли использовать train, чтобы избежать мелочей, поэтому позвольте predict.train выполнить работу.

Максимум

РЕДАКТИРОВАТЬ -

Про type = "class" и type = "prob" бит ..

predict.rpart по умолчанию производит вероятности классов. Хотя rpart - один из самых ранних пакетов, это нетипично, поскольку большинство создает классы по умолчанию.

predict.train по умолчанию создает классы, и вы должны использовать type = "prob", чтобы получить вероятности.

person topepo    schedule 19.12.2014