井出草平の研究ノート

lasso, adaptive lasso, group lasso[R]

https://www.math.mcgill.ca/yyang/comp/notes/note4code.R

library(glmnet)

このパッケージで使用されるデフォルトのモデルは、Guassian線形モデルまたは最小二乗法である。説明のためにあらかじめ作成したデータセットをロードする。ユーザは自分のデータをロードすることも、ワークスペースに保存されているデータを使用することもできる。

pacman::p_install_gh("emeryyi/gglasso")
library(gglasso)
data(bardet)
x<- bardet[["x"]]
y<- bardet[["y"]]

glmnetの最も基本的な呼び出しを使ってモデルをフィットさせる。

fit = glmnet(x, y)

"fit "はglmnetクラスのオブジェクトで、フィットされたモデルの関連情報をすべて含んでいる。我々は、ユーザが直接成分を抽出することを推奨していない。その代わりに、plot、print、coef、predictなどの様々なメソッドがオブジェクトに提供され、これらのタスクをよりエレガントに実行することができる。

plot関数を実行すれば、係数を可視化することができる:

plot(fit)

各曲線は変数に対応する。これは、λが変化する時の係数ベクトル全体の「1-norm」に対する係数のパスを示している。上の軸は、現在のλにおける非ゼロ係数の数を示しており、これはlassoの有効自由度(df)となる。ユーザーは、曲線に注釈を付けることもでき、これはplotコマンドでlabel = TRUEを設定することで可能だ。

オブジェクト名を入力するか、print機能を使えば、各ステップでのglmnetパスの概要が表示される:

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

    Df  %Dev   Lambda
1    0  0.00 0.097200
2    1  7.73 0.088560
3    1 14.16 0.080690
4    1 19.49 0.073520
5    1 23.91 0.066990
6    1 27.59 0.061040
7    2 31.42 0.055620
8    2 36.05 0.050680
9    4 40.59 0.046180
10   6 45.05 0.042070
...

左からゼロでない係数の数(Df)、-log(尤度)の値(%dev)、ラムダの値(Lambda)が表示される。デフォルトではglmnetは100個のλの値を要求するが、%dev%がλの値から次のλの値まで十分に変化しない場合、プログラムは早期に停止する(典型的にはパスの終わり近く)。

配列の範囲内の1つ以上のラムダで実際の係数を得ることができる:

coef0 = coef(fit,s=0.1)

関数glmnetは、ユーザーが選択できる一連のモデルを返す。多くの場合、ユーザーはソフトウェアがその中から1つを選択することを好むかもしれない。クロスバリデーションは、おそらくそのタスクのための最もシンプルで最も広く使われている方法である。

cv.glmnetは、プロットや予測などの様々なサポートメソッドとともに、クロスバリデーションを行うためのメイン関数です。ここでは、前に読み込んだサンプルデータを使っている。

cvfit = cv.glmnet(x, y)

cv.glmnetは、cv.glmnetオブジェクトを返しますが、これはここでは "cvfit"であり、クロスバリデーション適合のすべての成分を含むリストです。glmnetに関しては、選択されたλの値を見る以外には、ユーザが直接成分を抽出することは推奨しません。このパッケージは、潜在的なタスクのためによく設計された関数を提供する。

オブジェクトをプロットできる。

plot(cvfit)

クロスバリデーション曲線(赤い点線)、ラムダ配列に沿った上下の標準偏差曲線(エラーバー)が含まれる。選択された2つのラムダは縦の点線で示されている(下図参照)。

選択されたラムダと対応する係数を見ることができる。例えば、

cvfit$lambda.min

[1] 0.001226463

lambda.minは、クロスバリデーションの平均誤差を最小にするλの値である。もう1つの保存されたλはλ.1seで、これは誤差が最小の標準誤差の1つ以内に収まるような最も正則化されたモデルを与える。これを使うには、上記のlambda.minをlambda.1seに置き換えるだけでよい。

coef1 = coef(cvfit, s = "lambda.min")

係数はスパース行列形式で表現されていることに注意。その理由は、正則化パスに沿った解はスパースであることが多いため、スパースフォーマットを使用する方が時間的にも空間的にも効率的だからだ。スパースでない形式を好む場合は、出力をas.matrix()にパイプを通して出力する。

