Чи існує спосіб використання перехресної перевірки для вибору змінної / функції в R?


10

У мене є набір даних з приблизно 70 змінними, які я хотів би скоротити. Що я хочу зробити, це використовувати CV для пошуку найбільш корисних змінних у наступний спосіб.

1) Випадково виберіть скажімо 20 змінних.

2) Використовуйте stepwise/ LASSO/ lars/ тощо, щоб вибрати найбільш важливі змінні.

3) Повторіть ~ 50x і подивіться, які змінні вибираються (не усуваються) найчастіше.

Це узгоджується з тим, randomForestщо робити, але rfVarSelпакет, здається, працює лише для факторів / класифікації, і мені потрібно передбачити постійну залежну змінну.

Я використовую R, тому будь-які пропозиції в ідеалі будуть реалізовані там.


Чи важливі всі функції? Скільки у вас зразків? Якщо я правильно розумію проблему, ви можете спробувати зробити якийсь варіант прискорення - кілька разів вибирати підмножину зразків і прилаштовувати до них всі змінні та бачити, які з них з’являються частіше.
Офелія

1
Я думаю, що ваша процедура навряд чи поліпшиться на LASSO, реалізація якої в R (наприклад, glmnet та пеналі) за замовчуванням використовує перехресну перевірку, щоб знайти "оптимальний" параметр регуляризації. Одне, що ви можете розглянути, - це повторити пошук LASSO за цим параметром кілька разів, щоб впоратися з потенційно великою дисперсією перехресної перевірки (повторне резюме). Звичайно, жоден алгоритм не може перемогти ваші попередні знання, що стосуються конкретних предметів.
miura

Відповіді:


9

Я вважаю, те, що ви описуєте, вже реалізовано в caretпакеті. Подивіться на rfeфункцію або віньєтку тут: http://cran.r-project.org/web/packages/caret/vignettes/caretSelection.pdf

Тепер, сказавши це, чому потрібно зменшити кількість функцій? З 70 до 20 насправді не зменшується порядок. Я думаю, що вам знадобиться більше 70 функцій, перш ніж ви будете твердо попередньо вважати, що деякі функції справді і справді не мають значення. Але знову ж таки, саме тут, напевно, вступає суб'єктивний пріоритет.


5

Немає жодної причини, коли змінна частота вибору надає будь-яку інформацію, яку ви вже не отримуєте з очевидного значення змінних у початковій моделі. Це по суті повторення початкового статистичного значення. Ви також додаєте новий рівень свавілля при спробі прийняти рішення про обмеження частоти вибору. Перекомпонування змінного вибору сильно пошкоджується колінеарністю на додаток до інших проблем.


2

Я переглянув свою відповідь раніше, ніж сьогодні. Зараз я створив деякі приклади даних, за допомогою яких запустити код. Інші справедливо запропонували вам розглянути можливість використання пакету карет, з чим я згоден. Однак у деяких випадках вам може знадобитися написати власний код. Нижче я намагався продемонструвати, як використовувати функцію sample () в R для випадкового призначення спостережень складкам з перехресною валідацією. Я також використовую для циклів для виконання попереднього вибору змінної (використовуючи одновимірну лінійну регресію з відсічним значенням p значення 0,1) та побудову моделі (за допомогою покрокової регресії) на десяти навчальних наборах. Потім ви можете написати власний код, щоб застосувати отримані моделі до складок перевірки. Сподіваюся, це допомагає!

################################################################################
## 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.
################################################################################

Перш ніж проводити перехресну перевірку, важливо прочитати про її правильне використання. Ці дві посилання пропонують чудові дискусії про перехресну перевірку:

  1. Simon RM, Subramanian J, Li MC, Menezes S. Використання крос-валідації для оцінки прогнозної точності класифікаторів ризику виживання на основі високомірних даних. Коротка біоінформація. 2011 травня; 12 (3): 203-14. Epub 2011, 15 лютого. Http://bib.oxfordjournals.org/content/12/3/203.long
  2. Річард Саймон, Майкл Д. Радмахер, Кевін Доббін та Ліза М. МакШен. Підводні камені у використанні даних мікромасив ДНК для діагностичної та прогностичної класифікації. JNCI J Natl Cancer Inst (2003) 95 (1): 14-18. http://jnci.oxfordjournals.org/content/95/1/14.long

Ці документи орієнтовані на біостатистів, але будуть корисні для будь-кого.

Крім того, завжди пам’ятайте, що використання ступінчастої регресії небезпечно (хоча використання перехресної перевірки повинно сприяти полегшенню надмірного пристосування). Гарне обговорення ступінчастої регресії доступне тут: http://www.stata.com/support/faqs/stat/stepwise.html .

Повідомте мене, якщо у вас є додаткові запитання!


0

Я щойно знайшов щось приємне тут: http://cran.r-project.org/web/packages/Causata/vignettes/Causata-vignette.pdf

Спробуйте це, можливо, при використанні пакету glmnet

# extract nonzero coefficients
coefs.all <- as.matrix(coef(cv.glmnet.obj, s="lambda.min"))
idx <- as.vector(abs(coefs.all) > 0)
coefs.nonzero <- as.matrix(coefs.all[idx])
rownames(coefs.nonzero) <- rownames(coefs.all)[idx]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.