我需要在通过插入符号的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时,似乎发生错误。如何解决?
答案 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
维护者并报告此错误。如需完整说明,请随时提供此答案的链接。