予測は、フィットされたcv.glmnetオブジェクトに基づいて行うことができる。おもちゃの例を見てみよう。

predict(cvfit, newx = x[1:5,], s = "lambda.min")
  lambda.min

[1,] 8.406305 [2,] 8.353781 [3,] 8.377383 [4,] 8.294958 [5,] 8.379072

newxは新しい入力行列を表し、sは前回と同様、予測が行われるλの値(複数可)である。

adaptive lasso

ペナルティ・ファクターの例

[penalty.factor]引数により、各係数に別々のペナルティ係数を適用することができる。デフォルトは各パラメータに対して1だが、他の値を指定することもできる。特に、[penalty.factor]が0に等しい変数は、全くペナルティを受けません!v_jがj番目の変数の制約を表すとする。

ペナルティ制約は、内部的にnvarsの合計になるように再スケーリングされることに注意。

これは、変数に対する予備知識や好みがある場合に非常に便利だ。多くの場合、ある変数が非常に重要で、それを常に保持したい場合があり、これは対応する制約係数を0に設定することで実現できる: v_j は、ペナルティ係数を0に設定することで、ペナルティ係数を0にすることができる:

p.fac = rep(1, 120)
p.fac[c(31, 74, 111)] = 0
pfit = glmnet(x, y, penalty.factor = p.fac)
plot(pfit, xvar="lambda", label = TRUE)

その他の便利な引数をいくつか挙げる: [exclude]は、特定の変数をモデルにしないようにすることができる。もちろん、単純にxからこれらの変数を除外することもできるが、除外された変数をゼロに設定するだけで、係数の完全なベクトルを返すので、excludeの方が便利な場合もある。FALSEの場合、切片は強制的にゼロになる。

Adaptive lassoの例

adaptive lassoは一貫性のある第1段階を必要とする。 Zou (2006)はOLSかridge第一段lassoを推奨している。

thelasso.cv<-cv.glmnet(x,y,family = "gaussian",alpha=1) 

第1段階の係数から第2段階の重みを求める coef() はスパース行列

bhat<-as.matrix(coef(thelasso.cv,s="lambda.1se"))[-1,1] 
if(all(bhat==0)){
  bhat<-rep(.Machine$double.eps*2,length(bhat))
}

もしbhatがすべてゼロなら、すべてにゼロに極めて近いウェイトを割り当てる。これは、第2ステージのすべてにゼロのペナルティを課すことに等しい。

adaptive lasso weight

adpen<-(1/pmax(abs(bhat),.Machine$double.eps)) 

第2段階のlasso(adaptive lasso)

m_adlasso <- glmnet(x,y,family = "gaussian",alpha=1,exclude=which(bhat==0),
penalty.factor=adpen)
plot(m_adlasso)

エラスティックネットelastic-net

エラスティック・ネットの例

glmnetには、ユーザーがフィットをカスタマイズするための様々なオプションが用意されている。ここではよく使われるオプションをいくつか紹介するが、これらはglmnet関数で指定することができる。

[family="gaussian"]はglmnet関数のデフォルトのfamilyオプションだ。

[alpha]は弾性ネットの混合パラメータalphaで、alphaの範囲は[0,1]です。alpha=1はlasso(デフォルト)、alpha=0はリッジになる。

[nlambda] はシーケンス中のラムダ値の数であり、デフォルトは100ですが、[0,1]の範囲もある。

例として、α=0.2(よりリッジ回帰に近い)を設定し、オブザベーションの後半に2倍の重みを与える。 ここでの表示が長くなりすぎるのを避けるために、nlambdaを20に設定する。しかし実際には、λの値の数は100(デフォルト)以上にすることが推奨される。ほとんどの場合、アルゴリズムで使用されるウォーム・スタート warm-starts のために、余分なコストがかからず、非線形モデルではよりよい収束特性につながる。

fit = glmnet(x, y, alpha = 0.2, family="gaussian")

plot(fit, xvar = "lambda", label = TRUE)

グループlasso

グループlassoの例

install.packages("gglasso", repos = "http://cran.us.r-project.org")

https://cran.r-project.org/web/packages/gglasso/index.html

