it-swarm.com.de

Schrittweise Regression mit p-Werten zum Löschen von Variablen mit nicht signifikanten p-Werten

Ich möchte eine schrittweise lineare Regression unter Verwendung von p-Werten als Auswahlkriterium durchführen, z. B .: Bei jedem Schritt werden Variablen gelöscht, die den höchsten Wert haben, dh die unbedeutendsten p-Werte definiert durch eine Schwelle alpha.

Ich bin mir völlig bewusst, dass ich stattdessen die AIC (z. B. Befehl step oder stepAIC) oder ein anderes Kriterium verwenden sollte, aber mein Chef hat kein Verständnis für Statistiken und besteht nicht auf der Verwendung von p-Werten.

Wenn nötig, könnte ich meine eigene Routine programmieren, aber ich frage mich, ob es eine bereits implementierte Version davon gibt.

28
DainisZ

Zeigen Sie Ihrem Chef Folgendes:

set.seed(100)
x1 <- runif(100,0,1)
x2 <- as.factor(sample(letters[1:3],100,replace=T))

y <- x1+x1*(x2=="a")+2*(x2=="b")+rnorm(100)
summary(lm(y~x1*x2))

Was gibt:

            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -0.1525     0.3066  -0.498  0.61995    
x1            1.8693     0.6045   3.092  0.00261 ** 
x2b           2.5149     0.4334   5.802 8.77e-08 ***
x2c           0.3089     0.4475   0.690  0.49180    
x1:x2b       -1.1239     0.8022  -1.401  0.16451    
x1:x2c       -1.0497     0.7873  -1.333  0.18566    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Nun, basierend auf den p-Werten, würden Sie welche ausschließen? x2 ist am signifikantesten und gleichzeitig am wenigsten signifikant.


Bearbeiten: Zur Verdeutlichung: Dieses Beispiel ist nicht das beste, wie in den Kommentaren angegeben. Das Verfahren in Stata und SPSS basiert auf AFAIK und basiert nicht auf den p-Werten des T-Tests der Koeffizienten, sondern auf dem F-Test nach Entfernung einer der Variablen. 

Ich habe eine Funktion, die genau das tut. Dies ist eine Auswahl für den "p-Wert", jedoch nicht für den T-Test der Koeffizienten oder der Anova-Ergebnisse. Fühlen Sie sich frei, es zu verwenden, wenn es Ihnen nützlich erscheint.

#####################################
# Automated model selection
# Author      : Joris Meys
# version     : 0.2
# date        : 12/01/09
#####################################
#CHANGE LOG
# 0.2   : check for empty scopevar vector
#####################################

# Function has.interaction checks whether x is part of a term in terms
# terms is a vector with names of terms from a model
has.interaction <- function(x,terms){
    out <- sapply(terms,function(i){
        sum(1-(strsplit(x,":")[[1]] %in% strsplit(i,":")[[1]]))==0
    })
    return(sum(out)>0)
}

# Function Model.select
# model is the lm object of the full model
# keep is a list of model terms to keep in the model at all times
# sig gives the significance for removal of a variable. Can be 0.1 too (see SPSS)
# verbose=T gives the F-tests, dropped var and resulting model after 
model.select <- function(model,keep,sig=0.05,verbose=F){
      counter=1
      # check input
      if(!is(model,"lm")) stop(paste(deparse(substitute(model)),"is not an lm object\n"))
      # calculate scope for drop1 function
      terms <- attr(model$terms,"term.labels")
      if(missing(keep)){ # set scopevars to all terms
          scopevars <- terms
      } else{            # select the scopevars if keep is used
          index <- match(keep,terms)
          # check if all is specified correctly
          if(sum(is.na(index))>0){
              novar <- keep[is.na(index)]
              warning(paste(
                  c(novar,"cannot be found in the model",
                  "\nThese terms are ignored in the model selection."),
                  collapse=" "))
              index <- as.vector(na.omit(index))
          }
          scopevars <- terms[-index]
      }

      # Backward model selection : 

      while(T){
          # extract the test statistics from drop.
          test <- drop1(model, scope=scopevars,test="F")

          if(verbose){
              cat("-------------STEP ",counter,"-------------\n",
              "The drop statistics : \n")
              print(test)
          }

          pval <- test[,dim(test)[2]]

          names(pval) <- rownames(test)
          pval <- sort(pval,decreasing=T)

          if(sum(is.na(pval))>0) stop(paste("Model",
              deparse(substitute(model)),"is invalid. Check if all coefficients are estimated."))

          # check if all significant
          if(pval[1]<sig) break # stops the loop if all remaining vars are sign.

          # select var to drop
          i=1
          while(T){
              dropvar <- names(pval)[i]
              check.terms <- terms[-match(dropvar,terms)]
              x <- has.interaction(dropvar,check.terms)
              if(x){i=i+1;next} else {break}              
          } # end while(T) drop var

          if(pval[i]<sig) break # stops the loop if var to remove is significant

          if(verbose){
             cat("\n--------\nTerm dropped in step",counter,":",dropvar,"\n--------\n\n")              
          }

          #update terms, scopevars and model
          scopevars <- scopevars[-match(dropvar,scopevars)]
          terms <- terms[-match(dropvar,terms)]

          formul <- as.formula(paste(".~.-",dropvar))
          model <- update(model,formul)

          if(length(scopevars)==0) {
              warning("All variables are thrown out of the model.\n",
              "No model could be specified.")
              return()
          }
          counter=counter+1
      } # end while(T) main loop
      return(model)
}
28
Joris Meys

