2012-08-07 79 views
0

我已经构建了一个基本函数来从3个模型中提取AIC和BIC值,我对几个变量感兴趣。但是,当它运行时,我的电脑经常停下来,并说它不能为一个矢量分配200MB(我使用的是大型数据集 - 超过500K个案例,是的,我已将内存限制增加到最大 - 4000)。改进R函数内的循环

我实际上设法运行它,如果我一次选择几个变量。我感兴趣的是实际上一次运行该功能,但也改善了我的功能代码,以便在运行它之前不必删除其他所有内容,并且可能不需要等待30分钟。我很可能会使用修正后的AIC和BIC公式并添加其他内容,所以我宁愿保留AIC和BIC矢量化,不要切换到其他逻辑回归函数。我玩过它并添加了像rm(model1)这样的东西,但它可能没有什么区别。你能否建议解决内存分配问题的代码,并可能加快这个功能?

非常感谢

功能:

myF<-function(mydata,TotScore,group){ 
    BIC2<-BIC1<-BIC0<-AIC2<-AIC1<-AIC0<-rep(NA,length(ncol(mydata))) 
    for (i in (1:ncol(mydata))){ 
    M0<-glm(mydata[,i] ~ TotScore,family=binomial,data=mydata,x=F,y=F,model=F) 
    AIC0[i]<-extractAIC(M0)[2] 
    BIC0[i]<-extractAIC(M0,k=log(length(M0$fitted.values)))[2] 
    rm(M0) 
    M1<-glm(mydata[,i] ~ TotScore+group,family=binomial,data=mydata,x=F,y=F,model=F) 
    AIC1[i]<-extractAIC(M1)[2] 
    BIC1[i]<-extractAIC(M1,k=log(length(M1$fitted.values)))[2] 
    rm(M1) 
    M2<-glm(mydata[,i] ~ TotScore+group+TotScore*group,family=binomial,data=mydata,x=F,y=F,model=F) 
    AIC2[i]<-extractAIC(M2)[2] 
    BIC2[i]<-extractAIC(M2,k=log(length(M2$fitted.values)))[2] 
    rm(M2) 
    } 
    Results<-cbind(AIC0,AIC1,AIC2,BIC0,BIC1,BIC2) 
    rownames(Results)<-names(mydata) 
    return(Results) 
} 

附:该模型可以用

##Random dataset example 
v1<-sample(0:1, 500000, replace=TRUE, prob=c(.80,.20)) 
v2<-sample(0:1, 500000, replace=TRUE, prob=c(.85,.15)) 
v3<-sample(0:1, 500000, replace=TRUE, prob=c(.95,.05)) 
mydata<-as.data.frame(cbind(v1,v2,v3)) 
TotScore=rowSums(mydata) 
group<-(rep (1:5,100000)) 
myF(mydata,TotScore,group) 
+3

欢迎StackOverflow的损失。也许如果你做了一个[可重现的例子](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)来演示你的问题/问题,人们会发现它更容易回答。 – Andrie 2012-08-07 12:55:13

+0

道歉,附有小数据集示例。 – 2012-08-07 13:11:13

回答

0
library(difR) 
data(verbal) 
verbal$TotScore <- rowSums(verbal[, c(1:24)]) 
verbal$group <- with(verbal, factor(Gender):factor(Anger > 20)) 

myFun <- function(Y, dataset){ 
    output <- rep(NA, 6) 
    names(output) <- paste(rep(c("AIC", "BIC"), 3), rep(0:2, each = 2), sep = "") 
    m <- glm(as.formula(paste(Y, "~ TotScore")), data = dataset, family = binomial, 
     model = FALSE, x = FALSE, y = FALSE) 
    output[1:2] <- c(AIC(m), BIC(m)) 
    m <- glm(as.formula(paste(Y, "~ TotScore + group")), data = dataset, 
    family = binomial, model = FALSE, x = FALSE, y = FALSE) 
    output[3:4] <- c(AIC(m), BIC(m)) 
    m <- glm(as.formula(paste(Y, "~ TotScore * group")), data = dataset, 
     family = binomial, model = FALSE, x = FALSE, y = FALSE) 
    output[5:6] <- c(AIC(m), BIC(m)) 
    output 
} 

sapply(colnames(verbal)[1:2], myFun, dataset = verbal) 
+0

我无法显示任何速度收益(我做了类似的事情,但并未因此发布)。您能否详细说明您的解决方案如何解决内存或速度问题? – 2012-08-07 13:41:14

+0

你可能是对的,但这是我的错,我应该给你一个更大的数据集来尝试,以便测试大小和时间。我现在修改了这个问题(参见上文)。不幸的是蒂埃里的建议仍然让我的电脑失速,但是感谢提高功能。 – 2012-08-07 14:05:45

2

好的事审判有关离散预测二项式数据是可以聚合数据没有信息

set.seed(12345) 
v1<-sample(0:1, 500000, replace=TRUE, prob=c(.80,.20)) 
v2<-sample(0:1, 500000, replace=TRUE, prob=c(.85,.15)) 
v3<-sample(0:1, 500000, replace=TRUE, prob=c(.95,.05)) 
mydata<-as.data.frame(cbind(v1,v2,v3)) 
mydata$TotScore <- rowSums(mydata) 
mydata$group <- rep (1:5,100000) 

library(reshape) 
myFun2 <- function(Y, dataset){ 
    tmp <- as.data.frame(table(TotScore = dataset$TotScore, group = dataset$group, Response = dataset[, Y])) 
    levels(tmp$Response) <- c("Failure", "Succes") 
    tmp <- cast(TotScore + group ~ Response, data = tmp, value = "Freq") 
    tmp$TotScore <- as.numeric(levels(tmp$TotScore))[tmp$TotScore] 
    output <- rep(NA, 6) 
    names(output) <- paste(rep(c("AIC", "BIC"), 3), rep(0:2, each = 2), sep = "") 
    m <- glm(cbind(Succes, Failure) ~ TotScore, data = tmp, family = binomial, 
      model = FALSE, x = FALSE, y = FALSE) 
    output[1:2] <- c(AIC(m), BIC(m)) 
    m <- glm(cbind(Succes, Failure) ~ TotScore + group, data = tmp, family = binomial, 
      model = FALSE, x = FALSE, y = FALSE) 
    output[3:4] <- c(AIC(m), BIC(m)) 
    m <- glm(cbind(Succes, Failure) ~ TotScore * group, data = tmp, family = binomial, 
      model = FALSE, x = FALSE, y = FALSE) 
    output[5:6] <- c(AIC(m), BIC(m)) 
    output 
} 


system.time({ 
    sapply(colnames(mydata)[1:3], myFun, dataset = mydata) 
}) 
    user system elapsed 
    3.10 0.06 3.15 
+0

亲爱的蒂埃里,谢谢你的所有努力。将数据减少到表格格式确实可以在时间和内存方面大大改善。然而,减少(表格)数据的AIC和BIC值与完整数据集的数据并不相同,所以我认为它们与其他分析,拇指规则等没有可比性。如果您尝试使用BIC()函数在桌面数据和正常数据上你会明白我的意思。 BIC是特别的(“坏”),因为差异与完整表格数据和表格数据并不相同(而模型之间的AIC差异是相同的,因为它不包括样本大小)。 – 2012-08-08 10:07:54