group-lasso ペナルティ付き最小二乗法、ロジスティック回帰、Huberized SVM、二乗SVMの解経路を効率的に計算するための統一アルゴリズム、blockwise-majorization-descent (BMD)。 このパッケージは、Yang, Y. and Zou, H. (2015) DOI: <doi:10.1007/s11222-014-9498-5> の実装だ。

library(gglasso)

bardetデータセットの読み込み

data(bardet)

20のグループを定義する

group1 <- rep(1:20,each=5)

ペナルティ付き最小二乗"group lasso"にフィットさせる。

m1 <- gglasso(x=bardet$x,y=bardet$y,group=group1,loss="ls")
plot(m1)

ペナルティ付きグループLassoでls回帰を用いた5-fold クロスバリデーション

cv <- cv.gglasso(x=bardet$x, y=bardet$y, group=group1, loss="ls",
pred.loss="L2", lambda.factor=0.05, nfolds=5)
plot(cv)

colon データセットを読み込む

data(colon)

グループ指標を定義する

group2 <- rep(1:20,each=5)

グループlassoペナルティ付きロジスティック回帰にフィット

m2 <- gglasso(x=colon$x,y=colon$y,group=group2,loss="logit")
plot(m2)

グループlassoペナルティ付きロジスティック回帰を用いた5-foldクロスバリデーション

cv2 <- cv.gglasso(x=colon$x, y=colon$y, group=group2, loss="logit",
pred.loss="misclass", lambda.factor=0.05, nfolds=5)
plot(cv2)

λ=λ.1seにおける係数

pre = coef(cv$gglasso.fit, s = cv$lambda.1se)

シミュレーション・デモ-1

ロジスティック回帰と最小二乗法におけるlasso、adaptive lasso、scad、mcpの比較

Rライブラリをロード
glmnet: LASSO、adaptive LASSO、elastic net ペナルティ付き最小2乗法およびロジスティック回帰 (すべてポアソン多項式、コックスモデルをサポート)
ncvreg: SCAD および MCP ペナルティ化最小2乗法およびロジスティック回帰用

library(glmnet)
library(ncvreg)
library(MASS)

PART I 最小二乗法

n=100
p=200

真のベータ

truebeta <- c(4,4,4,-6*sqrt(2),4/3,rep(0,p-5))

誤差分散

sigma2 <- 0.3

XjとXkの間の共分散はcov(X_j, X_k) = rho^|i-j|共分散行列である。

covmat <- function(rho, p) {
  rho^(abs(outer(seq(p), seq(p), "-")))
}

rho = 0.1、Xの共分散行列を生成する。

sigma <- covmat(0.1,p)

X ~ N(0, sigma)
epsilon ~ N(0, sigma2)
真のモデル: y = x*truebeta + epsilon

x <- mvrnorm(n,rep(0,p),sigma)
epsilon <- rnorm(n,0,sd=sqrt(sigma2))
y <- x %*% truebeta + epsilon

lassoをフィットさせ、5-fold CVでラムダを選択する。

cvfit <- cv.glmnet(x = x, y = y, alpha = 1, family = "gaussian")
plot(cvfit)

CVで選ばれたラムダ

cvfit$lambda.min

[1] 0.0821079

解決パスをプロットする

plot(cvfit$glmnet.fit,label=TRUE,xvar="lambda")

λ.minのプロット

abline(v=log(cvfit$lambda.min),lty=1)

λ.1seをプロットする

abline(v=log(cvfit$lambda.1se),lty=2)
model_compare <- matrix(NA, nrow=5, ncol=p,
                dimnames=list(c("true model",
                "lasso","adaptive lasso","mcp","scad"),
                paste("V",seq(p),sep="")))

真のモデルを保存する

model_compare[1, ] <- truebeta

lassoによって推定された係数

cvfit <- cv.glmnet(x = x, y = y, alpha = 1, 
family = "gaussian")
tmp <- cvfit$glmnet.fit$beta
lasso_beta <- as.matrix(tmp[,cvfit$lambda==cvfit$lambda.min])
model_compare[2, ] <- lasso_beta

重みを計算し、adaptive lassoにフィットさせる

weight = 1/(lasso_beta)^2

推定係数がゼロの場合、対応するウェイトがInfとなり、数値誤差を防ぐため、Infを大きな数値(例えば1e6)に変換する。

weight[weight==Inf] = 1e6

