Agregowanie wyników z modeli liniowych przebiega R

16

Ponieważ modelowanie regresji jest często bardziej „sztuką” niż nauką, często testuję wiele iteracji struktury regresji. Jakie są skuteczne sposoby podsumowania informacji z tych wielu uruchomień modelu, próbując znaleźć „najlepszy” model? Jednym z zastosowanych przeze mnie sposobów jest umieszczenie wszystkich modeli na liście i przeglądanie summary()tej listy, ale wyobrażam sobie, że istnieją bardziej wydajne sposoby porównywania?

Przykładowy kod i modele:

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)
Gonić
źródło
5
Brzmi trochę jak pogłębianie danych. Czy nie powinieneś skupiać się na tym, co według ciebie jest właściwym modelem, na zmiennychach towarzyszących, transformacjach itp. Przed rozpoczęciem modelowania. R nie wie, że dopasowałeś cały model, by znaleźć dobry model.
Przywróć Monikę - G. Simpson
3
@Gavin - Widzę, że bardzo szybko staje się to strasznie nie na temat, ale krótka odpowiedź brzmi: nie, nie popieram pogłębiania danych ani znajdowania fałszywych związków między losowymi zmiennymi w zbiorze danych. Rozważ model regresji obejmujący dochód. Czy nie jest uzasadnione testowanie przekształceń dochodów, aby zobaczyć ich wpływ na model? Dziennik dochodów, dziennik dochodów w 10s dolarów, dziennik dochodów w 100s ... Nawet jeśli jest to pogłębianie danych - narzędzie funkcji / podsumowania, które może agregować dane wyjściowe z wielu uruchomień modeli, byłoby nadal bardzo pomocne, nie?
Chase

Odpowiedzi:

17

Wykreśl je!

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

Lub, jeśli musisz, użyj tabel: Pakiet apsrtable lub mtablefunkcja w pakiecie memisc .

Za pomocą 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
źródło
1
@Eduardo, +1, ładny wykres. Należy jednak zachować ostrożność, gdy w różnych regresjach stosowana jest inna transformacja zmiennej zależnej.
mpiktas
mpiktas, dotyczy to również stołu. Wykresy sprawiają, że jest bardziej kompaktowy, kosztem precyzji.
Eduardo Leoni
@Eduardo, czy możesz udostępnić kod dla wykresów?
suncoolsu
2
Kod @ suncoolsu R jest dostępny pod pierwszym linkiem podanym w odpowiedzi na @ Eduardo. On he, to gridnie jest lattice:)
chl
@Eduardo - Dziękuję za szczegółową odpowiedź, której memiscwcześniej nie zdawałem sobie sprawy , wygląda na bardzo poręczny pakiet, który można mieć w kołczanie!
Chase
12

Poniższe nie odpowiada dokładnie na pytanie. Może jednak dać ci kilka pomysłów. Jest to coś, co ostatnio zrobiłem, aby ocenić dopasowanie kilku modeli regresji przy użyciu od jednej do czterech zmiennych niezależnych (zmienna zależna była w pierwszej kolumnie ramki danych 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="~")))

Zawartość as.character (formlist) to

 [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"

Potem zebrałem kilka przydatnych wskaźników

# 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,])

Ostateczna ramka danych to

                      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

Na koniec wykres Cp (przy użyciu biblioteki wle)

George Dontas
źródło