Pythonではじめる機械学習2(2.3.3~2.3.4)メモ

引き続き「Pythonではじめる機械学習」を読み進めていく。

線形モデルによる回帰

線形モデルによる一般的な予測式は下記である。
$$
\hat{y} = w[0] \times x[0] + w[1] \times x[1] + \cdots + w[p] \times x[p] +b
$$
特徴量が1つのデータであればという説明が個人的にしっくりきた。
$$
\hat{y} = w[0] \times x[0] +b
$$
多数の特徴量を持つデータに対してこそ線形モデルは強力であるらしい。線形モデルを用いた回帰にはさまざまなアルゴリズムがあり、いくつかを説明している。順を追って見ていきたいと思う。

線形回帰(通常最小二乗法)

通常最小二乗法(Ordinary Least Squares)とも呼ばれる手法がある。予測と真の回帰ターゲットyとの平均二乗誤差(Mean Squared Error)が最小になるようにwとbを求める。線形回帰にはパラメータがない。

from sklearn.linear_model import LinearRegression
lr = LinearRegression().fit(X_train, y_train)
リッジ回帰

予測に用いる式は通常最小二乗法と同じだが、リッジ回帰には係数ここではwの大きさをならべく0に近づけるように調整(制約)することができる。この調整はL2正則化と呼ばれる。
調整に用いられるパラメータはalphaであり、このalphaを増やすと係数は0に近くなり訓練セットに対する性能は低下する一方で汎化にはいいかもしれない。一般的には訓練セットにおける精度と汎化性能はトレードオフのようだ。

from sklearn.linear_model import Ridge
ridge = Ridge().fit(X_train, y_train, alpha=0.1)
Lasso

Lassoはリッジ回帰と同様にwをなるべく0になるように制約をかけるが、その方法に違いがある。リッジがL2正則化に対してLassoはL1正則化を行うようだ。
その結果いくつかの係数が0になり自動的に特徴量を選択しているかのように考えることができる。重要な特徴量のみに目を向けることができそうだ。制約を調整するパラメータはalphaでリッジと同じだ。

from sklearn.linear_model import Lasso
lasso = Lasso().fit(X_train, y_train, alpha=0.1)
ElasticNet

scikit-learnにはRidgeとLassoを組み合わせたハイブリッドモデルがある。ElasticNetはalphaの他にl1_ratioというパラメータがある。ハイブリッドなので両者の長所を活かせる可能性があるが、調整するパラメータが増えるというコストもある。

from sklearn.linear_model import ElasticNet
elastic = ElasticNet(alpha=0.1, l1_ratio=0.5)
L1正則化とL2正則化

損失関数を𝑓(𝑥)、パラメータ𝜆とししたときに、
正則化なし
$$
\min{f(x)}
$$
L1正則化
正則化を行う項はペナルティ項と呼ばれるらしい。L1正則化では係数の絶対値の合計に対して、ペナルティをかけることにより合計を小さくする。それによりいくつかの係数は0になるため、特徴量選択を行ってることに等しく次元圧縮の役割となる。
$$
\min{f(x)+\lambda\sum_{i=1}^n |w_i|}\\
$$
L2正則化
L2正則化では係数の二乗和に対してペナルティをかける。L1正則化は次元圧縮のために用いられることが多く、L2正則化過学習を防ぐために用いられることが多い。
$$
\min{f(x)+\frac{\lambda}{2}\sum_{i=1}^n |w_i|^2}\\
$$

L1,L2正則化について下記参考にさせていただきました。
正則化の種類と目的 L1正則化 L2正則化について | AVILEN AI Trend

線形モデルによるクラス分類

2クラス分類

線形モデルでクラス分類を行うこともでき、2値分類を行う場合は次の式で予測を行う。
この式で得られた値が0より大きければ一方のクラス、0より小さければもう一方のクラスへ分類するものだ。
$$
\hat{y} = w[0] \times x[0] + w[1] \times x[1] + \cdots + w[p] \times x[p] +b > 0
$$

線形モデルを学習するアルゴリズムは主に次の2点で区別される。

  1. 係数wと切片bの特定の組み合わせと訓練データの適合度を図る尺度
  2. 正規化を行うかとその方法。

主に2番目に意味があるらしい。

ロジスティック回帰(logistic regression)、線形サポートベクタマシン(linear support vector machines : SVM)

ロジスティック回帰は回帰アルゴリズムではなく、分類アルゴリズムであるらしく線形回帰と混同しないようにと記載がある。
scikit-learnのロジスティック回帰と線形サポートベクタマシンではデフォルトでL2正則化を行いパラメータCを大きくすると正則化は弱くなり、小さく設定すると正則化の影響が強くなる。penaltyという引数に"l1"を指定することでL1正則化を行うこともできる。

from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
logreg = LogisiticRegression(C=0.01).fit(X_train, y_train)
lr_l1 = LogisiticRegression(C=0.01, penalty="l1").fit(X_train, y_train)
svc = LinearSVC().fit(X_train, y_train)
線形モデルによる多クラス分類

2クラス分類に用いる線形クラス分類モデルを他クラス分類アルゴリズムに拡張する手法として1対その他アプローチというものがある。
$$
w[0] \times x[0] + w[1] \times x[1] + \cdots + w[p] \times x[p] +b
$$
1クラスにつき1つの2クラス分類器があるため、クラスごとに上記のwとbの組み合わせがある。この出力が最も大きいクラスを予測としては採用する。3クラスのデータセットに対しての例が紹介されている。linear_svm.coef_.shapeの出力は(3, 2)であり各クラスに対応する係数ベクトルがあることがわかる。linear_svm.intercept_.shapeの出力は(3,)なので各クラスのbに対応する切片があることがわかる。

from sklearn.datasets import make_blobs
from sklearn.svm import LinearSVC
X, y = make_blobs(random_state=42)
linear_svm = LinearSVC().fit(X, y)