cvfit <- cv.glmnet(x = x, y = y, alpha = 1, 
        family = "gaussian", 
        nfolds = 5, penalty.factor=weight)

Adaptive Lassoによって推定された係数

tmp <- cvfit$glmnet.fit$beta
adaptive_lasso_beta <- as.matrix(tmp[,cvfit$lambda==cvfit$lambda.min])
model_compare[3, ] <- adaptive_lasso_beta

mcpによって推定された係数

cvfit <- cv.ncvreg(X = x, y = y, penalty = "MCP", family = "gaussian")
mcp_beta <- cvfit$fit$beta[, cvfit$min]
model_compare[4, ] <- mcp_beta[-1]

scadによって推定された係数

cvfit <- cv.ncvreg(X = x, y = y, penalty = "SCAD", family = "gaussian")
scad_beta <- cvfit$fit$beta[, cvfit$min]
model_compare[5, ] <- scad_beta[-1]

4つの方法で推定された係数を比較すると、lasso over-selected、adaptive lasso、scad、mcpが問題を解決していることがわかる。

model_compare
               V1           V2 V3        V4       V5 V6 V7 V8 V9 V10
true model      4  4.000000000  4 -8.485281 1.333333  0  0  0  0   0
lasso           0 -0.022023796  0  0.000000 0.000000  0  0  0  0   0
adaptive lasso  0  0.000000000  0  0.000000 0.000000  0  0  0  0   0
mcp             0  0.000000000  0  0.000000 0.000000  0  0  0  0   0
scad            0 -0.004545409  0  0.000000 0.000000  0  0  0  0   0
                       V11         V12        V13       V14       V15 V16
true model     0.000000000  0.00000000  0.0000000 0.0000000  0.000000   0
lasso          0.006311609  0.00000000  0.0000000 0.0000000  0.000000   0
adaptive lasso 0.000000000  0.00000000  0.0000000 0.0000000  0.000000   0
mcp            0.000000000 -0.08207367 -0.1647326 0.2088095 -1.000567   0
scad           0.000000000  0.00000000  0.0000000 0.0000000 -1.033549   0
                      V17         V18 V19 V20 V21          V22         V23
true model     0.00000000  0.00000000   0   0   0 0.0000000000  0.00000000
lasso          0.00000000 -0.01762063   0   0   0 0.0001952964 -0.05328850
adaptive lasso 0.00000000  0.00000000   0   0   0 0.0000000000  0.00000000
mcp            0.03504008  0.00000000   0   0   0 0.0000000000  0.00000000
scad           0.00000000  0.00000000   0   0   0 0.0000000000 -0.08488739
                      V24        V25        V26 V27        V28 V29        V30
true model      0.0000000  0.0000000 0.00000000   0  0.0000000   0  0.0000000
lasso           0.0000000 -0.5648782 0.06002556   0  0.0000000   0 -0.3371098
adaptive lasso  0.0000000 -1.0114037 0.00000000   0  0.0000000   0  0.0000000
mcp            -0.4379709  0.0000000 0.00000000   0 -0.1994319   0  0.0000000
scad            0.0000000  0.0000000 0.00000000   0  0.0000000   0  0.0000000
                      V31 V32        V33 V34 V35       V36 V37 V38 V39 V40 V41
true model      0.0000000   0  0.0000000   0   0 0.0000000   0   0   0   0   0
lasso          -0.1165544   0  0.0000000   0   0 0.0482393   0   0   0   0   0
adaptive lasso  0.0000000   0  0.0000000   0   0 0.0000000   0   0   0   0   0
mcp            -0.4561359   0 -0.1259705   0   0 0.1201394   0   0   0   0   0
scad            0.0000000   0  0.0000000   0   0 0.0000000   0   0   0   0   0
               V42 V43         V44 V45        V46       V47 V48 V49        V50
true model       0   0 0.000000000   0  0.0000000 0.0000000   0   0  0.0000000
lasso            0   0 0.009982214   0 -0.2897772 0.0000000   0   0  0.0000000
adaptive lasso   0   0 0.000000000   0 -0.6616183 0.0000000   0   0  0.0000000
mcp              0   0 0.000000000   0 -0.4648836 0.1156758   0   0 -0.1438189
scad             0   0 0.000000000   0 -0.1163973 0.0000000   0   0  0.0000000
                      V51 V52        V53        V54 V55 V56 V57         V58 V59