Warum versuchen Sie nicht, die Funktion step() zu verwenden, die Ihre Testmethode angibt?

Zum Beispiel geben Sie zur Rückwärtseliminierung nur einen Befehl ein:

step(FullModel, direction = "backward", test = "F")

und für die schrittweise Auswahl einfach:

step(FullModel, direction = "both", test = "F")

Dies kann sowohl die AIC-Werte als auch die F- und P-Werte anzeigen.

17
leonie

Hier ist ein Beispiel. Beginnen Sie mit dem kompliziertesten Modell: Dies beinhaltet Interaktionen zwischen allen drei erklärenden Variablen.

model1 <-lm (ozone~temp*wind*rad)
summary(model1)

Coefficients:
Estimate Std.Error t value Pr(>t)
(Intercept) 5.683e+02 2.073e+02 2.741 0.00725 **
temp          -1.076e+01 4.303e+00 -2.501 0.01401 *
wind          -3.237e+01 1.173e+01 -2.760 0.00687 **
rad           -3.117e-01 5.585e-01 -0.558 0.57799
temp:wind      2.377e-01 1.367e-01 1.739 0.08519   
temp:rad       8.402e-03 7.512e-03 1.119 0.26602
wind:rad       2.054e-02 4.892e-02 0.420 0.47552
temp:wind:rad -4.324e-04 6.595e-04 -0.656 0.51358

Die Dreiwege-Interaktion ist eindeutig nicht signifikant. So entfernen Sie es, um mit der Modellvereinfachung zu beginnen:

model2 <- update(model1,~. - temp:wind:rad)
summary(model2)

Abhängig von den Ergebnissen können Sie Ihr Modell weiter vereinfachen:

model3 <- update(model2,~. - temp:rad)
summary(model3)
...

Alternativ können Sie die automatische Modellvereinfachungsfunktion step verwenden, um zu sehen, wie gut es geht:

model_step <- step(model1)
10
George Dontas

Wenn Sie nur versuchen, das beste Vorhersagemodell zu erhalten, ist es vielleicht nicht wichtig, aber für alles andere sollten Sie sich nicht mit dieser Art von Modellauswahl beschäftigen. Es ist falsch.

Verwenden Sie eine Schrumpfungsmethode, z. B. die Rückgratregression (z. B. in Paket MASS in lm.ridge()) oder das Lasso oder das elastische Netz (eine Kombination aus Rand- und Lasso-Einschränkungen). Von diesen wird nur das Lasso und das elastische Netz eine Art Modellauswahl treffen, d. H. Die Koeffizienten einiger Kovariaten auf Null setzen.

Weitere Informationen finden Sie im Abschnitt Regularisierung und Schrumpfen der Taskansicht Machine Learning in CRAN.

7
Gavin Simpson

Paket rms: Regressionsmodellierungsstrategien hat fastbw(), die genau das macht, was Sie brauchen. Es gibt sogar einen Parameter, um von der AIC zur p-Wert-basierten Eliminierung zu wechseln.

7
Chris

Wie von Gavin Simpson erwähnt, kann die Funktion fastbw aus dem Paket rms verwendet werden, um Variablen mit dem p-Wert auszuwählen. Bellow ist ein Beispiel am Beispiel von George Dontas. Verwenden Sie die Option rule='p', um p-Wert-Kriterien auszuwählen.

require(rms)
model1 <- ols(Ozone ~ Temp * Wind * Solar.R, data=airquality)
model2 <- fastbw(fit=model1, rule="p", sls=0.05)
model2
0
fhernanb