Ошибка при использовании varImp для нейронной сети nnet

Мне нужно использовать функцию varImp в модели нейронной сети, созданной методом nnet через каретку.

Код:

#Load Packages
require(quantmod)
require(nnet)
require(caret)

#Creating data
T <- seq(0,20,length=200)                                   
y <- 1 + 3*cos(4*T+2) +.2*T^2 + rnorm(200)                  
dat <- data.frame( y, x1=Lag(y,1), x2=Lag(y,2),x3=Lag(y,3)) 
dat <- dat[4:length(dat[,1]),]
names(dat) <- c('y','x1','x2','x3')

set.seed(100) 
podzial <- createDataPartition(y, p = 3/4, list = FALSE)
zucz<-dat[podzial,]
ztest<-dat[-podzial,]

# Train control
ctrl <- trainControl(method = "LGOCV",p=0.7)

#Training
model <- train(y ~ x1+x2 , zucz, method='nnet', linout=TRUE, trace=F,maxit=100,skip=T,
           tuneGrid=expand.grid(.size=c(10),.decay=c(0,0.1,0.001,0.0001)),
           trControl = ctrl,
           preProcess = c("range"))

varImp(model,scale=F)

Когда я пытаюсь использовать varImp, возникает ошибка:

Error in i2h[hidden, input] <- abeta[grep(label, nms, fixed = TRUE)] : 
number of items to replace is not a multiple of replacement length

Я сделал несколько тестов с разным количеством нейронов. Похоже, что ошибка возникает, когда количество нейронов (параметр размера) больше 9. Как это исправить?


person mismael    schedule 26.05.2014    source источник
comment
Это означает, что общая длина (hidden * input) области вывода не соответствует длине того, что выводит abeta. Вам нужно это исправить.   -  person Carl Witthoft    schedule 26.05.2014


Ответы (1)


Я думаю, что это явная ошибка в пакете caret, особенно в функции caret:::GarsonWeights. Эта функция пытается декодировать имена коэффициентов из вашей окончательной модели. Они есть

names(coef(model$finalModel))
#  [1] "b->h1"   "i1->h1"  "i2->h1"  "b->h2"   "i1->h2"  "i2->h2"  "b->h3"  
#  [8] "i1->h3"  "i2->h3"  "b->h4"   "i1->h4"  "i2->h4"  "b->h5"   "i1->h5" 
# [15] "i2->h5"  "b->h6"   "i1->h6"  "i2->h6"  "b->h7"   "i1->h7"  "i2->h7" 
# [22] "b->h8"   "i1->h8"  "i2->h8"  "b->h9"   "i1->h9"  "i2->h9"  "b->h10" 
# [29] "i1->h10" "i2->h10" "b->o"    "h1->o"   "h2->o"   "h3->o"   "h4->o"  
# [36] "h5->o"   "h6->o"   "h7->o"   "h8->o"   "h9->o"   "h10->o" 

Здесь у вас есть 2 входных и 10 скрытых узлов. Функция пытается найти коэффициент для входа 1 и скрытой ноты 1 путем поиска "i1-> h1" с помощью

grep("i1->h1",names(coef(model$finalModel)),fixed=T)
# [1]  2 29

Но, как вы можете видеть, возвращаются два столбца: «i1-> h1» и «i1-> h10». Вот почему проблема возникает только тогда, когда вы получаете более 9 узлов. Итак, очевидно, что grep - неправильная функция здесь. Это то, что вызывает ошибку, которую вы видите.

Теперь как это исправить. Во-первых, нам нужна исправленная версия GarsonWeights. Итак, что я собираюсь сделать, это скопировать версию из caret и попытаться заменить grep на match.

gw <- caret:::GarsonWeights
body(gw)[[c(7,4,2,4,3,3,3)]] <- quote(match(label,nms))
body(gw)[[c(8,4,2,4,3,3,3)]] <- quote(match(label,nms))

Здесь я копаюсь в теле функции и меняю только один раздел. Сейчас этот метод исправления функции очень хрупкий и может меняться в разных версиях. Я тестировал это с помощью caret_6.0-21.

Вторая задача - заставить varImp использовать эту обновленную версию функции весов. К сожалению, мы не можем напрямую обновить тот, который находится в пространстве имен caret, и код по умолчанию явно использует его. Итак, что нам нужно сделать, это фактически изменить объект model, который сообщает varImp(), как запускать. Если вы посмотрите на model$modelInfo$varImp, вы увидите, где он звонит caret:::GarsonWeights. Нам просто нужно изменить это на нашу gw функцию. Мы можем сделать это с

body(model$modelInfo$varImp)[[c(2,3)]]<-quote(gw(object,...))

Я думаю, это должно сработать. Вам нужно будет повторно запустить каждую модель, которую вы получите при запуске train() с method="nnet".

Я предлагаю вам связаться с caret сопровождающим и сообщить об этой ошибке. Не стесняйтесь давать ссылку на этот ответ для полного описания.

person MrFlick    schedule 26.05.2014
comment
Ранее это было исправлено в разрабатываемой версии пакета. Вероятно, через неделю он появится на CRAN. - person topepo; 27.05.2014