true model      0.0000000   0 0.00000000 0.00000000   0   0   0  0.00000000   0
lasso           0.0000000   0 0.05634673 0.13775797   0   0   0  0.00000000   0
adaptive lasso  0.0000000   0 0.00000000 0.09460430   0   0   0  0.00000000   0
mcp             0.0000000   0 0.07499241 0.11837706   0   0   0 -0.05640483   0
scad           -0.1008567   0 0.00000000 0.08972644   0   0   0  0.00000000   0
               V60 V61 V62        V63 V64       V65         V66 V67 V68 V69 V70
true model       0   0   0 0.00000000   0 0.0000000  0.00000000   0   0   0   0
lasso            0   0   0 0.00000000   0 0.2563789 -0.12041928   0   0   0   0
adaptive lasso   0   0   0 0.00000000   0 0.2957797  0.00000000   0   0   0   0
mcp              0   0   0 0.02528918   0 0.3411462  0.00000000   0   0   0   0
scad             0   0   0 0.00000000   0 0.1248035 -0.03840615   0   0   0   0
               V71 V72        V73 V74 V75         V76       V77        V78 V79
true model       0   0 0.00000000   0   0  0.00000000 0.0000000 0.00000000   0
lasso            0   0 0.05161909   0   0  0.00000000 0.0000000 0.04393271   0
adaptive lasso   0   0 0.00000000   0   0  0.00000000 0.0000000 0.00000000   0
mcp              0   0 0.07055282   0   0  0.00000000 0.0652188 0.12140394   0
scad             0   0 0.00000000   0   0 -0.06290252 0.0000000 0.00000000   0
               V80 V81 V82 V83 V84 V85        V86          V87 V88       V89
true model       0   0   0   0   0   0 0.00000000  0.000000000   0 0.0000000
lasso            0   0   0   0   0   0 0.00000000 -0.001347216   0 0.2044193
adaptive lasso   0   0   0   0   0   0 0.00000000  0.000000000   0 0.1554728
mcp              0   0   0   0   0   0 0.04738824  0.000000000   0 0.4817615
scad             0   0   0   0   0   0 0.00000000  0.000000000   0 0.0000000
               V90 V91 V92 V93        V94 V95 V96 V97 V98 V99       V100 V101
true model       0   0   0   0 0.00000000   0   0   0   0   0 0.00000000    0
lasso            0   0   0   0 0.07206646   0   0   0   0   0 0.06736159    0
adaptive lasso   0   0   0   0 0.00000000   0   0   0   0   0 0.00000000    0
mcp              0   0   0   0 0.44369829   0   0   0   0   0 0.14673570    0
scad             0   0   0   0 0.00000000   0   0   0   0   0 0.00000000    0
                       V102 V103 V104 V105 V106 V107 V108 V109 V110        V111
true model      0.000000000    0    0    0    0    0    0    0    0 0.000000000
lasso          -0.022023796    0    0    0    0    0    0    0    0 0.006311609
adaptive lasso  0.000000000    0    0    0    0    0    0    0    0 0.000000000
mcp             0.000000000    0    0    0    0    0    0    0    0 0.000000000
scad           -0.004545409    0    0    0    0    0    0    0    0 0.000000000
                      V112       V113      V114      V115 V116       V117
true model      0.00000000  0.0000000 0.0000000  0.000000    0 0.00000000
lasso           0.00000000  0.0000000 0.0000000  0.000000    0 0.00000000
adaptive lasso  0.00000000  0.0000000 0.0000000  0.000000    0 0.00000000
mcp            -0.08207367 -0.1647326 0.2088095 -1.000567    0 0.03504008
scad            0.00000000  0.0000000 0.0000000 -1.033549    0 0.00000000
                      V118 V119 V120 V121         V122        V123       V124
true model      0.00000000    0    0    0 0.0000000000  0.00000000  0.0000000
lasso          -0.01762063    0    0    0 0.0001952964 -0.05328850  0.0000000
adaptive lasso  0.00000000    0    0    0 0.0000000000  0.00000000  0.0000000
mcp             0.00000000    0    0    0 0.0000000000  0.00000000 -0.4379709
scad            0.00000000    0    0    0 0.0000000000 -0.08488739  0.0000000
                     V125       V126 V127       V128 V129       V130       V131
