Machine Learning with Scikit Learn (Part III)
Machine Learning with Scikit Learn (Part II)(2015/8/26)のつづき。今回は、Part IIの動画の5.1節の内容を簡単にまとめた。書いてたら長くなったので5.1節だけ。
5.1 In Depth - Linear Models
回帰のための線形モデルの詳細が取り上げられている。線形回帰は過学習(Overfitting)に弱い。過学習を回避するために正則化を導入したリッジ回帰、Lasso、ElasticNetの使い方が事例をもとに説明されている。また、線形分類器の正則化の例としてSVMとロジスティック回帰のパラメータCが説明されている。
線形回帰
まずは、単純な線形回帰から。線形回帰は、特徴量の線形結合で表されるモデル。
ここで、が係数(
coef_
)でが切片(
intercept_
)と呼ばれる。線形回帰では、教師データ から係数と切片を学習するのが目的。線形回帰はPart I(2015/8/10)の動画でも取り上げられていたけど使うのは簡単
線形回帰は特徴量に比べてサンプル数が少ないと過学習しやすく、精度が大幅に悪化するという欠点がある。横軸にサンプル数、縦軸に精度が来る学習曲線を描いてみるとよくわかる。
訓練データ数が特徴量の数(50)より少ないとき、訓練データのスコア(点線)に比べてテストデータのスコア(実線)が非常に低く、明らかに過学習していることがわかる。訓練データ数が十分あればテストスコアはどんどん改善して過学習は解消されていることもわかる。訓練データ数が少なくて過学習するときは以下に述べる様々な正則化(regularization)テクニックが使える。
リッジ回帰(ridge regression)
線形回帰にL2正則化 (L2 regularization)を加えたのがリッジ回帰。線形回帰のコスト関数に係数の2乗和の項が加わることで係数が小さくなるようなバイアスがかかる。正則化の強さは複雑度パラメータalpha
で変えられる。最適なalpha
はCross Validationで求められる。これを自動的にやってくれるRidgeCV
が用意されている。
先と同様に学習曲線を描いてみる。
plot_learning_curve(linear_model.LinearRegression(), X, y)
plot_learning_curve(linear_model.Ridge(alpha=1.0), X, y)
plot_learning_curve(linear_model.RidgeCV(), X, y)
とりあえずテストスコアだけ見てみる。訓練データ数が少ないところでは線形回帰(LinearRegression
)に比べてリッジ回帰(Ridge
)の精度がずっとよいことがわかる。さらにCross Validationで最適なalpha
を求めたRidgeCV
はさらにスコアがよくなっている。
Lasso
線形回帰にL1正則化(L1 regularization)を加えたのがLasso。線形回帰のコスト関数に係数の絶対値の和の項が加わる。Lassoは多くの係数が0になる疎な解が得られやすいという特徴がある。
本当にそうなるのかやったことなかったので試してみよう。
出力は、
[ 1.22 2.363 -2.554 -0.972 -0.596 -0.334 -1.1 0.615 -1.215 -0.895 -0.911 1.076 2.087 -1.524 0.333 -0.301 -1.239 -1.167 -2.765 -0.917 0.734 0.709 -0.362 -0.84 -0.779 -0.78 -0.425 -0.029 -0.317 0.903 -0.793 -0.221 1.691 0.329 -0.689 -1.755 0.302 0.232 1.095 2.925 0.702 -1.634 0.643 -0.976 -0.38 0.144 -0.734 0.861 -0.173 -0.238] [ 0. 1.235 -1.587 -0.049 -0. -0. -0. 0. -0. -0. -0. 0. 0.922 -0.275 0. -0. -0.066 -0. -1.755 -0. 0. 0. -0. -0. -0. -0. -0. -0. -0. 0.153 -0. -0. 0.248 0. -0. -0.532 0. 0. 0. 1.859 0. -0.125 0. -0. -0. -0. -0. 0. -0. -0. ]
上がリッジ回帰の係数で下がLassoの係数。確かにLassoを使うと多くの係数が0になることがわかる。どうしてこうなるかはPRMLにも書かれていたけどいまいち納得できていない・・・
LassoにもRidgeCV
と同じくパラメータのCross ValidationまでやってくれるLassoCV
が用意されている。
plot_learning_curve(linear_model.RidgeCV(), X, y)
plot_learning_curve(linear_model.LassoCV(n_alphas=20), X, y)
結果は、
となる。テストスコアを比べるとリッジ回帰よりLassoの方がよりスコアが高くなることがわかる。これはたまたまかも。何回か試すとスコアが逆転することもある。リッジ回帰とLassoはどうやって使い分ければよいのだろう?
ElasticNet
最後にリッジ回帰とLassoの中間に位置するElasticNet。コスト関数にL1正則化とL2正則化の項を重みづけして加えただけの手法。
ElasticNetはl1_ratio
というパラメータを取る。l1_ratio = 0.0
にするとL2ペナルティのみになりRidgeと等価になる。逆にl1_ratio = 1.0
にするとL1ペナルティのみになりLassoと等価になる。
同様にElasticNetCV
でCross Validationできる。ただし、最適化されるパラメータはl1_ratio
ではなくalpha
のようだ。l1_ratio
の最適化はまた別にCross Validationを回す必要がありそう。
plot_learning_curve(linear_model.RidgeCV(), X, y) plot_learning_curve(linear_model.ElasticNetCV(l1_ratio=0.6, n_alphas=20), X, y) plot_learning_curve(linear_model.LassoCV(n_alphas=20), X, y)
上の例ではl1_ratio
を0.6で固定している。スコアもRidgeとLassoの中間くらいになる。
RidgeとかLassoとかElasticNetって名前わかりにくい感じがした。名前を見てもどんな手法かまったく想像がつかない・・・ElasticNetはニューラルネットの仲間かと思ってたし。名前の由来は何だろうね?
余談だけどビッグデータ時代でもこういう正則化テクニックはまだ重要なのだろうか?先にも書いたけど訓練データが山ほどあれば正則化を使わなくても過学習は解消される。大量のデータがあっても教師あり学習のラベル付けの手間はかかるからまだこういう技術が必要なのだろうか。
線形分類器の正則化
線形回帰ではなく、線形分類器の正則化の例としてSVMとロジスティック回帰が取り上げられている。これらのアルゴリズムでは、パラメータCによって正則化を調整できる。
svm = SVC(kernel='linear', C=C).fit(X_train, y_train)
Cを変えたときの分類境界を描画すると下のようになる。
Cが小さいほど正則化が強まり、過学習が解消され、汎化性能が高まる。逆にCを大きくすると正則化が弱まり、過学習気味になっていく。上の例では左上の赤丸の扱いがわかりやすい。Cを大きくしていくとこの赤丸を無理やり分類しようとする様子が見て取れる。すべての訓練データをきちんと分類する傾向が高まるため過学習気味と判断できる(過学習の特徴は訓練データの精度が高く、テストデータの精度が低くなる)。
線形SVMだとあまり面白くないが、5.2節でカーネルを使った非線形SVMが取り上げられている。非線形SVMだとパラメータCによる正則化の効果が非常によくわかる。
ロジスティック回帰も正則化を制御するのにCパラメータがある。共役勾配法によるロジスティック回帰のパラメータ推定(2014/4/15)でやった。このときはパラメータCと呼んでなかったが、正則化項の重みがCにあたる。
ロジスティック回帰の最適なCをグリッドサーチで探索してみよう。
出力は
0.966666666667 {'C': 0.01}
となる。最適なCは0.01でそのときの分類精度は96.7%になる。
Part IVにつづく。