使基于 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 调用转换为并行版本,例如 sfLapplyparLapplymclapply 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"’

这似乎不是严重错误,但正如我所说,我不准备建议如何修复它。