GLMNETからの変数の重要性


18

機能を選択し、予測モデルをバイナリターゲットに適合させる方法として投げ縄を使用することを検討しています。以下は、正規化されたロジスティック回帰でメソッドを試すために遊んでいたコードです。

私の質問は、「重要な」変数のグループを取得することですが、それぞれの相対的な重要性を推定するためにこれらを順序付けすることはできますか?この目的のために係数を絶対値でランク付けすることはできますか(coef関数を介して元の変数スケールで表示されることを理解しています)?その場合、その方法(xとyの標準偏差を使用)回帰係数を標準化します。

サンプルコード:

    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)

回答:


14

私の知る限り、glmnetは回帰係数の標準誤差を計算しません(周期座標降下を使用してモデルパラメーターに適合するため)。したがって、標準化された回帰係数が必要な場合は、他の方法(glmなど)を使用する必要があります

とはいえ、説明変数が適合前に標準化され、glmnetが "standardize = FALSE"で呼び出されると、重要度の低い係数は重要度の高い係数よりも小さくなります。これは、自明でない量の縮小(つまり、ゼロ以外のラムダ)でさらに顕著になります。

お役に立てれば..


2
ありがとう。係数は元のスケールで返されると思います。したがって、それらを再スケーリングする必要があります(たとえば、私が投稿した手法を使用することで推測します)。
B_Miner

user6129が正しい!選択した変数をランク付けする手段はありません。それは研究の活発な分野です。
-suncoolsu

3
@B_Miner:「standardize = TRUE」を指定して呼び出した場合、glmnetは元のスケールで係数を返します。これを回避する1つの方法は、外部の説明変数を標準化して(たとえば、「scale()」関数を使用して)、「standardize = FALSE」でglmnetを呼び出すことです。次に、結果の係数を大きさでランク付けして、その重要性を判断できます。
エフゲニー

@suncoolsu:上記の更新された回答をご覧ください
Yevgeny

@Yevgeny質問があります。技術的には、 'standardize = FALSE'を設定して変数を標準化しても、単に 'standardize = TRUE'を使用しても、パフォーマンス結果(曲線下の面積など)は同じになりますか?(返されるベータ係数のみが異なります)。これは理論的には考えていることですが、実際には、 'standardize = TRUE'を使用すると若干良い結果が得られます。したがって、係数とパフォーマンスの両方が異なります。これはどうあるべきか?
ミシェル

7

重要度を直接比較できる空間で係数を取得するには、それらを標準化する必要があります。ロジスティック回帰係数の標準化について議論するために、Thinklabでメモを書きました。

(非常に)簡単に言えば、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

glmnetによる内部標準化(デフォルトオプションstandardize = TRUE)に依存している場合、これらの標準化された係数は、実際には、元の空間でglmnetによる再変換を行う前のフィッティングステップの結果です(別のメモ :-)を参照)。


2
std_coefs <- coefs[-1, 1] * sds
b=bσバツ

アントワーヌ-ここでは、除算ではなく乗算が適切であることを確認できますか?
B_Miner

1
確かに、あなたの乗算係数σバツ+bバツ+=+bσバツバツμ/σバツ+bσバツ=バツ

はい、それはタイプミスです(さらに、コードを実行せずに例を入力しないことを思い出させます;-))キャッチしてくれてありがとう、修正されました。
アントワーヌリゼ

これにより、glmnetオブジェクトがstandardize = TRUEまたはstandardize = FALSEで作成されたかどうかにかかわらず、正しい標準化された係数が得られます。
ジェームズヒルシュホーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.