C'è un modo per usare la validazione incrociata per fare la selezione di variabili / caratteristiche in R?


10

Ho un set di dati con circa 70 variabili che vorrei ridurre. Quello che sto cercando di fare è usare CV per trovare le variabili più utili nel modo seguente.

1) Seleziona in modo casuale diciamo 20 variabili.

2) Utilizzare stepwise/ LASSO/ lars/ etc per scegliere le variabili più importanti.

3) Ripeti ~ 50x e vedi quali variabili sono selezionate (non eliminate) più frequentemente.

Questo è in linea con quello che randomForestfarebbe, ma il rfVarSelpacchetto sembra funzionare solo per fattori / classificazione e ho bisogno di prevedere una variabile dipendente continua.

Sto usando R, quindi qualsiasi suggerimento sarebbe idealmente implementato lì.


Tutte le funzionalità sono importanti? Quanti campioni hai? Se capisco correttamente il problema, puoi provare a fare una variante del potenziamento: seleziona ripetutamente un sottoinsieme di campioni e adatta tutte le variabili a loro e vedi quali pop-up più spesso.
Ofelia,

1
Penso che è improbabile che la tua procedura migliori su LASSO, le cui implementazioni in R (ad es. Glmnet e penalizzate) utilizzano per impostazione predefinita la convalida incrociata per trovare il parametro di regolarizzazione "ottimale". Una cosa che potresti considerare è ripetere la ricerca LASSO per questo parametro più volte per far fronte alla varianza potenzialmente grande della convalida incrociata (CV ripetuto). Ovviamente, nessun algoritmo può battere le tue conoscenze precedenti specifiche della materia.
miura,

Risposte:


9

Credo che ciò che descrivi sia già implementato nel caretpacchetto. Guarda la rfefunzione o la vignetta qui: http://cran.r-project.org/web/packages/caret/vignettes/caretSelection.pdf

Ora, detto questo, perché è necessario ridurre il numero di funzionalità? Da 70 a 20 non è in realtà un calo dell'ordine di grandezza. Penserei che avresti bisogno di più di 70 funzionalità prima di avere una ferma convinzione che alcune funzionalità davvero e veramente non contano. Ma poi di nuovo, ecco dove arriva un priore soggettivo, suppongo.


5

Non vi è alcun motivo per cui la frequenza di selezione delle variabili fornisca informazioni che non si ottengono già dall'apparente importanza delle variabili nel modello iniziale. Questo è essenzialmente un replay del significato statistico iniziale. stai anche aggiungendo un nuovo livello di arbitrarietà quando cerchi di decidere un limite per la frequenza di selezione. Il ricampionamento della selezione delle variabili è gravemente danneggiato dalla collinearità oltre agli altri problemi.


2

Ho rivisto la mia risposta da prima di oggi. Ora ho generato alcuni dati di esempio su cui eseguire il codice. Altri hanno giustamente suggerito di esaminare l'uso del pacchetto di assistenza, che sono d'accordo. In alcuni casi, tuttavia, potrebbe essere necessario scrivere il proprio codice. Di seguito ho tentato di dimostrare come utilizzare la funzione sample () in R per assegnare casualmente le osservazioni alle pieghe di validazione incrociata. Uso anche i loop per eseguire la preselezione variabile (usando la regressione lineare univariata con un valore di cut-off lenente di 0,1) e la costruzione del modello (usando la regressione graduale) sui dieci set di allenamento. È quindi possibile scrivere il proprio codice per applicare i modelli risultanti alle pieghe di convalida. Spero che sia di aiuto!

################################################################################
## Load the MASS library, which contains the "stepAIC" function for performing
## stepwise regression, to be used later in this script
library(MASS)
################################################################################


################################################################################
## Generate example data, with 100 observations (rows), 70 variables (columns 1
## to 70), and a continuous dependent variable (column 71)
Data <- NULL
Data <- as.data.frame(Data)

for (i in 1:71) {
for (j in 1:100) {
Data[j,i]  <- rnorm(1) }}

names(Data)[71] <- "Dependent"
################################################################################


################################################################################
## Create ten folds for cross-validation. Each observation in your data will
## randomly be assigned to one of ten folds.
Data$Fold <- sample(c(rep(1:10,10)))

## Each fold will have the same number of observations assigned to it. You can
## double check this by typing the following:
table(Data$Fold)

## Note: If you were to have 105 observations instead of 100, you could instead
## write: Data$Fold <- sample(c(rep(1:10,10),rep(1:5,1)))
################################################################################


