查找R中具有最低AIC的模型(从for循环返回)

时间:2017-07-22 12:23:21

标签: r for-loop glm model-comparison

我正在尝试找到AIC最低的模型。模型从两个for循环返回,这些循环可以实现列的组合。我无法使具有最低AIC的函数返回模型。下面的代码演示了我遇到的问题:

getFirst()

有什么建议吗?谢谢!

3 个答案:

答案 0 :(得分:0)

我用矢量化替代品替换了你的for循环

library(tidyverse)
library(iterators)
# Column names you want to use in glm model, saved as list
whichcols <- Reduce("c", map(1:length(mod_headers), ~lapply(iter(combn(mod_headers,.x), by="col"),function(y) c(y))))

# glm model results using selected column names, saved as list
models <- map(1:length(whichcols), ~glm(Species ~., data=data[c(whichcols[[.x]], "Species")], family = binomial(link = "logit")))

# selects model with lowest AIC
best <- models[[which.min(sapply(1:length(models),function(x)AIC(models[[x]])))]]

输出

Call:  glm(formula = Species ~ ., family = binomial(link = "logit"), 
data = data[c(whichcols[[.x]], "Species")])

Coefficients:
 (Intercept)  Petal.Length  
       55.40        -17.17  

Degrees of Freedom: 99 Total (i.e. Null);  98 Residual
Null Deviance:      138.6 
Residual Deviance: 1.208e-09    AIC: 4

答案 1 :(得分:0)

使用循环,只需将所有模型放在一个列表中。 然后计算所有这些模型的AIC。 最后返回具有最小AIC的模型。

f <- function(mod_headers) {

  models <- list()
  k <- 1
  for (i in 1:length(mod_headers)) {
    tab <- combn(mod_headers, i)
    for(j in 1:ncol(tab)) {
      mod_tab_new <- c(tab[, j], "Species")
      models[[k]] <- glm(Species ~ ., data = data[mod_tab_new], 
                         family = binomial(link = "logit"))
      k <- k + 1
    }
  }

  models[[which.min(sapply(models, AIC))]]
}

答案 2 :(得分:0)

glm()使用迭代重新加权最小二乘算法。算法在收敛之前达到最大迭代次数 - 在您的情况下更改此参数有用:

 glm(Species ~., data=data[mod_tab_new], family = binomial(link = "logit"), control = list(maxit = 50))

使用which还有另一个问题,在每个模型适合与目前为止最低的AIC进行比较后,我用if替换了它。但是,我认为有比这种for-loop方法更好的解决方案。

f <- function(mod_headers){
  lowest_aic <- Inf     # added
  best_model <- NULL    # added

  for(i in 1:length(mod_headers)){
    tab <- combn(mod_headers,i)
    for(j in 1:ncol(tab)){
      tab_new <- tab[, j]
      mod_tab_new <- c(tab_new, "Species")
      model <- glm(Species ~., data=data[mod_tab_new], family = binomial(link = "logit"), control = list(maxit = 50))
      if(AIC(model) < lowest_aic){ # added
        lowest_aic <- AIC(model)   # added
        best_model <- model        # added
      }
    }
  }
  return(best_model)
}