使基于 kernlab 函数 运行 的程序更快
Make program based on kernlab function run faster
对于一个范围,我想确定分布发生变化的地方和该值最大的地方。目前,我正在对 范围内的每个值 使用内核最大差异测试,我在该值前后取 200 个值,然后提取 mmd 统计量最大的位置。但这在 R 中计算非常密集。请注意,我正在使用 kernlab 来计算 kmmd。我想知道是否有办法更快地做到这一点?或者如果您有任何建议。任何帮助将不胜感激。
我的代码是:
cvg<-seq(1,2000)
cvg<-cvg^3-2*cvg^2+5*cvg
myRange<-seq(400:(length(cvg)-400))
kernel<-"splinedot"
cvg[201:(length(cvg)-200)]->cvg
myRange<-seq(400:(length(cvg)-400))
lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel)))->kmm.ls
as.data.frame(as.matrix(kmm.ls))->kmm.ls
lapply(kmm.ls, function(x) which.max(mmdstats(x)))->store.max
我声明我不是该主题的专家 kernlab
因此我无法判断您分析的正确性或改进您的代码。
但是,我建议您将 lapply
调用转换为并行版本,例如 sfLapply
、parLapply
、mclapply
future_lapply
ecc。
在这里,我 post 一个来自 snowfall
包的 sfLapply
的例子(在我看来这真的很简单):
#your original lapply call took 500 seconds on my PC
system.time(kmm.ls <- lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1):
(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel))))
library(kernlab)
library(snowfall)
sfInit(parallel=TRUE,cpus = parallel::detectCores()-1)
# Load the required packages inside the cluster
sfLibrary(kernlab)
#export all variable in all the cluster
sfExportAll()
# Run parallelized lapply with custom function
#sfLapply took 22 second on my 48 cores PC
system.time(kmm.ls <- sfLapply(myRange, function(x)
mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])),
kernel=kernel))))
#stop cluster
sfStop()
这是一个仅对您的代码进行第一次 lapply
调用的示例,但同样的想法可以应用于第二次调用(当我尝试 运行 您的代码时,第二次 lapply
打电话给我一个错误)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘mmdstats’ for signature ‘"list"’
这似乎不是严重错误,但正如我所说,我不准备建议如何修复它。
对于一个范围,我想确定分布发生变化的地方和该值最大的地方。目前,我正在对 范围内的每个值 使用内核最大差异测试,我在该值前后取 200 个值,然后提取 mmd 统计量最大的位置。但这在 R 中计算非常密集。请注意,我正在使用 kernlab 来计算 kmmd。我想知道是否有办法更快地做到这一点?或者如果您有任何建议。任何帮助将不胜感激。
我的代码是:
cvg<-seq(1,2000)
cvg<-cvg^3-2*cvg^2+5*cvg
myRange<-seq(400:(length(cvg)-400))
kernel<-"splinedot"
cvg[201:(length(cvg)-200)]->cvg
myRange<-seq(400:(length(cvg)-400))
lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel)))->kmm.ls
as.data.frame(as.matrix(kmm.ls))->kmm.ls
lapply(kmm.ls, function(x) which.max(mmdstats(x)))->store.max
我声明我不是该主题的专家 kernlab
因此我无法判断您分析的正确性或改进您的代码。
但是,我建议您将 lapply
调用转换为并行版本,例如 sfLapply
、parLapply
、mclapply
future_lapply
ecc。
在这里,我 post 一个来自 snowfall
包的 sfLapply
的例子(在我看来这真的很简单):
#your original lapply call took 500 seconds on my PC
system.time(kmm.ls <- lapply(myRange, function(x) mmdstats(kmmd((as.matrix(cvg[(x+1):
(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])), kernel=kernel))))
library(kernlab)
library(snowfall)
sfInit(parallel=TRUE,cpus = parallel::detectCores()-1)
# Load the required packages inside the cluster
sfLibrary(kernlab)
#export all variable in all the cluster
sfExportAll()
# Run parallelized lapply with custom function
#sfLapply took 22 second on my 48 cores PC
system.time(kmm.ls <- sfLapply(myRange, function(x)
mmdstats(kmmd((as.matrix(cvg[(x+1):(x+400)])), (as.matrix(cvg[(x+801):(x+1200)])),
kernel=kernel))))
#stop cluster
sfStop()
这是一个仅对您的代码进行第一次 lapply
调用的示例,但同样的想法可以应用于第二次调用(当我尝试 运行 您的代码时,第二次 lapply
打电话给我一个错误)
Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘mmdstats’ for signature ‘"list"’
这似乎不是严重错误,但正如我所说,我不准备建议如何修复它。