2014-12-18 2 views
4

В течение нескольких дней я пытаюсь выполнить дерево классификации с помощью пакета caret. Проблема заключается в моих переменных фактора. Я генерирую дерево, но когда я пытаюсь использовать лучшую модель для прогнозирования тестового образца, она терпит неудачу, потому что функция поезда создает манекены для моих переменных факторов, а затем функция предсказания не может найти эти вновь созданные манекены в тестовом наборе , Как мне решить эту проблему?R-пакет (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) 

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

$ 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 <- predict(tree1$finalModel,testing) Error in eval(expr, envir, enclos) : object 'sect_isodev1' not found

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

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

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

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

ответ

5

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

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

После воспроизведения вашей ошибки со случайными данными (напоминающие ваш str), используя х и у объектов и вызов 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.

+0

спасибо. Он работает плавно. Я ценю время и усилия, которые вы вложили в это. СПАСИБО! – lorelai

7

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

Max

EDIT -

О type = "class" и type = "prob" немного ..

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

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

Смежные вопросы