glmnetの解釈方法は?


36

約60の予測変数と30の観測値を持つ多変量線形回帰モデルを近似しようとしています。そのため、p> nであるため、正規化回帰にglmnetパッケージを使用してます。

私はドキュメントや他の質問を行ってきましたが、結果を解釈することはまだできません。サンプルコード(簡単にするために20の予測子と10の観測値を使用)を次に示します。

num rows = numの観測値とnum cols = numの予測子、および応答変数を表すベクトルyを含む行列xを作成します

> x=matrix(rnorm(10*20),10,20)
> y=rnorm(10)

アルファをデフォルトのままにしてglmnetモデルに適合します(投げ縄ペナルティの場合= 1)

> fit1=glmnet(x,y)
> print(fit1)

ラムダの値が減少すると異なる予測が得られることを理解しています(つまり、ペナルティ)

Call:  glmnet(x = x, y = y) 

        Df    %Dev   Lambda
  [1,]  0 0.00000 0.890700
  [2,]  1 0.06159 0.850200
  [3,]  1 0.11770 0.811500
  [4,]  1 0.16880 0.774600
   .
   .
   .
  [96,] 10 0.99740 0.010730
  [97,] 10 0.99760 0.010240
  [98,] 10 0.99780 0.009775
  [99,] 10 0.99800 0.009331
 [100,] 10 0.99820 0.008907

ここで、たとえば、次から与えられる最小のラムダ値を選択して、ベータ値を予測します glmnet

> predict(fit1,type="coef", s = 0.008907)

21 x 1 sparse Matrix of class "dgCMatrix"
                  1
(Intercept) -0.08872364
V1           0.23734885
V2          -0.35472137
V3          -0.08088463
V4           .         
V5           .         
V6           .         
V7           0.31127123
V8           .         
V9           .         
V10          .         
V11          0.10636867
V12          .         
V13         -0.20328200
V14         -0.77717745
V15          .         
V16         -0.25924281
V17          .         
V18          .         
V19         -0.57989929
V20         -0.22522859

代わりにlambdaを選択した場合

cv <- cv.glmnet(x,y)
model=glmnet(x,y,lambda=cv$lambda.min)

すべての変数は(。)になります。

疑問点と質問:

  1. ラムダの選択方法がわかりません。
  2. 別のモデルに適合するために非(。)変数を使用する必要がありますか?私の場合、できるだけ多くの変数を保持したいと思います。
  3. p値、つまりどの変数が応答を有意に予測するかをどのように知ることができますか?

統計に関する知識が乏しいことをおaびします!そして、助けてくれてありがとう。


たぶん、CRANパッケージを見ていHDIを 1は、高次元モデルのための推論を提供することを、...
トムWenseleers

使用される方法の完全な説明については、この論文を参照してください:projecteuclid.org/euclid.ss/1449670857
トムウェンセリアーズ

回答:


40

これは直感に反する事実です。glmnetに単一のラムダ値を与えることは実際には想定されていません。ここのドキュメントから

ラムダに単一の値を指定しないでください(CVの後の予測では、代わりにpredict()を使用してください)。代わりに、減少する一連のラムダ値を指定します。glmnetは、ウォームスタートの速度に依存しており、多くの場合、単一のフィットを計算するよりもパス全体をフィットする方が高速です。

cv.glmnet例でほのめかしたように、ラムダを選択するのに役立ちます。glmnetパッケージの作成者はのcv$lambda.1se代わりにを提案しcv$lambda.minていますが、実際には後者で成功しています。

cv.glmnetを実行した後、glmnetを再実行する必要はありません!グリッド内のすべてのラムダ(cv$lambda)はすでに実行されています。この手法は「ウォームスタート」と呼ばれ、こちらで詳細を読むことができます。導入から言い換えると、ウォームスタートテクニックは、異なる最適化問題(たとえば、ラムダが大きいglmnet)のソリューションを後の最適化問題(たとえば、ラムダが小さいglmnet)の開始値として使用することにより、反復メソッドの実行時間を短縮します。 )。

から目的の実行を抽出するにはcv.glmnet.fit、これを試してください:

small.lambda.index <- which(cv$lambda == cv$lambda.min)
small.lambda.betas <- cv$glmnet.fit$beta[, small.lambda.index]

改訂(2017年1月28日)

上記のようにglmnetオブジェクトをハックする必要はありません。@取る以下alex23lemmのアドバイスとパスs = "lambda.min"s = "lambda.1se"または他のいくつかの番号を(例えば、s = .007両方ともに)coefpredict。係数と予測は、相互検証によって設定されるこの値に依存することに注意してください。再現性のためにシードを使用してください!また、"s"in coefおよびを指定しないpredict場合は、デフォルトのを使用することを忘れないでくださいs = "lambda.1se"。小さなデータの状況でうまく動作するのを見て、デフォルトにウォームアップしました。s = "lambda.1se"また、より多くの正則化を提供する傾向があるため、アルファ> 0で作業している場合は、より節約的なモデルに向かう傾向があります。また、plot.glmnetを使用してsの数値を選択して、その間のどこかに到達することもできます(x軸からの値をべき乗することを忘れないでください!)。


