稳健回归中的MM估计

时间:2019-12-29 17:46:19

标签: r machine-learning regression robustness

我正在R中使用不同的线性回归模型。我使用了DATASET,它具有21263行和82列。

除了使用R函数lmrob的MM估计回归以外,所有回归模型都具有可接受的时间消耗。

我等待了10多个小时才能运行第一个for循环(#B块A),但它不起作用。所谓“无效”,是指两天后可能会给我输出。我使用较小的DATASET尝试了此代码,该response of get request using Requests library in python具有9568行,5列,并且在一分钟内即可运行。

我正在使用标准笔记本电脑。

我的分析步骤如下

上传和缩放数据集,然后使用k = 30的k倍拆分,因为我想计算k拆分内每个变量的系数方差。

能否请您提供任何指南?

wdbc = read.csv("train.csv") #critical_temp is the dependent varaible. 
wdbcc=as.data.frame(scale(wdbc)) # scaling the variables
### k-folds split ###
set.seed(12345)
k = 30
folds <- createFolds(wdbcc$critical_temp, k = k, list = TRUE, returnTrain = TRUE)

############ Start of MM Regression Model #################
#Block A
lmrob = list()
for (i in 1:k) {
    lmrob[[i]] = lmrob(critical_temp~ ., 
                       data = wdbcc[folds[[i]],],setting="KS2014")
}

#Block B
lmrob_coef = list()
lmrob_coef_var = list()

for(j in 1:(lmrob[[1]]$coefficients %>% length())){

    for(i in 1:k){

        lmrob_coef[[i]] = lmrob[[i]]$coefficients[j] 
        lmrob_coef_var[[j]] = lmrob_coef %>% unlist() %>% var()
    }

}

#Block C
lmrob_var = unlist(lmrob_coef_var)
lmrob_df = cbind(coefficients = lmrob[[1]]$coefficients %>% names() %>% as.data.frame()
                 , variance = lmrob_var %>% as.data.frame()) 
colnames(lmrob_df) = c("coefficients", "variance_lmrob")
#Block D
lmrob_var_sum = sum(lmrob_var)

1 个答案:

答案 0 :(得分:1)

不是答案,而是一些代码来帮助您自己进行测试。我没有在完整的数据集上运行lmrob(),但是下面显示的所有内容表明,模型的一个完整实现(所有观察值,所有预测变量)应在10岁左右的时间中运行约10-20分钟MacOS台式机],则可以推断出大约需要5个小时来进行30倍的交叉验证。 (看起来时间尺度比观测数的平方根差一点,并且甚至与对数尺度非线性地在对数尺度上 ...)您可以尝试以下代码查看计算机上的运行情况是否慢得多,并预测完成整个问题所需的时间。其他一般建议:

  • 您是否有可能内存不足?内存限制会使事情运行很多变慢
  • 如果问题仅在于事情太慢,如果可以访问多个核心,则可以轻松地在折叠中并行化(很可能不在笔记本电脑上这样做,否则会把它烧掉)
  • AWS和其他云服务可能非常有用

我设置了一个测试函数来记录lmrob()在您的数据集中的随机预测变量和观测值上运行所花费的时间。

提取数据,加载程序包:

unzip("superconduct.zip")
xx <- read.csv("train.csv")
library(robustbase)
library(ggplot2); theme_set(theme_bw())
library(cowplot)

定义用于计时lmrob运行的测试函数,以用于不同数量的观察值和预测值:

nc <- ncol(xx)  ## response vble is last column, "critical_temp"
test <- function(nobs=1000,npred=10,seed=NULL, ...) {
    if (!is.null(seed)) set.seed(seed)
    dd <- xx[sample(nrow(xx),size=nobs),
             c(sample(nc-1,size=npred),nc)]
    tt <- system.time(fit <- lmrob(critical_temp ~ ., data=dd, ...))
    tt[c("user.self","sys.self","elapsed")]
}    

t0 <- test()

这里的最小示例(1000个观察值,10个预测变量)非常快(0.2秒)。 这是我运行的基本循环:

res <- expand.grid(nobs=seq(1000,10000,by=1000), npred=seq(10,30,by=2))
res$user.self <- res$sys.self <- res$elapsed <- NA
for (i in seq(nrow(res))) {
    cat(res$nobs[i],res$npred[i],"\n")
    res[i,-(1:2)] <- test(res$nobs[i],res$npred[i],seed=101)
}

(如下图所示,我再次使用大量的观测值和预测变量进行了此操作,并使用rbind()将结果组合到单个数据框中。)我还尝试拟合线性模型来制作使用所有预测变量完成完整数据集所需的时间预测。 (作图[见下文]表明时间在观察次数上是对数-对数线性的,而在预测变量上则是非线性的...)

m1 <- lm(log10(elapsed)~poly(log10(npred),2)*log10(nobs), data=resc)
pp <- predict(m1, newdata=data.frame(npred=ncol(xx)-1,nobs=nrow(xx)),
              interval="confidence")  
10^pp  ## convert from log10(predicted seconds) to seconds

测试完整的数据集。

t_all <- test(nobs=nrow(xx),npred=ncol(xx)-1)

然后我意识到您正在使用setting = "KS2014"(如文档中所建议)而不是默认值:如以下比较所建议的那样,它至少慢了5倍:

test(nobs=10000,npred=30)
test(nobs=10000,npred=30,setting = "KS2014")

我用setting="KS2014"重新运行了上面的一些内容。对整个数据集进行预测建议运行时间约为700秒(CI从300到2000秒)-仍然远远没有您所建议的慢。

gg0 <- ggplot(resc2,aes(x=npred,y=elapsed,colour=nobs,linetype=setting))+
    geom_point()+geom_line(aes(group=interaction(nobs,setting)))+
    scale_x_log10()+scale_y_log10()
gg1 <- ggplot(resc2,aes(x=nobs,y=elapsed,colour=npred, linetype=setting))+
    geom_point()+geom_line(aes(group=interaction(npred,setting)))+
    scale_x_log10()+scale_y_log10()
plot_grid(gg0,gg1,nrow=1)
ggsave("lmrob_times.pdf")

enter image description here