一般化線形モデルのラッソとリッジでの推定量算出・予測

しばらく更新が止まってブログが死にかけていましたけど、今やっていることや調べたこと、考えていることをちょいちょい外に書き出していかないといけないなと改めて思い直したのでつらつらと書いていきます。ツッコミ等は歓迎ではありますが、お手柔らかにお願い致します。

### 一般化線形モデルとは何ぞや

略称は GLM (Generalized liner model) で、正規分布以外の分布を扱えるように線形回帰を拡張したモデルです。

### ラッソ、リッジとは何ぞや

ラッソは一般化線形モデルを推定するための正規化手法です。詳しい説明としては以下のリンク先が正確。

[一般化線形モデルの Lasso および Elastic Net](http://jp.mathworks.com/help/stats/lasso-regularization-of-generalized-linear-models.html#btdy0d0-1)

ラッソ・リッジ共に推定された係数のサイズを制約する「ペナルティ」があることにより疎な解を得ることができるという特徴があります。

この辺は[前](http://qiita.com/ynakayama/items/9c5867b6947aa41e9229)もちょっとだけ書いたのですが、ラッソでは縮小推定機なので使わない変数があることを仮定しています。ラッソ推定器は通常の最尤推定量よりも誤差が小さくなり、一般的には最小二乗法より良い推定や予測が得られます。

リッジ回帰もペナルティを儲けて可学習を防ぐ方法で、いくつかの説明変数間に相関が強く多重共線性を防ぎたいときに有効です。

ラッソにおいて [scikit-learn](http://scikit-learn.org/) による実装では以下のようになっています。

```math
(1 / (2 * n_samples)) * ||y - Xw||^2_2 + alpha * ||w||_1
```

複雑性を排して少数の選択された説明変数を入れることによりシンプルなモデルを作りたいというときにこいつの出番というわけです。

正則化項 λ が 0 だと最小二乗法と一致します。
λ が小さいとペナルティが緩いので複雑、大きいとペナルティがきついのでシンプルなモデルになります。

なお、正則化項の決め方としては[交差検定](https://ja.wikipedia.org/wiki/%E4%BA%A4%E5%B7%AE%E6%A4%9C%E8%A8%BC)いわゆるクロスバリデーションがあります。

## scikit-learn を利用したラッソ、リッジ

sklearn では sklearn.linear_model の下に Lasso と Ridge が実装されています。

なので

```py3
import sklearn.linear_model as lm
```

なんてやると lm.Lasso のように呼び出せるようになったりします。

### Lasso
http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html#sklearn.linear_model.Lasso

Lasso インスタンス生成時にいくつかのパラメータがあります。

* alpha はペナルティで上で説明している λ にあたります。
* fit_intercept は切片で False にすると使われません。
* normalize を True にすると回帰式計算の前に最適化されます。

本当にそのままなので、あとは上のリンクから公式ページを見てください。
以下もなぞっただけですが

```py3
from sklearn import linear_model
clf = linear_model.Lasso(alpha=0.1)
clf.fit([[0,0], [1, 1], [2, 2]], [0, 1, 2])
#=> Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,
#         normalize=False, positive=False, precompute=False, random_state=None,
#         selection='cyclic', tol=0.0001, warm_start=False)
print(clf.coef_)
#=> [ 0.85  0.  ]
print(clf.intercept_)
#=> 0.15
```

fit メソッドでフィッティング (学習) 、 predict メソッドで予測というのはいつも通りです。

### Ridge
http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html#sklearn.linear_model.Ridge

```py3
from sklearn import linear_model
clf = linear_model.Ridge (alpha = .5)
clf.fit ([[0, 0], [0, 0], [1, 1]], [0, .1, 1]) 
#=> Ridge(alpha=0.5, copy_X=True, fit_intercept=True, max_iter=None,
#=>       normalize=False, solver='auto', tol=0.001)
clf.coef_
#=> array([ 0.34545455,  0.34545455])
clf.intercept_ 
#=> 0.13636...
```

```py3
from sklearn.linear_model import Ridge
import numpy as np
n_samples, n_features = 10, 5
np.random.seed(0)
y = np.random.randn(n_samples)
X = np.random.randn(n_samples, n_features)
clf = Ridge(alpha=1.0)
clf.fit(X, y) 
#=> Ridge(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=None,
#         normalize=False, solver='auto', tol=0.001)
```

そして scikit-learn にはこれを応用したラッソ交差検定 [LassoCV](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LassoCV.html#sklearn.linear_model.LassoCV) やラッソ回帰 [LassoRegression](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression) 、同じく [RidgeCV](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RidgeCV.html#sklearn.linear_model.RidgeCV) や [RidgeRegression](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RidgeClassifier.html#sklearn.linear_model.RidgeClassifier) 他にも[線形モデル](http://scikit-learn.org/stable/modules/classes.html#module-sklearn.linear_model)のいろいろな実装がなされているのでこのあたりを見ながらパラメータをチューニングして適切なモデルを探っていくことになります。

今回は以上です。