将varImp用于nnet神经网络时出错

时间:2014-05-26 14:35:14

标签: r r-caret nnet

我需要在通过插入符号的nnet方法创建的神经网络模型上使用varImp函数。

代码:

#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时,似乎发生错误。如何解决?

1 个答案:

答案 0 :(得分: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个隐藏节点。该函数试图通过点击&#34; i1-&gt; h1&#34;来找到输入1和隐藏注释1的系数。与

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

但正如您所看到的,返回了两列,&#34; i1-&gt; h1&#34;和&#34; i1-&gt; h10&#34;。这就是为什么只有当你获得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维护者并报告此错误。如需完整说明,请随时提供此答案的链接。