使用单个命令运行具有不同参数的函数列表
Posted
技术标签:
【中文标题】使用单个命令运行具有不同参数的函数列表【英文标题】:Running a list of functions with different params with a single command 【发布时间】:2013-03-19 10:09:28 【问题描述】:我希望在相同数据上测试不同回归/分类算法(即 svm、nnet、rpart、randomForest、naiveBayes 等)的结果,看看哪个效果更好。但我需要让我的代码尽可能短而干净。为了测试所有算法,我想使用包 multicore
的单个 mclapply()
调用来运行它们:
invisible(lapply(c("party","nnet","caret","klaR","randomForest","e1071","rpart",
"multicore"), require, character.only = T))
algorithms <- c(knn3, NaiveBayes, nnet, ctree, randomForest, svm, naiveBayes, rpart)
data(iris)
model <- mclapply(algorithms, function(alg) alg(Species ~ ., iris))
问题是某些算法需要额外的参数,即nnet()
需要设置参数size
。当然,这可以通过几个if,else
命令来解决,但是有没有更简单的解决方案?
【问题讨论】:
您可以尝试用包装器替换nnet
:algorithms[[3]] <- function(...) nnet(...,size=your_size)
【参考方案1】:
您可以做的一件事是用部分函数替换 algorithms
中需要额外参数的那些,例如
algorithms <- c(knn3, ctree, function(...) nnet(..., size=2))
【讨论】:
等效地,使用functional
包,您可以使用Curry(nnet, size=2)
作为函数。
这是一个很好的解决方案。我在想我们是否可以轻松地将算法名称分配给mclapply()
结果中的names()
,而无需额外的变量定义:即alg.names <- c("knn3",...
@BrianDiggs 啊哈,Curry
!我知道这在某个地方。
@Ali 原子向量接受名称,因此您可以使用 c(knn3=knn3, nnet=function(...) nnet(..., 2), etc.)
。我不记得mclapply
是否会保留这些名称,但无论如何你都可以使用names(model) <- names(algorithms)
。【参考方案2】:
包multicore
似乎不适用于Windows,但这里有一个方法,以普通lapply
的简单示例:
# names of the functions as strings
algorithms <- c("lm", "glm")
# arguments for each function (empty list for those which do not need any)
arguments <- list(lm=list(model=FALSE),glm=list(family = gaussian),lm=list())
# Use lapply with do.call
output<-lapply(1:length(algorithms), function(i) do.call(what=algorithms[i],
args=c(list(formula=y ~ .,data=freeny),arguments[[i]])))
names(output)<-algorithms #Add names to output
现在列表output
包含每个算法的输出。请注意,乍一看,这个例子的输出(通过命令output$lm
)看起来有点糟糕,因为lm
和glm
的打印显示了函数调用和摘要,这里的函数调用很长。
编辑:一些小的调整。
【讨论】:
以上是关于使用单个命令运行具有不同参数的函数列表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 iText 列表将具有不同权重的文本添加到单个 ListItem
使用具有与 Windows 中的 & 一样的参数的子进程运行命令
如何使用具有不同端口的单个 ssl 证书运行节点 js 和 apache?