Как автоматизировать выбор переменных в glmnet и перекрестную проверку

Я изучаю использование пакетов glmnet и brnn. Рассмотрим следующий код:

library(RODBC)
library(brnn)
library(glmnet)
memory.limit(size = 4000)
z <-odbcConnect("mydb") # database with Access queries and tables

# import the data
f5 <- sqlFetch(z,"my_qry")

# head(f5)

# check for 'NA'
sum(is.na(f5))

# choose a 'locn', up to 16 of variable 'locn' are present
f6 <- subset(f5, locn == "mm")
# dim(f6)

# use glmnet to identify possible iv's

training_xnm <- f6[,1:52] # training data
xnm <- as.matrix(training_xnm)
y <- f6[,54] # response

fit.nm <- glmnet(xnm,y, family="binomial", alpha=0.6, nlambda=1000,standardize=TRUE,maxit=100000)
# print(fit.nm)

# cross validation for glmnet to determine a good lambda value
cv.fit.nm <- cv.glmnet(xnm, y)

# have a look at the 'min' and '1se' lambda values
cv.fit.nm$lambda.min
cv.fit.nm$lambda.1se
# returned $lambda.min of 0.002906279, $lambda.1se of 2.587214

# for testing purposes I choose a value between 'min' and '1se'
mid.lambda.nm = (cv.fit.nm$lambda.min + cv.fit.nm$lambda.1se)/2

print(coef(fit.nm, s = mid.lambda.nm)) # 8 iv's retained

# I then manually inspect the data frame and enter the column index for each of the iv's
# these iv's will be the input to my 'brnn' neural nets

cols <- c(1, 3, 6, 8, 11, 20, 25, 38) # column indices of useful iv's

# brnn creation: only one shown but this step will be repeated
# take a 85% sample from data frame
ridxs <- sample(1:nrow(f6), floor(0.85*nrow(f6)) ) # row id's
f6train <- f6[ridxs,] # the resultant data frame of 85%
f6train <-f6train[,cols] # 'cols' as chosen above

# For the 'brnn' phase response is a binary value, 'fin'
# and predictors are the 8 iv's found earlier
out = brnn( fin ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8, data=f6train, neurons=3,normalize=TRUE, epochs=500, verbose=FALSE)
#summary(out)

# see how well the net predicts the training cases
pred <- predict(out)

Приведенный выше скрипт работает нормально.

Мой вопрос: как я могу автоматизировать приведенный выше скрипт для запуска для разных значений locn, то есть, по сути, как я могу обобщить получение шага: cols <- c(1, 3, 6, 8, 11, 20, 25, 38) # column indices of useful iv's. В настоящее время я могу сделать это вручную, но не вижу, как это сделать в общем случае для разных значений locn, например

locn.list <- c("am", "bm", "cm", "dm", "em")  
for(j in 1:5) {
this.locn <- locn.list[j]
# run the above script
}

person cousin_pete    schedule 21.08.2013    source источник
comment
Не похоже, что какое-либо тестирование с вашими данными возможно, но вы должны сразу же понять, что использование ( после токена заставляет R искать функцию с таким именем. Вероятно, нужно locn.list[j]. Строка j<-1 кажется совершенно лишней.   -  person IRTFM    schedule 21.08.2013
comment
Спасибо за комментарий DWin: мой плохой, опечатка, и да, я согласен j ‹- 1 избыточен!   -  person cousin_pete    schedule 22.08.2013
comment
Спасибо за комментарий DWin: мой плохой, опечатка, и да, я согласен j ‹- 1 избыточен! Как я уже упоминал, нет проблем с запуском кода, мой вопрос заключался в том, как обобщить набор полезных переменных из glmnet после перекрестной проверки. В настоящее время я использую код много раз в день, используя текущие финансовые данные для одного значения «locn». Я мог бы сделать отдельный скрипт для всех 17 значений 'locn' и запускать их последовательно, но я надеялся захватить начало строки: cols ‹- c(1,......) программно, а не вводить это вручную. очередь для каждого 'locn'.   -  person cousin_pete    schedule 22.08.2013
comment
Вы должны отредактировать свой вопрос, если согласны с тем, что в вашем коде есть ошибки. Я заинтересован в проблеме, если вы можете ясно видеть свой путь, чтобы сделать набор данных доступным.   -  person IRTFM    schedule 22.08.2013
comment
Спасибо DWin, я отредактировал свой пост, как вы предлагаете.   -  person cousin_pete    schedule 23.08.2013


Ответы (1)


После публикации моего вопроса я нашел статью Саймона, Фридмана, Хасти и Тибширани: Кокснет: регуляризованная регрессия Кокса, в которой рассматривается, как извлечь то, что я хотел.

Некоторые важные детали из этой статьи, адаптированные для моих данных (за исключением символа лямбда!): мы можем проверить, какие ковариаты наша модель выбрала в качестве активных, и увидеть коэффициенты этих ковариат.

coef(fit.nm, s = cv.fit.nm$lambda.min) # returns the p length coefficient vector

решения, соответствующего лямбда = cv.fit$lambda.min.

Coefficients <- coef(fit.nm, s = cv.fit.nm$lambda.min)
Active.Index <- which(Coefficients != 0)
Active.Coefficients <- Coefficients[Active.Index]

Active.Index # identifies the covariates that are active in the model and
Active.Coefficients # shows the coefficients of those covariates

Надеюсь, это может быть полезно для других!

person cousin_pete    schedule 23.08.2013