Importância variável do GLMNET

18

Eu estou olhando para usar o laço como um método para selecionar recursos e ajustar um modelo preditivo com um alvo binário. Abaixo está um código com o qual eu estava jogando para testar o método com regressão logística regularizada.

Minha pergunta é: recebo um grupo de variáveis ​​"significativas", mas posso classificá-las para estimar a importância relativa de cada uma? Os coeficientes podem ser padronizados para esse propósito de classificação por valor absoluto (eu entendo que eles são mostrados na escala de variáveis ​​original por meio da coeffunção)? Nesse caso, como fazê-lo (usando o desvio padrão de xey) Padronizar coeficientes de regressão .

CÓDIGO DE AMOSTRA:

    library(glmnet)

    #data comes from

#http://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Diagnostic)

    datasetTest <- read.csv('C:/Documents and Settings/E997608/Desktop/wdbc.data.txt',head=FALSE)


#appears to use the first level as the target success
   datasetTest$V2<-as.factor(ifelse(as.character(datasetTest$V2)=="M","0","1"))


#cross validation to find optimal lambda
#using the lasso because alpha=1

    cv.result<-cv.glmnet(       
              x=as.matrix(dataset[,3:ncol(datasetTest)]),
              y=datasetTest[,2],        
              family="binomial",        
              nfolds=10,        
              type.measure="deviance",       
              alpha=1      
              )

#values of lambda used

    histogram(cv.result$lambda)

#plot of the error measure (here was deviance)
#as a CI from each of the 10 folds
#for each value of lambda (log actually)

    plot(cv.result) 

#the mean cross validation error (one for each of the
#100 values of lambda

    cv.result$cvm

#the value of lambda that minimzes the error measure
#result: 0.001909601

    cv.result$lambda.min
    log(cv.result$lambda.min)

#the value of lambda that minimzes the error measure
#within 1 SE of the minimum
#result: 0.007024236

    cv.result$lambda.1se

#the full sequence was fit in the object called cv.result$glmnet.fit
#this is same as a call to it directly.
#here are the coefficients from the min lambda

    coef(cv.result$glmnet.fit,s=cv.result$lambda.1se)
B_Miner
fonte

Respostas:

14

Até onde eu sei, o glmnet não calcula os erros padrão dos coeficientes de regressão (uma vez que se ajusta aos parâmetros do modelo usando a descida de coordenadas cíclicas). Portanto, se você precisar de coeficientes de regressão padronizados, precisará usar outro método (por exemplo, glm)

Dito isto, se as variáveis ​​explicativas forem padronizadas antes do ajuste e do glmnet serem chamados com "padronize = FALSE", os coeficientes menos importantes serão menores que os mais importantes - para que você possa classificá-los apenas pela sua magnitude. Isso se torna ainda mais pronunciado com o encolhimento não trivial da quantidade (isto é, lambda diferente de zero)

Espero que isto ajude..

Yevgeny
fonte
2
obrigado. Acredito que os coeficientes retornem à escala original. Portanto, seria necessário redimensioná-los (suponho que usando a técnica que publiquei por exemplo).
B_Miner
user6129 está certo! você não tem como classificar as variáveis ​​selecionadas. É uma área ativa de pesquisa.
suncoolsu 01/09/11
3
@ B_Miner: você está certo, se chamado com "standardize = TRUE" glmnet retorna coeficientes na escala original. Uma maneira de contornar isso é padronizar as variáveis ​​explicativas externas (por exemplo, usando a função "scale ()") e chamar o glmnet com "standardize = FALSE". Os coeficientes resultantes poderiam então ser classificados por magnitude para julgar sua importância.
Yevgeny
@suncoolsu: pls veja minha resposta atualizada acima
Yevgeny
@Yevgeny Eu tenho uma pergunta. Então, tecnicamente, os resultados de desempenho (por exemplo, área sob a curva) devem ser os mesmos, se definirmos 'standardize = FALSE' e padronizarmos as variáveis ​​por nós mesmos ou se usarmos 'standardize = TRUE'? (Somente os coeficientes beta retornados seriam diferentes). É o que eu penso teoricamente, mas, na prática, obtenho resultados um pouco melhores quando uso 'padronizar = VERDADEIRO'. Portanto, os coeficientes e o desempenho são diferentes. é assim que deveria ser?
Michelle
7

Para obter o coeficiente em um espaço que permita comparar diretamente a importância deles, você deve padronizá-los. Escrevi uma nota no Thinklab para discutir a padronização dos coeficientes de regressão logística.

(Muito) Resumindo, recomendo usar o método Agresti :

# if X is the input matrix of the glmnet function,
# and cv.result is your glmnet object:
sds <- apply(X, 2, sd)
cs <- as.matrix(coef(cv.result, s = "lambda.min"))
std_coefs <- coefs[-1, 1] * sds

Se você confiou na padronização interna pelo glmnet (opção padrão standardize = TRUE), esses coeficientes padronizados são realmente os resultantes da etapa de ajuste, antes da retransformação pelo glmnet no espaço original (consulte outra nota :-)).

Antoine Lizée
fonte
2
std_coefs <- coefs[-1, 1] * sds
b=bσx
Antoine - Você pode confirmar que multiplicação e não divisão são apropriadas aqui?
B_Miner 9/09/17
1
σx+bx+=+(bσx)(x-μ)/σx+...bσx=x
Sim, é um erro de digitação (mais um lembrete para nunca digitar exemplos sem executar o código ;-)) Obrigado por capturá-lo, está corrigido.
Antoine Lizée
Isso fornece os coeficientes padronizados corretos, se o glmnetobjeto foi criado com standardize = TRUEou standardize = FALSE, sim?
James Hirschorn