true model      0.0000000 0.00000000    0  0.0000000    0  0.0000000  0.0000000
lasso          -0.5648782 0.06002556    0  0.0000000    0 -0.3371098 -0.1165544
adaptive lasso -1.0114037 0.00000000    0  0.0000000    0  0.0000000  0.0000000
mcp             0.0000000 0.00000000    0 -0.1994319    0  0.0000000 -0.4561359
scad            0.0000000 0.00000000    0  0.0000000    0  0.0000000  0.0000000
               V132       V133 V134 V135      V136 V137 V138 V139 V140 V141
true model        0  0.0000000    0    0 0.0000000    0    0    0    0    0
lasso             0  0.0000000    0    0 0.0482393    0    0    0    0    0
adaptive lasso    0  0.0000000    0    0 0.0000000    0    0    0    0    0
mcp               0 -0.1259705    0    0 0.1201394    0    0    0    0    0
scad              0  0.0000000    0    0 0.0000000    0    0    0    0    0
               V142 V143        V144 V145       V146      V147 V148 V149
true model        0    0 0.000000000    0  0.0000000 0.0000000    0    0
lasso             0    0 0.009982214    0 -0.2897772 0.0000000    0    0
adaptive lasso    0    0 0.000000000    0 -0.6616183 0.0000000    0    0
mcp               0    0 0.000000000    0 -0.4648836 0.1156758    0    0
scad              0    0 0.000000000    0 -0.1163973 0.0000000    0    0
                     V150       V151 V152       V153       V154 V155 V156 V157
true model      0.0000000  0.0000000    0 0.00000000 0.00000000    0    0    0
lasso           0.0000000  0.0000000    0 0.05634673 0.13775797    0    0    0
adaptive lasso  0.0000000  0.0000000    0 0.00000000 0.09460430    0    0    0
mcp            -0.1438189  0.0000000    0 0.07499241 0.11837706    0    0    0
scad            0.0000000 -0.1008567    0 0.00000000 0.08972644    0    0    0
                      V158 V159 V160 V161 V162       V163 V164      V165
true model      0.00000000    0    0    0    0 0.00000000    0 0.0000000
lasso           0.00000000    0    0    0    0 0.00000000    0 0.2563789
adaptive lasso  0.00000000    0    0    0    0 0.00000000    0 0.2957797
mcp            -0.05640483    0    0    0    0 0.02528918    0 0.3411462
scad            0.00000000    0    0    0    0 0.00000000    0 0.1248035
                      V166 V167 V168 V169 V170 V171 V172       V173 V174 V175
true model      0.00000000    0    0    0    0    0    0 0.00000000    0    0
lasso          -0.12041928    0    0    0    0    0    0 0.05161909    0    0
adaptive lasso  0.00000000    0    0    0    0    0    0 0.00000000    0    0
mcp             0.00000000    0    0    0    0    0    0 0.07055282    0    0
scad           -0.03840615    0    0    0    0    0    0 0.00000000    0    0
                      V176      V177       V178 V179 V180 V181 V182 V183 V184
true model      0.00000000 0.0000000 0.00000000    0    0    0    0    0    0
lasso           0.00000000 0.0000000 0.04393271    0    0    0    0    0    0
adaptive lasso  0.00000000 0.0000000 0.00000000    0    0    0    0    0    0
mcp             0.00000000 0.0652188 0.12140394    0    0    0    0    0    0
scad           -0.06290252 0.0000000 0.00000000    0    0    0    0    0    0
               V185       V186         V187 V188      V189 V190 V191 V192 V193
true model        0 0.00000000  0.000000000    0 0.0000000    0    0    0    0
lasso             0 0.00000000 -0.001347216    0 0.2044193    0    0    0    0
adaptive lasso    0 0.00000000  0.000000000    0 0.1554728    0    0    0    0
mcp               0 0.04738824  0.000000000    0 0.4817615    0    0    0    0
scad              0 0.00000000  0.000000000    0 0.0000000    0    0    0    0
                     V194 V195 V196 V197 V198 V199       V200
true model     0.00000000    0    0    0    0    0 0.00000000
lasso          0.07206646    0    0    0    0    0 0.06736159
adaptive lasso 0.00000000    0    0    0    0    0 0.00000000
mcp            0.44369829    0    0    0    0    0 0.14673570
scad           0.00000000    0    0    0    0    0 0.00000000

