Agregando resultados de execuções de modelos lineares R

16

Como a modelagem de regressão geralmente é mais "arte" do que ciência, muitas vezes me pego testando muitas iterações de uma estrutura de regressão. Quais são algumas maneiras eficientes de resumir as informações dessas várias execuções de modelo na tentativa de encontrar o "melhor" modelo? Uma abordagem que usei é colocar todos os modelos em uma lista e percorrer summary()essa lista, mas imagino que existem maneiras mais eficientes de comparar?

Código e modelos de amostra:

ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)

lm1 <- lm(weight ~ group)
lm2 <- lm(weight ~ group - 1)
lm3 <- lm(log(weight) ~ group - 1)

#Draw comparisions between models 1 - 3?

models <- list(lm1, lm2, lm3)

lapply(models, summary)
correr atrás
fonte
5
Soa um pouco como dados de dragagem para mim. O foco não deveria ser o que você considera plausivelmente um modelo apropriado, quais covariáveis, transformações etc. antes de começar a modelar. R não sabe que você fez todo esse ajuste de modelo para encontrar um bom modelo.
Reintegrar Monica - G. Simpson
3
@ Gavin - Eu posso ver isso ficando terrivelmente fora de tópico muito rapidamente, mas a resposta curta é não, não estou defendendo a dragagem de dados ou encontrando relações espúrias entre variáveis ​​aleatórias em um conjunto de dados. Considere um modelo de regressão que inclua renda. Não é razoável testar transformações na renda para ver seu impacto no modelo? Registro de receita, registro de receita em 10s de dólares, registro de receita em 100s ...? Mesmo que seja uma dragagem de dados - uma ferramenta de função / resumo que pode agregar a saída de muitas execuções de modelos ainda seria muito útil, não é?
Chase

Respostas:

17

Traçá-los!

http://svn.cluelessresearch.com/tables2graphs/longley.png

Ou, se necessário, use tabelas: O pacote apsrtable ou a mtablefunção no pacote memisc .

Usando mtable

 mtable123 <- mtable("Model 1"=lm1,"Model 2"=lm2,"Model 3"=lm3,
     summary.stats=c("sigma","R-squared","F","p","N"))

> mtable123

Calls:
Model 1: lm(formula = weight ~ group)
Model 2: lm(formula = weight ~ group - 1)
Model 3: lm(formula = log(weight) ~ group - 1)

=============================================
                 Model 1   Model 2   Model 3 
---------------------------------------------
(Intercept)      5.032***                    
                (0.220)                      
group: Trt/Ctl  -0.371                       
                (0.311)                      
group: Ctl                 5.032***  1.610***
                          (0.220)   (0.045)  
group: Trt                 4.661***  1.527***
                          (0.220)   (0.045)  
---------------------------------------------
sigma             0.696      0.696     0.143 
R-squared         0.073      0.982     0.993 
F                 1.419    485.051  1200.388 
p                 0.249      0.000     0.000 
N                20         20        20     
=============================================

Eduardo Leoni
fonte
1
@ Eduardo, +1, bom gráfico. Deve ser usado com cuidado, porém, quando a transformação diferente da variável dependente é usada em diferentes regressões.
Mvctas # 03/02
mpiktas, isso também é verdade em uma tabela. Os gráficos apenas o tornam mais compacto, à custa da precisão.
Eduardo Leoni
@ Eduardo, você pode compartilhar o código para gráficos?
suncoolsu
2
O código @suncoolsu R está disponível no primeiro link fornecido na resposta de @ Eduardo. He he, é grid, não lattice:)
chl
@ Eduardo - Obrigado pela resposta detalhada, que eu não conhecia memiscanteriormente, parece um pacote muito útil para se ter na aljava!
Chase
12

O seguinte não responde exatamente à pergunta. Pode dar algumas idéias, no entanto. Recentemente, fiz algo para avaliar o ajuste de vários modelos de regressão usando uma a quatro variáveis ​​independentes (a variável dependente estava na primeira coluna do quadro de dados df1).

# create the combinations of the 4 independent variables
library(foreach)
xcomb <- foreach(i=1:4, .combine=c) %do% {combn(names(df1)[-1], i, simplify=FALSE) }

# create formulas
formlist <- lapply(xcomb, function(l) formula(paste(names(df1)[1], paste(l, collapse="+"), sep="~")))

O conteúdo de as.character (formlist) foi

 [1] "price ~ sqft"                     "price ~ age"                     
 [3] "price ~ feats"                    "price ~ tax"                     
 [5] "price ~ sqft + age"               "price ~ sqft + feats"            
 [7] "price ~ sqft + tax"               "price ~ age + feats"             
 [9] "price ~ age + tax"                "price ~ feats + tax"             
[11] "price ~ sqft + age + feats"       "price ~ sqft + age + tax"        
[13] "price ~ sqft + feats + tax"       "price ~ age + feats + tax"       
[15] "price ~ sqft + age + feats + tax"

Então eu coletei alguns índices úteis

# R squared
models.r.sq <- sapply(formlist, function(i) summary(lm(i))$r.squared)
# adjusted R squared
models.adj.r.sq <- sapply(formlist, function(i) summary(lm(i))$adj.r.squared)
# MSEp
models.MSEp <- sapply(formlist, function(i) anova(lm(i))['Mean Sq']['Residuals',])

# Full model MSE
MSE <- anova(lm(formlist[[length(formlist)]]))['Mean Sq']['Residuals',]

# Mallow's Cp
models.Cp <- sapply(formlist, function(i) {
SSEp <- anova(lm(i))['Sum Sq']['Residuals',]
mod.mat <- model.matrix(lm(i))
n <- dim(mod.mat)[1]
p <- dim(mod.mat)[2]
c(p,SSEp / MSE - (n - 2*p))
})

df.model.eval <- data.frame(model=as.character(formlist), p=models.Cp[1,],
r.sq=models.r.sq, adj.r.sq=models.adj.r.sq, MSEp=models.MSEp, Cp=models.Cp[2,])

O quadro de dados final foi

                      model p       r.sq   adj.r.sq      MSEp         Cp
1                price~sqft 2 0.71390776 0.71139818  42044.46  49.260620
2                 price~age 2 0.02847477 0.01352823 162541.84 292.462049
3               price~feats 2 0.17858447 0.17137907 120716.21 351.004441
4                 price~tax 2 0.76641940 0.76417343  35035.94  20.591913
5            price~sqft+age 3 0.80348960 0.79734865  33391.05  10.899307
6          price~sqft+feats 3 0.72245824 0.71754599  41148.82  46.441002
7            price~sqft+tax 3 0.79837622 0.79446120  30536.19   5.819766
8           price~age+feats 3 0.16146638 0.13526220 142483.62 245.803026
9             price~age+tax 3 0.77886989 0.77173666  37884.71  20.026075
10          price~feats+tax 3 0.76941242 0.76493500  34922.80  21.021060
11     price~sqft+age+feats 4 0.80454221 0.79523470  33739.36  12.514175
12       price~sqft+age+tax 4 0.82977846 0.82140691  29640.97   3.832692
13     price~sqft+feats+tax 4 0.80068220 0.79481991  30482.90   6.609502
14      price~age+feats+tax 4 0.79186713 0.78163109  36242.54  17.381201
15 price~sqft+age+feats+tax 5 0.83210849 0.82091573  29722.50   5.000000

Finalmente, um gráfico de Cp (usando a biblioteca wle)

George Dontas
fonte