1
ありがとうございました!これは役立ちます...質問2と3の答えがありますか?
アリス

3
心配ありません。(。)はゼロを表します。Lassoを使用したので、「スパース」ソリューション(つまり、多数のゼロ)が必要であることを指定しました。すべてに値を設定する場合は、alpha = 0に設定します。これで、LassoからRidge回帰に進みました。glmnetのp値は概念的に注意が必要です。たとえば、「なげなわのp値」を検索すると、最近の多くの研究と議論が見られます。著者は、p値はなげなわやリッジ回帰などの偏りのある回帰には意味がないと主張した1つのアカウント(元記憶喪失)を読みました。
ベンオゴレク

6
最小のcvmを与えるラムダの値に関連付けられた係数を抽出する別の方法は次のとおりですsmall.lambda.betas <- coef(cv, s = "lambda.min")
。– alex23lemm

1
@BenOgorek、素晴らしいアップデート!別の有用なリファレンスは、フリードマンJ、ヘイスティT、ヘフリングH、ティブシラーニR.パスワイズ座標最適化です。応用統計の年報。2007; 2(1):302–332。(arxiv.org/pdf/0708.1485.pdf
dv_bn

1
@ erosennin、cv.glmnetのラムダ引数を確認してください:「オプションのユーザー指定のラムダシーケンス。デフォルトはNULLです。glmnetは独自のシーケンスを選択します。」。あなたは温かい開始原理を使用して、興味のある範囲に減少する前に、ラムダのいくつかのより大きな値を持つシーケンスを開始したいと思う
ベンOgorek

2

Q1)ラムダの選択方法がわかりません。Q2)別のモデルに適合するために非(。)変数を使用する必要がありますか?私の場合、できるだけ多くの変数を保持したいと思います。

@BenOgorekのすばらしい答えによると、通常、フィッティングにラムダシーケンス全体を使用させ、最適な係数を抽出する際にlambda.1se値を使用します(あなたがしたこととは異なります)。

以下の3つの注意事項に従う限り、正則化と戦ったり、モデルを微調整したりしないでください。変数が省略された場合、全体的なペナルティが低くなるためです。警告は次のとおりです。

  1. 正規化された係数が意味を持つようにするには、変数の平均と標準偏差を事前に明示的に正規化してくださいscale(); に依存しないでくださいglmnet(standardize=T)。正当化については、なげなわの前の標準化は本当に必要ですか?」を参照してください; 基本的に、大きな値を持つ変数は、正則化で不当に罰せられる可能性があります。

  2. 再現set.seed性を高めるには、いくつかのランダムシードを使用して実行し、正規化された係数の安定性を確認します。

  3. より過酷な正則化、つまりより多くの変数を含める場合は、単純なリッジではなく、alpha <1(つまり適切なelastic-net)を使用します。アルファを0から1にスイープすることをお勧めします。それを行う場合は、ハイパーパラメーターアルファと回帰エラーの過剰適合を回避するためにcv.glmnet()、単純ではなく交差検証を使用する必要がありますglmnet()

for (alpha in c(0,.1,.3,.5,.7,.9,1)) {
  fit <- cv.glmnet(..., alpha=alpha, nfolds=...)
  # Look at the CVE at lambda.1se to find the minimum for this alpha value...
}

このようなgridsearchをCVで自動化する場合は、自分でコーディングするか、glmnetの上にキャレットパッケージを使用できます。キャレットはこれをうまく行います。cv.glmnet nfoldsパラメーター値については、データセットが小さい場合は3(最小)を選択し、大きい場合は5または10を選択します。

Q3)p値、つまりどの変数が応答を有意に予測するかをどのように知るのですか?

意味がありませんglmnetモデルから回帰係数の統計的要約情報を取得するのはなぜお勧めできないのかで詳細に説明したように

cv.glmnet()変数を自動的に選択するだけです。上記の警告付き。そしてもちろん、応答変数の分布は正常である必要があります(使用している場合family='gaussian')。


非常に役立つコメントをありがとう!また、glmnet(standardize = T)を使用するのではなく、自分で変数を標準化することがうまくいくように感じました。
ミシェル

しかし、cvglmnetによって返されるベータ値について、@ smciに質問があります。私はそれらが試みられたラムダ値の各グリッド点でのベータ値であることを理解しています。ただし、各ラムダ値に対して返されるベータ値は、(1)10倍の平均係数値(10foldCVを使用した場合)、(2)最高の精度を与えた倍のベータ値、または(3)からの係数データセット全体でモデルを再実行しますか?
ミシェル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.