2015-02-05 7 views
0

Мне кажется, что я обнаружил ошибку в исполнении функции pred() для метода = gbm в пакете Caret в R. Мне любопытно узнать, согласны ли другие, или если у кого-то есть объяснение поведение этой функции.Возможная ошибка в функции Caret: предсказать.gb()?

1. Сформировать данные

library(caret) 

x1 <- rnorm(100) 

x2 <- rnorm(100, 2) 

y <- x1 + x2 + rnorm(100) 

df <- data.frame(x1=x1, x2=x2, y=y) 

2. Прогнозировать с помощью метода = "лм"

Следующий код работает, как ожидалось: с помощью метода = «лм» два предсказаны значения совпадают , В первом случае p1, «y» включен в newdata, во втором случае p2 - нет.

tempd <- df[1:99, c("y", "x1", "x2") ] 

newdata <- df[100, c("y", "x1", "x2")] 

lm.fit <- train(y~x1 + x2, data=tempd, method="lm") 

p1 <- predict(lm.fit$finalModel, newdata=newdata) 

newdata <- df[100, c("x1", "x2")] 

p2 <- predict(lm.fit$finalModel, newdata=newdata) 

p1 должно быть равно p2, и делает:

p1==p2 

3. Прогнозировать с помощью метода = "GBM"

Этот код не работает, как ожидалось: с помощью метода = «GBM , "С одинаковой настройкой, два предсказанных значения не совпадают.

tempd <- df[1:99, c("y","x1","x2")] 

newdata <- df[100, c("y","x1","x2")] 

gbm.fit <- train(y~x1+x2 , data=tempd, method="gbm", verbose=F) 

p1 <- predict(gbm.fit$finalModel, newdata=newdata, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,      
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 

newdata <- df[100, c("x1","x2")] 

p2 <- predict(gbm.fit$finalModel, newdata=newdata, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,     
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 

В этом случае p1 не равно p2:

p1==p2 

4. предсказать, используя метод = "GBM" с другим набором до

НО, как ни странно, с одним небольшое изменение - не явное обозначение переменных в операции подмножества - оно действительно работает:

tempd <- df[1:99, ] 

newdata <- df[100, ] 

gbm.fit <- train(y~x1+x2 , data=tempd, method="gbm", verbose=F) 

p1 <- predict(gbm.fit$finalModel, newdata=newdata, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,           
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 

newdata <- df[100, c("x1","x2")] 

p2 <- predict(gbm.fit$finalModel, newdata=newdata, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,     
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 

p1==p2 

Заранее благодарим за наши мысли.

Джефф

+0

Есть ли причина, по которой вы не должны следовать «нормальному» использованию «предсказывать», например, «предсказывать (gbm.fit, newdata = newdata)»? –

ответ

2

Как @Pascal отметил, вы пропуская важный шаг. Вместо того, чтобы вызывать predict() по значению finalModel, вы должны позвонить predict непосредственно на объект gmb.fit. Примечание

class(gbm.fit) 
# [1] "train"   "train.formula" 
class(gbm.fit$finalModel) 
# [1] "gbm" 

Поскольку эти объекты имеют разные классы, они вызывают различные основные функции прогнозирования. Важная часть состоит в том, что predict.train преобразует newdata в нужный формат для предиктора gbm. Без этого изменения формы данных, вы получите неправильные результаты (предсказатель ожидает, что столбцы в определенном порядке)

Наблюдайте

newdata1 <- df[100, c("y","x1","x2")] 
newdata2 <- df[100, c("x1","x2")] 
newdata3 <- df[100, ] 

predict(gbm.fit, newdata1) 
# [1] 1.427069 
predict(gbm.fit, newdata2) 
# [1] 1.427069 
predict(gbm.fit, newdata3) 
# [1] 1.427069 

predict(gbm.fit$finalModel, newdata=newdata1, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,     
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 
# [1] 2.166468 
predict(gbm.fit$finalModel, newdata=newdata2, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,     
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 
# [1] 1.427069 
predict(gbm.fit$finalModel, newdata=newdata3, 
      n.trees=gbm.fit$finalModel$tuneValue$n.trees,     
      interaction.depth=gbm.fit$finalModel$tuneValue$interaction.depth, 
      shrinkage=gbm.fit$finalModel$tuneValue$shrinkage) 
# [1] 1.427069 

Так что, если вы собираетесь использовать функцию train() в соответствии с Вашим модель, обязательно используйте правильную функцию predict.train, чтобы правильно делать прогнозы от модели.