【scikit-learn】Ridge回帰

Ridge回帰は係数 wに対して min_{w}||wX-y||^{2}+\alpha||w||^{2}を満たす wを見つけるというもの.

Ridge回帰による正則化係数 \alphaと係数 wの関係を見てみる
import numpy as np
import matplotlib.pyplot as plt
import sklearn.linear_model

# 10*10の行列を作る 
X = 1. / (np.arange(1, 11) + np.arange(0, 10)[:, np.newaxis])
y = np.ones(10)

Xは

[[ 1  2  3  4  5  6  7  8  9 10]
 [ 2  3  4  5  6  7  8  9 10 11]
 [ 3  4  5  6  7  8  9 10 11 12]
 [ 4  5  6  7  8  9 10 11 12 13]
 [ 5  6  7  8  9 10 11 12 13 14]
 [ 6  7  8  9 10 11 12 13 14 15]
 [ 7  8  9 10 11 12 13 14 15 16]
 [ 8  9 10 11 12 13 14 15 16 17]
 [ 9 10 11 12 13 14 15 16 17 18]
 [10 11 12 13 14 15 16 17 18 19]]

の行列の各要素で1を割った行列なので,左上に行くほど大きく,右下に行くほど小さい値となっている0.5~1.0の行列である.
次に学習を行う.

n_alphas = 200
alphas = np.logspace(-10, -2, n_alphas)#1e-10 ~ 1e-2までを10を底とした指数で表示
coefs = []
for a in alphas:
    ridge = linear_model.Ridge(alpha=a, fit_intercept=False)#モデルの定義
    ridge.fit(X, y)#学習
    coefs.append(ridge.coef_)

ridge.fit(X,y)のところは図にするとおそらくこんな感じ.
f:id:umashika5555:20170925141927p:plain
次にプロットを行う.

ax = plt.gca()
ax.plot(alphas, coefs)
ax.set_xscale('log')
ax.set_xlim(ax.get_xlim()[::-1])  # reverse axis
plt.xlabel('alpha')
plt.ylabel('weights')
plt.title('Ridge coefficients as a function of the regularization')
plt.axis('tight')
plt.show()

出力結果は下のようになった.
f:id:umashika5555:20170925143538p:plain
これはあるαのときにおける式1-10の係数wの大きさを表している.
αが小さいとき(グラフの右に行くほど) min_{w}||wX-y||^{2}+\alpha||w||^{2} = min_{w}||wX-y||^{2}となるのでこれはほぼ線形回帰であり,係数の影響を抑えきれなくなる.
αが大きいほど(グラフの左に行くほど)wは小さくなりたがろうとするので係数の大きさはほぼ0になる.

【補足】

ベクトルの作り方
a = np.arange(0,10)
#[0,1,2,3,4,5,6,7,8,9]
b = np.linspace(0,10,6)
#[0,2,4,6,8,10]
c = np.logspace(2,5,4)
#[10**2,10**3,10**4,10**5]
d = np.ones(10)
#[1,1,1,1,1,1,1,1,1,1]
e = np.zeros(10)
#[0,0,0,0,0,0,0,0,0,0]

【参考】
http://scikit-learn.org/stable/auto_examples/linear_model/plot_ridge_path.html#sphx-glr-auto-examples-linear-model-plot-ridge-path-py