2015-05-07 1 views
9

Использование R 3.2.0 с кареткой 6.0-41 и randomForest 4.6-10 на 64-разрядной машине Linux.Ошибка при использовании функции прогноза() для объекта randomForest, обученного с помощью каретки() с использованием формулы

При попытке использовать метод predict() на randomForest объекте обученного с функцией train() из caret пакета, используя формулу, функция возвращает ошибку. При обучении через randomForest() и/или используя x= и y=, а не формулу, все работает плавно.

Вот рабочий пример:

library(randomForest) 
library(caret) 

data(imports85) 
imp85  <- imports85[, c("stroke", "price", "fuelType", "numOfDoors")] 
imp85  <- imp85[complete.cases(imp85), ] 
imp85[] <- lapply(imp85, function(x) if (is.factor(x)) x[,drop=TRUE] else x) ## Drop empty levels for factors. 

modRf1 <- randomForest(numOfDoors~., data=imp85) 
caretRf <- train(numOfDoors~., data=imp85, method = "rf") 
modRf2 <- caretRf$finalModel 
modRf3 <- randomForest(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"]) 
caretRf <- train(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"], method = "rf") 
modRf4 <- caretRf$finalModel 

p1  <- predict(modRf1, newdata=imp85) 
p2  <- predict(modRf2, newdata=imp85) 
p3  <- predict(modRf3, newdata=imp85) 
p4  <- predict(modRf4, newdata=imp85) 

Среди последних 4-х строк, только второй один p2 <- predict(modRf2, newdata=imp85) возвращает следующее сообщение об ошибке:

Error in predict.randomForest(modRf2, newdata = imp85) : 
variables in the training data missing in newdata 

Представляется, что причиной этой ошибки является то, что метод predict.randomForest использует rownames(object$importance) для определения имени переменных, используемых для обучения случайному лесу object. А если смотреть на

rownames(modRf1$importance) 
rownames(modRf2$importance) 
rownames(modRf3$importance) 
rownames(modRf4$importance) 

Мы видим:

[1] "stroke" "price" "fuelType" 
[1] "stroke" "price" "fuelTypegas" 
[1] "stroke" "price" "fuelType" 
[1] "stroke" "price" "fuelType" 

Так или иначе, при использовании функции carettrain() с формулой меняет название (фактор) переменные в importance поле randomForest объекта ,

Это действительно несоответствие между формулой и не-формулой версии функции каттера train()? Или я чего-то не хватает?

+2

'modRf3 <- RandomForest (х = dataTrain [с ("инсульт", "цена", "fuelType")], у = dataTrain [, "numOfDoors"], данные = imp85) Ошибка randomForest (x = dataTrain [, c ("stroke", "price", "fuelType")],: объект 'dataTrain' не найден' –

+0

Как вы указали, вы не определили 'dataTrain' в вашем примере, что означает проблема не является [воспроизводимой] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Нелегко помочь вам, если мы не сможем запустить код и получите те же результаты, что и вы. – MrFlick

+0

Мой плохой 'dataTrain' должен был быть' imp85', я отредактировал код в исходном вопросе. Я также удалил опцию 'data = imp85' в вызове, где' x' и ' y' явно упоминаются как t здесь бесполезно. –

ответ

21

Во-первых, почти никогда использовать объект $finalModel для прогнозирования. Используйте predict.train. Это один из хороших примеров того, почему.

Существует некоторая несогласованность между некоторыми функциями (включая randomForest и train). Большинство функций в R, которые используют метод формулы, преобразуют коэффициенты-предсказатели в фиктивные переменные, потому что их модели требуют численных представлений данных. Исключение составляют модели, основанные на деревьях и правилах (которые могут разделяться на категориальные предиктора), наивные байесов и некоторые другие.

Так randomForest будет не создавать фиктивные переменные при использовании randomForest(y ~ ., data = dat) но train (и большинство других) будут с помощью вызова, как train(y ~ ., data = dat).

Ошибка возникает из-за того, что fuelType является фактором. У фиктивных переменных, созданных train, нет одинаковых имен, поэтому predict.randomForest не может их найти.

Использование неформового метода с train передаст предикторам факторов randomForest, и все будет работать.

TL; DR

Используйте метод, не формула с train, если вы хотите, чтобы одни и те же уровни или использование predict.train

Макс

+1

У меня, к сожалению, недостаточно репутации, чтобы поддержать свой ответ, но вы полностью ответили на мой вопрос. Я задавался вопросом обо всех тех функциях, которые позволяют использовать формулу, если была разница в способе обработки данных между формулой и не-формульными версиями вызова функции. Теперь я знаю! Для использования '$ finalModel' я согласен с тем, что использовать его вообще не рекомендуется. Здесь я просто хотел сравнить результаты методов 'caret' и' randomForest'. –

0

Там могут быть две причины, почему вы получите эту ошибку.

1. Категории категориальных переменных в поездах и наборах тестов не совпадают. Чтобы проверить это, вы можете запустить что-то вроде следующего.

Ну, во-первых, рекомендуется сохранять независимые переменные/функции в списке. Скажем, что этот список - «варны». И скажите, что вы разделили «Данные» на «Поезд» и «Тест». Пойдемт:

for (v in vars){ 
    if (class(Data[,v]) == 'factor'){ 
    print(v) 
    # print(levels(Train[,v])) 
    # print(levels(Test[,v])) 
    print(all.equal(levels(Train[,v]) , levels(Test[,v]))) 
    } 
} 

После того, как вы найдете несовпадающих категориальные переменные, вы можете вернуться назад, и ввести категории данных испытаний на данные поездов, а затем повторно создать модель. В цикле аналогично выше, для каждого nonMatchingVar, вы можете сделать

levels(Test$nonMatchingVar) <- levels(Train$nonMatchingVar) 

2. Глупый один. Если вы случайно оставите зависимую переменную в наборе независимых переменных, вы можете столкнуться с этим сообщением об ошибке. Я сделал эту ошибку. Решение: Просто будьте осторожны.

0

Другой способ заключается в явном кодировании данных тестирования с использованием model.matrix, например.

p2 <- predict(modRf2, newdata=model.matrix(~., imp85)) 

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

  • Нет связанных вопросов^_^