医療統計学を学ぶ大学生のブログ

医療統計学、因果推論を専攻しています。R, SASユーザーです。

SASによる解析:GLMSELECTプロシジャを用いたLasso回帰

f:id:NorihiroSuzuki:20210806133624p:plain

 今回はSASのGLMSELECTプロシジャを用いて、Lasso回帰を行います。Lasso(L1正則化)、Ridge(L2正則化)は割とメジャーな手法ですが、つい最近までSASでの実装方法を知らなかったので、忘備録的にまとめます。

 

 

 Lasso(L1正則化)について

 Lassoは簡単に言うと、パラメータの推定と選択を同時に行ってくれる手法です。まずはその内容を簡単に確認します。Lassoではまず初めに以下のような線形モデルを考えます。

f:id:NorihiroSuzuki:20210806135106p:plain

 ここでyiは目的変数、xijは説明変数、解析で推定したいパラメータは係数βjとし、iはサンプルのインデックスであると仮定します。なお誤差項εは平均0、分散σ2正規分布に独立に従うとします。通常の回帰分析では、以下の式で表される残差平方和(RSS; residual sum of squares)を最小にするパラメータβjを推定します。

f:id:NorihiroSuzuki:20210806140351p:plain

 

 しかし説明変数が増えるにつれ、例えば次のような問題が浮上してきます。

  • すべてのパラメータがnonzeroであると解釈が難しい
  • overfitting など

 オッカムの剃刀やbias-variance dilenma(bias-variance trade-off)でも言われるように、モデルは複雑であればいいというわけではありません。(たとえそれが真のモデルであっても)
というわけで、この説明変数を削減する、次元を削除するために使われるのがLassoになります。

 

 Tibshiraniが1996年に提案したLassoの問題は、上記のRSSの式に以下のように条件を付けたしたものです。

f:id:NorihiroSuzuki:20210806142602p:plain

この制約条件(subject to ~)はβの凸領域を与えます。n=p=2の時のこの領域を表したものがよく見るこの図です。

f:id:NorihiroSuzuki:20210806133624p:plain

 楕円の中心がy、楕円が最適化したい関数(RSS)に対する等高線、広がりを示しています。凸領域があることによって、この領域と関数が接するのが自然と軸上になり、つまり、x1=0と疎な解を与えることが分かります。

 この最適化を与えるβはtの値に影響され、tが小さければ多くのβ(パラメータ)が0に、tが大きければ0にならないパラメータが増えます。

 

 ただこのTibshiraniによる問題よりもラグランジュの未定乗数法によって制約を設けず、罰則項付きの式として表されたほうがより一般的です。このどちらの表現でも問題としては等価であり、同じ解を与えるtとλは1対1に対応します。

f:id:NorihiroSuzuki:20210910173822p:plain

  Lasooはサンプルサイズ(n)よりもパラメータ数(p)が大きい場合であっても使える手法ではありますが、いくつか注意点が必要です。

 

 まず、式を見てもわかるようにβの大きさに関して制約をつけているため、そのβが影響を受ける説明変数xの大きさも揃える必要があります。そのためLassoを行う際には、説明変数の標準化をする必要があります。

 

 次にλをどう選ぶかということです。λの値が小さくなるほど0になるパラメータの値が増えるわけでですが、その値をどうするかについてはよく考える必要があります。一般的方法の一つは、k-Fold Cross Validation(k分割交差検証)です。これは簡単に言うと、データをk個に分け1つを教師データに、k-1個を訓練データとして、最適なλの値を探索していくという方法です。
 ただあまりにもサンプルサイズが小さすぎると、このCross Validationの分散が大きく推定結果の不確実性が増します。そのため、近年ではstability selectionといったBootstrap法を組み合わせたときの挙動を見る方法が考えられているそうです。

 

 SASでの実装

データについて

 実際にSAS StudioでLasso回帰をやってみます。今回使用するデータはSASHELP.FISHの漁獲データセットです。これは、フィンランドのLaengelmaevesi湖(Puranen 1917)で捕獲された159匹の魚の計測値のデータです。7種類の魚(bream, roach, whitefish, parkki, perch, pike, and smelt)について、下記の表のように、それぞれの魚の重さ、長さ、高さ、幅が集計されています。

詳細についてはこちら

f:id:NorihiroSuzuki:20210806155404p:plain

 

今回はこのデータのうち、Weightを目的変数に、Length1、Length2、Length3、Height、Widthを説明変数としてLasso回帰を行います。魚の種類を無視するのはよくないですが、あくまで今回はLassoを使ってみようということなので、ご容赦いただければ幸いです。

 

解析

データの標準化にはStandardプロシジャを使います。このプロシジャでは以下のように指定することで変数の標準化を行うことができます。

f:id:NorihiroSuzuki:20210806155051p:plain

 

 

サンプルデータでのLasso回帰のコードはこんな感じ

f:id:NorihiroSuzuki:20210806155127p:plain

 

GLMSELECTプロシジャでは、上記のように線形モデルを指定した後selectionの項目でどのように変数選択を行うかを指定することができます。ほかのプロシジャ含め、selectionで指定できる変数選択法は次の表のとおりです。

f:id:NorihiroSuzuki:20210806160548p:plain

なお上記の解析ではλを決めるためにCross Validationを用いています。


解析の結果はこちら。

f:id:NorihiroSuzuki:20210806160744p:plain

f:id:NorihiroSuzuki:20210806160759p:plain

このように5変数から、4変数に絞ることができました。これがもっとパラメータ数が多くなるとかなりLassoのありがたみは感じるかなと思います。

 

今回はここで終わりますが、Bootstrap法を併用した方法について勉強しているところなのでそれが理解でき次第また記事にしていきたいかなと思います。

 

コード

data df1;
set SASHELP.BASEBALL;
run;

/*データの標準化*/
proc standard data=df1 out=df2 m=0 std=1;
var nHome nAtBat nHits nRuns nRBI nBB nOuts nAssts nError;
run;

/*標準化データでのLasso回帰モデル*/
proc glmselect data=df2 seed=12345 ;
model Salary=nHome nAtBat nHits nRuns nRBI nBB nOuts nAssts nError:/selection=lasso(choose=cv steps=100 stop=none)
cvmethod=random(10) stb ;
run;