シミュレーション・デモ-2

PART II ロジスティック回帰

データを生成する

n <- 200 
p <- 8

真のベータ

truebeta <- c(6,3.5,0,5,rep(0,p-4)) 
truebeta

真のモデルからxとyを生成 真のモデル: P(y=1|x) = exp(xtruebeta)/(exp(xtruebeta)+1)

x <- matrix(rnorm(n*p), n, p)
feta <- x %*% truebeta 
fprob <- ifelse(feta < 0, exp(feta)/(1+exp(feta)), 1/(1 + exp(-feta)))
y <- rbinom(n, 1, fprob)


model_compare <- matrix(NA, nrow=5, ncol=p,
                        dimnames=list(c("true model","lasso",
                        "adaptive lasso","mcp","scad"),
                        paste("V",seq(p),sep="")))

真のモデルを保存する

model_compare[1, ] <- truebeta

lassoのケース
cv.glmfit ラッソモデルをフィットし、ラムダの選択にクロス検証を使用する。

family = "binomial", ロジスティック回帰
family = "gaussian", 最小二乗法

alphaはL1ペナルティ項の度合いを制御する、
alpha = 1, lasso、
alpha = 0, ridge、
alpha = (0,1), 弾性ネット

nfolds = 5, 5回クロスバリデーション(CV)

cvfit <- cv.glmnet(x = x, y = y, alpha = 1, family = "binomial", nfolds = 5)

CV結果をプロットする 左の縦線(λ.min)は、最小の偏差を与えるλに対応する。
右の縦線(λ.1se)は、1標準偏差ルールのλに対応する。

plot(cvfit)

解決パスをプロットする

plot(cvfit$glmnet.fit,label=TRUE,xvar="lambda")

plot(cvfit$glmnet.fit,label=TRUE,xvar="lambda")

λ.minをプロットする

abline(v=log(cvfit$lambda.min),lty=1)

λ.1seをプロットする

abline(v=log(cvfit$lambda.1se),lty=2)

各列はラムダ値の推定値を表す。

tmp <- cvfit$glmnet.fit$beta
tmp

CVが選択したλ.minに対応するベータ値

lasso_beta <- as.matrix(tmp[,cvfit$lambda==cvfit$lambda.min])
model_compare[2, ] <- lasso_beta

重みを計算し、Adaptive Lassoをフィットさせる

weight = 1/(lasso_beta)^2

推定係数がゼロの場合、対応するウェイトがInfとなり、数値誤差を防ぐため、Infを大きな数値(例えば1e6)に変換する。

weight[weight==Inf] = 1e6

cvfit <- cv.glmnet(x = x, y = y, alpha = 1, family = "binomial", 
                        nfolds = 5, penalty.factor=weight)

Adaptive Lassoによって推定された係数

tmp <- cvfit$glmnet.fit$beta
adaptive_lasso_beta <- as.matrix(tmp[,cvfit$lambda==cvfit$lambda.min])
model_compare[3, ] <- adaptive_lasso_beta

mcpによって推定された係数

cvfit <- cv.ncvreg(X = x, y = y, penalty = "MCP", family = "binomial")
mcp_beta <- cvfit$fit$beta[, cvfit$min]
model_compare[4, ] <- mcp_beta[-1]

scadによって推定された係数

cvfit <- cv.ncvreg(X = x, y = y, penalty = "SCAD", family = "binomial")
scad_beta <- cvfit$fit$beta[, cvfit$min]
model_compare[5, ] <- scad_beta[-1]

4つの方法から推定された係数を比較する。

model_compare
                     V1       V2 V3       V4 V5          V6         V7
true model           NA       NA NA       NA NA          NA         NA
lasso          4.467528 2.375300  0 3.096532  0 -0.07315415 -0.3499353
adaptive lasso 4.664295 2.480856  0 3.335227  0  0.00000000  0.0000000
mcp            4.459921 2.533341  0 3.366028  0  0.00000000  0.0000000
scad           4.808539 2.744814  0 3.615375  0  0.00000000  0.0000000
                      V8
true model            NA
lasso          0.3801377
adaptive lasso 0.0000000
mcp            0.0000000
scad           0.0000000