################################################################################
## I like to use a "for loop" for cross-validation. Here, prior to beginning my
## "for loop", I will define the variables I plan to use in it. You have to do
## this first or R will give you an error code.
fit <- NULL
stepw <- NULL
training <- NULL
testing <- NULL
Preselection <- NULL
Selected <- NULL
variables <- NULL
################################################################################


################################################################################
## Now we can begin the ten-fold cross validation. First, we open the "for loop"
for (CV in 1:10) {

## Now we define your training and testing folds. I like to store these data in
## a list, so at the end of the script, if I want to, I can go back and look at
## the observations in each individual fold
training[[CV]] <- Data[which(Data$Fold != CV),]
testing[[CV]]  <- Data[which(Data$Fold == CV),]

## We can preselect variables by analyzing each variable separately using
## univariate linear regression and then ranking them by p value. First we will
## define the container object to which we plan to output these data.
Preselection[[CV]] <- as.data.frame(Preselection[CV])

## Now we will run a separate linear regression for each of our 70 variables.
## We will store the variable name and the coefficient p value in our object
## called "Preselection".
for (i in 1:70) {
Preselection[[CV]][i,1]  <- i
Preselection[[CV]][i,2]  <- summary(lm(Dependent ~ training[[CV]][,i] , data = training[[CV]]))$coefficients[2,4]
}

## Now we will remove "i" and also we will name the columns of our new object.
rm(i)
names(Preselection[[CV]]) <- c("Variable", "pValue")

## Now we will make note of those variables whose p values were less than 0.1.
Selected[[CV]] <- Preselection[[CV]][which(Preselection[[CV]]$pValue <= 0.1),] ; row.names(Selected[[CV]]) <- NULL

## Fit a model using the pre-selected variables to the training fold
## First we must save the variable names as a character string
temp <- NULL
for (k in 1:(as.numeric(length(Selected[[CV]]$Variable)))) {
temp[k] <- paste("training[[CV]]$V",Selected[[CV]]$Variable[k]," + ",sep="")}
variables[[CV]] <- paste(temp, collapse = "")
variables[[CV]] <- substr(variables[[CV]],1,(nchar(variables[[CV]])-3))

## Now we can use this string as the independent variables list in our model
y <- training[[CV]][,"Dependent"]
form <- as.formula(paste("y ~", variables[[CV]]))

## We can build a model using all of the pre-selected variables
fit[[CV]] <- lm(form, training[[CV]])

## Then we can build new models using stepwise removal of these variables using
## the MASS package
stepw[[CV]] <- stepAIC(fit[[CV]], direction="both")

## End for loop
}

## Now you have your ten training and validation sets saved as training[[CV]]
## and testing[[CV]]. You also have results from your univariate pre-selection
## analyses saved as Preselection[[CV]]. Those variables that had p values less
## than 0.1 are saved in Selected[[CV]]. Models built using these variables are
## saved in fit[[CV]]. Reduced versions of these models (by stepwise selection)
## are saved in stepw[[CV]].

## Now you might consider using the predict.lm function from the stats package
## to apply your ten models to their corresponding validation folds. You then
## could look at the performance of the ten models and average their performance
## statistics together to get an overall idea of how well your data predict the
## outcome.
################################################################################

Prima di eseguire la convalida incrociata, è importante leggere sul suo uso corretto. Questi due riferimenti offrono eccellenti discussioni sulla convalida incrociata:

  1. Simon RM, Subramanian J, Li MC, Menezes S. Utilizzo della validazione incrociata per valutare l'accuratezza predittiva dei classificatori del rischio di sopravvivenza sulla base di dati ad alta dimensione. Breve Bioinforma. Maggio 2011; 12 (3): 203-14. Epub 2011, 15 febbraio. Http://bib.oxfordjournals.org/content/12/3/203.long
  2. Richard Simon, Michael D. Radmacher, Kevin Dobbin e Lisa M. McShane. Insidie ​​nell'uso dei dati di microarray di DNA per la classificazione diagnostica e prognostica. JNCI J Natl Cancer Inst (2003) 95 (1): 14-18. http://jnci.oxfordjournals.org/content/95/1/14.long

Questi documenti sono rivolti ai biostatisti, ma sarebbero utili a chiunque.

Inoltre, tieni sempre presente che l'uso della regressione graduale è pericoloso (sebbene l'uso della convalida incrociata dovrebbe aiutare ad alleviare l'eccessivo adattamento). Una buona discussione sulla regressione graduale è disponibile qui: http://www.stata.com/support/faqs/stat/stepwise.html .

Fammi sapere se hai altre domande!


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.