目次
1.機械学習のプロセス
2.機械学習のモデル
3.線形回帰
4.非線形回帰
5.正則化
6.ロジスティック回帰
7.ここまでの演習
8.主成分分析
9.アルゴリズム
10.サポートベクターマシン
11.後半の演習
#1 機械学習のプロセス
-
問題設定:どんな課題を解決するか。←ここが一番大切
そもそも機械学習で解決する問題なのか?
ルールベースでゴリゴリ書いた方が問題を的確に解決するケースもある。 -
データ選定
データはそもそも手に入るのか
適切なデータが手に入るか。
友達からのアンケートをもとに全国を予測。 ←データの範囲が狭すぎる
日本人のデータをもとにアメリカ人の予測をした ←母集団がだいぶ違う -
データの前処理
kaggleのカーネルは参考になる。(実データをどうやって処理するか)
モデルを作って調整してなどというのは全体の1割
ほとんどはデータの前処理。 -
モデル選定
-
パラメータ調整
-
モデル評価
#2 機械学習のモデル
教師あり
- 予測: 線形回帰・非線形回帰
- 分類: ロジスティック回帰
教師なし - クラスタリング: k近傍
- 次元削減: 主成分分析
#3 線形回帰
ルールベース vs MLモデル
トム・ミッチェル
・タスクTを性能指標Pで測定し、その性能が経験Eにより改善される
・人が認識方法をプログラムするのではなく、学習方法をプログラムする
(講師の方は、AIとは?と聞かれたら「数学」と答えるようにしている)
→ データを学習させることで出力が変化してゆく。
→ 性能指標をどう選ぶかというのはひとつの大きなテーマ
線形回帰とは
線形:ざっくりいうと、比例
$ y = ax + b $
$ z = ax + by + c $
一変数なら線形、二変数なら平面、三変数以上なら超平面
(超平面は図には描けない)
$ y = a_0x_0 + a_1x_1 + a_2x_2 \cdots + a_nx_n$
※ 上の式で、$ x_0 = 1 $ と置くとすっきり書ける
$ y = \sum a_ix_i (where x_0 = 1) $
さらにベクトルで、
y = \boldsymbol{a}^{\mathrm{T}}\cdot\boldsymbol{x}
where a =
\left(
\begin{array}{c}a_1 \\ a_2 \\ \vdots \\ a_n
\end{array}
\right)
\boldsymbol{a}^{ \mathrm{T}} = ( a_0, a_1, \cdots a_{n-1}) \\
\\
\boldsymbol{x} = \left( \begin{array}{c} x_0 \\ x_1 \\ \vdots \\ x_n \end{array} \right)
回帰問題
入力から連続の出力値を予測する。
線形回帰モデル
・回帰問題を解くためのモデル
・教師あり学習
入力とm次元パラメータの線形結合を出力するモデル。
入力(説明変数): m次元ベクトル
書籍などでは、太字で表されるのはベクトル $ \boldsymbol{x} $
黒板の板書などでは、二重線で書くことが多い。
出力(目的変数): 多くはスカラーだが、多次元の出力もやろうと思えばできる。
教師データ :$ (x_i, y_i) ; i = 1, \cdots , n $
線形結合 : 掛けて足す、掛けて足す、がベクトルの表記で書ける。
\hat{y} = \boldsymbol{w}^\mathrm{T}\boldsymbol{x} + w_0 = \sum_{j=1}^{m} w_j x_j + w_0
慣例的に、予測値には ^ ハット を付ける。
※ バプニックの原理(SVMを作った人が提唱)
解きたい問題よりも難しい問題を途中で解くべきではない、という考え方。
(密度比推定はバプニックの原理を体感するのに良い研究とのこと)
必ずしもひとつの変数で説明はできない。
(例)その日の気温だけでは来店者数は予測できない。
気温と曜日が真のモデルだとした場合、
もし気温だけでモデリングしたとしたら、曜日の情報は、誤差に乗ってくる。
※ 誤差があまりに大きい場合は、何か影響するものが考慮されていないのではないか、という考察ができるともいえる。
連立方程式
連立方程式 \\
y_1 = w_0 + w_1x_1 + \epsilon_1 \\
y_2 = w_0 + w_1x_2 + \epsilon_2 \\
\vdots \\
y_n = w_0 + w_1x_n + \epsilon_n \\
行列表現 \\
\boldsymbol{y} = \boldsymbol{w} \boldsymbol{x} + \epsilon \\
\\
以下の式を、↑ でこんなにスッキリ 書ける。\\
\left(
\begin{array}{c}
y_0 \\ y_1 \\ \vdots \\ y_n
\end{array}
\right)
=
\left(
\begin{array}{c}
1 x_1 x^{\prime} \\
1 x_2 x^{\prime} \\
\vdots \\
1 x_n x^{\prime} \\
\end{array}
\right)
\left(
\begin{array}{c}
w_0 \\ w_1 \\ w_2
\end{array}
\right)
+
\left(
\begin{array}{c}
\epsilon_1 \\ \epsilon_2 \\ \vdots \\ \epsilon_n
\end{array}
\right)
参考書籍のおすすめ
機械学習のエッセンス 数学、最適化、E資格の機械学習の範囲とだいたい一致しているとのこと。
フレームワークなしで作れるかどうかを問われるようなところ。
(第4版以降がよい)
データの分割と汎化性能測定
学習データと検証データを必ず分ける!
クロスバリデーションなど。(後述)
またまた参考書籍のおすすめ
イラストで学ぶ機械学習(杉山さんの本)
損失関数に焦点をあてている
ここで線形回帰に話を戻す。
最小二乗法
線形回帰モデルで重みを決めるのは最小二乗法。
・平均二乗誤差(残差平方和)を最小にするアルゴリズム
$$ \sum(\hat{y}_i - y_i)^2 = \sum\epsilon^2 $$ と書ける。
MSE (Mean Squared Error)
$$ MSE_{train} = \frac{1}{n_{train}}\sum_{i=1}^{n_{train}}
(\hat{y}_i^{train}-y_i^{train}) $$
これは w の関数 J(w) ← これを最小にするのが目的
※ 二乗損失は一般的に外れ値には弱い。
※ Huber損失とかTukey(テューキー)損失、というものもある。
右辺が2次関数になっているので、下に凸の関数なので最小値をとれば誤差を最小化できる。
$$ \hat{w} = \arg \min MSE_{train} $$
MSE を 最小化するための、w(入力)を返して、という意味
(MSEの最小がほしいわけではない)
$$ \frac{\partial}{\partial w} \lbrace (\frac{1}{n_{train}} \sum_{i=1}^{n_{train}}(\hat{y}_i - y_i)^2 ) \rbrace = 0 $$
偏微分で求める。
ここで使用したベクトルの微分の法則
$$
\frac{\partial(\boldsymbol{w}^T\boldsymbol{x})}
{\partial\boldsymbol{w}}
= \boldsymbol{x} $$
$$
\frac{\partial(\boldsymbol{w}^T A \boldsymbol{x}}
{\partial \boldsymbol{w}} = ( A + A^T ) \cdot \boldsymbol{x} = 2A \boldsymbol{x}
$$
# 単純な線形回帰の実装
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def linear(n_size):
# 真のデータを生成する関数
def base_func(x):
return 1.5 * x + 6
# 学習データ生成
def fractuate(y_base):
return y_base + np.random.normal(scale=0.3, size=y_base.shape)
x_train = np.linspace(0, 1, n_size)
y_base = base_func(x_train)
y_train = fractuate(y_base)
#学習
def train(x, y):
cov = np.cov(x, y, ddof=0)
a = cov[0, 1] / cov[0, 0]
b = np.mean(y) - a * np.mean(x)
return cov, a, b
cov, a, b = train(x_train, y_train)
#予測
#xs_new = np.linspace(0, 1, n_sample)
ys_pred = a * x_train + b
#結果の描画
plt.scatter(x_train, y_train, facecolor="none", edgecolor="b", s=50, label="training data")
plt.plot(x_train, y_base, label="$1.5 x + 6$")
plt.plot(x_train, ys_pred, label=f"prediction (a={a:.4}, b={b:.4}), dat_size{n_size}")
plt.legend()
plt.show()
linear(10)
linear(20)
linear(40)
linear(60)
linear(80)
linear(100)
linear(120)
linear(140)
※ データ数を増やしてゆくと、結果が安定することを確認した。
(当てはまりがよくなっていくことが多くなる)
#4 非線形回帰
単回帰 w0 + w1x
重回帰 w0 + w1x1 + w2x2 ... wnxn
非線形回帰は、
$$ w_0 + w_1\phi_1(x1) + w_2\phi_2(x2) \cdots w_n\phi_n(x_n) $$
こういう形になる。
xを入力とする関数がある。 この$ \phi $ を 基底関数 と呼ぶ
xについては非線形だが、wに関しては線形である。
☆Gauss型基底関数の例
(正規分布の式のようなもの)
話戻る
やっていることは線形回帰とほとんど同じ。
直接xをつかうのではなく、xを$\phi$の空間に飛ばしてから使う、という違い。
結局MSEを最小化するwはさっきと同じ。
線形回帰 : $ \hat{w} = (x^Tx)^{-1}x^Ty $
非線形回帰: $ \hat{w} = (\Phi^T\Phi)^{-1}\Phi^Ty $
☆☆ 重要用語 ☆☆
未学習(=underfitting):モデルの表現力不足。
→(解決策)表現力の高いモデルを使用する。
過学習(=overfitting) :学習データを学習しすぎている状態
学習時の誤差は小さくできたが、テスト時の誤差が大きい
→(解決策)データを増やす。
不要な変数や基底関数を除去して表現力を抑止。
(どこまで削ればよいのかは難しい)
(赤池情報量基準AICなどを使用する)
正則化を利用して表現力を抑止。
#5 正則化
必ず本に載っているけど理解できている人は少ない(?)とのこと
予測: $ \hat{y} = X* (X^TX)^{-1}X^Ty $
アスタがついているのは、新しいデータ(予測するための)という意味。
wが大きくなってしまうとき。
逆行列が計算できない。一次独立になっていない、ほぼ平行とか。
こんな場合にwを大きくさせないようにするために、罰則項を設ける。
$ E(w) = J(w) + λ・w^T・w $
λはハイパーパラメータ。
MSEの等高線を広げていって、ぶつかったところを推定量とする。
(L2は円、L1は正方形のお馴染みの図)
#6 ロジスティック回帰
\sigma(\cdot)はシグモイド関数。 \\
\sigma(h) = \frac{1}{1 + \exp{(-h)}}で定義される。
訓練データ \\
X = [\boldsymbol{x}_{1}, \boldsymbol{x}_{2}, ..., \boldsymbol{x}_{n}]^{\mathrm{T}}, \boldsymbol{y} = [y_{1}, y_{2}, ..., y_{n}]^{\mathrm{T}} (y_{i} = \{0, 1\}) に対して \\
尤度関数 L は以下のように書ける。
L(\boldsymbol{w}) = \prod_{i=1}^{n} p(y_{i}=1 | \boldsymbol{x}_{i}; \boldsymbol{w})^{y_{i}} (1 - p(y_{i}=1 | \boldsymbol{x}_{i}; \boldsymbol{w}))^{1 - y_{i}}
負の対数尤度関数は
- \log{L(\boldsymbol{w})} = - \sum_{i=1}^{n} \left[ y_{i} \log{p(y_{i}=1 | \boldsymbol{x}_{i}; \boldsymbol{w})} + (1 - y_{i}) \log{(1 - p(y_{i}=1 | \boldsymbol{x}_{i}; \boldsymbol{w}))} \right]
のように書ける。 これを最小化する$\boldsymbol{w}$を求める。
ポイント
この負の対数尤度関数を偏微分して0となるようなwを求める。
しかし、このwは今までの線形回帰などのように、
一発で(解析的に)もとめられないので、
データから繰り返し学習してwの値を更新することで最適解に近づけていく手法を取る。
\boldsymbol{w} \leftarrow \boldsymbol{w} - \eta \frac{\partial }{\partial \boldsymbol{w}} (-\log{L(\boldsymbol{w})})
#7 ここまでの演習
・ボストン住宅予測のsklearnを使用した線形回帰
(その他のモデルとの比較)
・線形回帰のnumpy.covを使った実装
・線形回帰の行列バージョンを使った実装
・ロジスティック回帰を教材を参考にして実装
ノートブック
https://github.com/rkti498/e_shikaku/blob/main/02_machine_learning_enshu.ipynb
表示されない場合はこちら
https://nbviewer.jupyter.org/github/rkti498/e_shikaku/blob/main/02_machine_learning_enshu.ipynb
(githubのノートブックが表示されない場合、nbviewerで開くためのURL)
★ ここまでの考察
線形回帰とロジスティック回帰の数式の行列ベクトル計算は、手計算と実装を両方行ったことで理解が深まり、
必要な計算の流れは把握できたと思う。講義で詳しい式変形を解説してくれていたため、大変理解しやすかった。
しかし全てに渡り詳細な説明があるわけではないので、必要なところは調べつつ理解した。
実装の方は、scikitを使ってしまうと中身が分からないのでnpでの実装のサンプルコードを参考に模倣的に実装を行うことでこちらも理解が深まった。可視化のコードなども参考になった。
#8 主成分分析
学習データはm次元ベクトルのn個のセットとする。
x_11, x_12, x_13... x_1m
x_21, x_22, x_23... x_2m
:
x_n1, x_n2, x_n3... x_nm
やりたいこと:
次元を削減(情報の縮約)を行い、全体を簡潔に説明すること。
作業内容的には、数多くの変数から新しい概念の変数を作ること。
このような散布図で、オレンジの先のような1次元のデータに圧縮すれば、
2変数の事象を1変数で簡潔に説明できる。(たとえばBMIなどは2変数(身長体重)の事象を1変数(肥満率のようなもの)で説明しているようなイメージ)
分散が最大になるような方向に縮約すること。
一つだけでなく、第一主成分、第ニ主成分、..... と m個分の主成分が導き出される。
計算手順
それぞれの平均を引いて、平均が0になるようにする。(標準化)
右上のようなデータがあったとして、横軸の平均が2.47
縦軸の平均が3.57だった場合にそれぞれの平均を引くことで、左下のデータに移動させている。横軸縦軸の平均がそれぞれ0になる
★ 線形変換後に、「分散が最大になる射影軸」、を考える
線形変換とは、y = x を y' = ax + b のように係数を掛けること。
線形回帰のw(重みベクトル)のようなものを想定
これを今回は 「a」 とする
標準化しているので、分散は例えば3次元なら
p1 = a1x_11 + a2x_12 + a3x_13
p2 = a1x_21 + a2x_22 + a3x_23
:
pm
S_p^2 = \frac{1}{n} \{ (p1-\bar{p})^2 + (p2-\bar{p})^2 + (p3-\bar{p})^2 ... (pm-\bar{p})^2 \} \\\
こんな s_p^2 を最大にする 「a」 を考える。
標準化されているので \bar{p} は 0 なので 実質的にはこれ。
$$
S_p^2 = \frac{1}{n}(p1^2 +p2^2 + p3^2 ... pm^2)
$$
このようにaを使って線形変換したときにSが最大になる a を考える。
制約条件はaベクトルを2乗して足したときに1になるようなものとする。
このような制約付きの最適化問題を解くときには、
ラグランジュの未定乗数法 を使用する
ラグランジュの未定乗数法
$ minimize f(x) subject to g(x) = 0 $
$ L(x, λ) = f(x) - λg(x) $
$ Lはラグランジュ関数 $
$ λはラグランジュ乗数 $
(つくば大学の機械学習オープンコースの講義より)
つまり
L(a_j) = a_j^T Var(\bar{X}) a_j - λ(a_m^T a_j - 1) \\
と表せる。\\
\\
\\ \\
このLをa_jで微分すると、 \\
\frac{\partial L}{\partial a_j} = 2Var(\bar{X})a_j-2λa_j=0 \\
よって \\
Var(\bar{X})a_j = λa_j \\
これはどこかで見たことある形である。 \\
\\
A\vec{x}=\lambda\vec{x} \\
これは固有値分解の導入時の数式。(λは固有値ベクトル)
このことから、主成分分析は、分散共分散行列の固有値分解の問題であるといえる。
最大m個の、固有値・固有ベクトルのペアが出現する。
#9 アルゴリズム
k近傍法(kNN)(k Nearest Neighbor)
教師あり学習のための分類アルゴリズムの中で最も単純なアルゴリズムの一つ
教師データからは学習しない。教師データからパラメーターを調整(今までのアルゴリズムで出てきた重みをもとめるような工程)することがない。
怠惰学習(lazy learner)とも言われている。
任意の k を決める。
例えば k=3 の場合
赤い点からユークリッド距離が近い順から3つの点を選び、その3つの多数決によって赤い点をどのクラスに分類するかを決める。
POINT
・kを大きくすると決定境界は滑らかになる
・単純なアルゴリズムだが、説明がしやすいし、理解もしてもらいやすいというメリットがある。
・次元が大きくなるにつれてどのデータとの距離も大きくなってしまい、どれも似たような距離になってしまうので意味をなさなくなることがある。
・距離は、通常はユークリッド距離で計算する。(マンハッタンを使うこともある)
k-means(k平均法)
クラスタリングの代表選手 教師なし学習の分類アルゴリズム
事前準備 分けたいクラス数 k を決める。
手順1 k個の点を「クラスタ中心点」としてランダムに初期値として設定する
手順2 各データ点から、それぞれクラスタ中心点への距離を計算し、最も距離が近いクラスタに割当てる。
手順3 各クラスタの重心(平均ベクトル)(中心)を計算する。
手順4 手順2,3を収束するまで繰り返す。
★k-meansの問題点
初期値によっては、「局所最適解」に陥る
明らかに分類できていない状態なのに、初期値が近いところにあったりするとうまく分類できなくなる。
https://aiacademy.jp/media/?p=254
k-meansを可視化しているページ
http://tech.nitoyon.com/ja/blog/2013/11/07/k-means/
#10 サポートベクターマシン
- 汎化性能が高い
- 応用分野が広い
- 一時期かなり流行した。(ディープラーニングが流行る前)
デメリット:計算コストが大きく、大規模データだと時間がかかりすぎるため適さない
主に2値分類を行うが、他クラス分類や回帰にも拡張できる。
###ハードマージン
マージン最大化を行う。
マージンとは2つの種類のクラスの間に引かれるちょうどよい感じの線(線形判別関数、決定境界関数)と、
その線と最も近いデータの距離のこと。
線形判別関数(決定境界関数)の直線を
$ W^Tx_i+b=0 $
このように定義すると、
黄色(クラス1($ K_1 $)) : $ W^Tx_i+b > 0 $ となるデータ集合
ピンク(クラス2($ K_2 $)): $ W^Tx_i+b < 0 $ となるデータ集合
といえる。つまりこうなる。
$ x_i \in K_1 \iff W^Tx_i+b > 0 $
$ x_i \in K_2 \iff W^Tx_i+b < 0 $
(例えば2次元の場合だと、px + qy + b = 0 のような直線のこと)
マージンは、数Ⅱの、点と直線の距離の公式を使って算出する。
$ d = \frac{|x_1w_1 + x_2w_2 + ... + x_nw_n|}{\sqrt{w_1^2 + w_2^2}} = \frac{|\boldsymbol{W}^T\boldsymbol{x} + b|}{||\boldsymbol{\omega}||}$
さらに、ラベル変数$ t_i $ を用いて、クラス1なら1を掛ける、クラス2なら-1を掛ける、として、
絶対値を外して、マージン最大化の式はこうなる。
$ \max M, \frac{t_i(w^Txi+b)}{||\omega||} \geqq M, (i =1, 2, ..., n $)
(とくに判別境界に一番近いデータ(これをサポートベクトルと呼ぶ)の場合は、等号が成り立つ)
※ ここからいろいろ式変形。
2番目をMで割る。
$ \frac{w}{w||\omega||} $ と $ \frac{w}{b||\omega||} $ をそれぞれ $ \tilde{\omega}, \tilde{b} $ とする。
すると
$ \frac{ t_i(\tilde{\boldsymbol{w}^T\boldsymbol{x}_i+\tilde{b}}) }{||\tilde{\omega}||} \geq 1 $ がすべてのデータについて成立する。
上記の変形と、さらに、今回の場合、最大を求めることと逆数の最小を求めることが同値になっているので
マージン最大化の式は、このように変形できる。
$ \min \frac{1}{2}||w||^2, t_i(\boldsymbol{w}^T\boldsymbol{x}_i+b) \geq 1, (i=1, 2, ..., n) $
ここで見やすさのためにチルダは敢えて書いていない。
ここまでハードマージン
ソフトマージンは、境界がはっきりと判別できないようなときに少し緩くする手法。
上記の式の「$ \geq 1 $」だと厳しいので、すこし余裕をもたせる。
こここで、スラック変数 を使う。
ギリシャ文字の $ \xi $ (グザイ) を使用する。
$ t_i(w^Txi+b) \geq 1 - \xi ← スラック変数 $
スラック変数の定義
$ \xi = \max \lbrace 0, M - \frac{t_i(w^Txi+b)}{||\omega||} \rbrace $
0以下にならないようにしている。
ソフトマージンの最適化問題
$ \min \ \lbrace \ \frac{1}{2}||w||^2 + C \sum_{i=1}^n\xi_i \ \rbrace $
制約条件
$ t_i(w^Txi+b) \geq 1 - \xi $
$ \xi \geq 0 , \ i=1, 2, ... n $
そして最終的に以下の双対問題を解くことになる。
$ \max \ \lbrace \ \tilde{L}(\alpha) = \sum_{i=1}^n \alpha_i - \frac{1}{2} \sum_{i=1}^n \sum_{j=1}^n \alpha_i \alpha_j y_i y_j \boldsymbol{x_i}^T \boldsymbol{x_j} \rbrace $
$ \sum_{i=1}^n \alpha_i y_i = 0, \ \ 0 < \alpha_j < C, \ \ i = 1, 2, ..., n $
☆ ラグランジュの未定乗数法
PCAでやったときと少し形が違う。
λ(および制約条件の式)はひとつだったが、今回は、複数ある。
でもほぼ同じ考え方(偏微分して連立を解く)で計算できる。
カーネル法
線形から非線形へ。
入力空間 →(写像)→ (高次元)特徴空間
一般に入力間に次元のデータを高次のr次元特徴空間に変換する関数
$ \phi(\boldsymbol{x})=(\phi_1(\boldsymbol{x}, \boldsymbol{x})) $
例えば $ \boldsymbol{x} = (x1, x2) を高次元に写像するとき $
$ \phi(\boldsymbol{x} = (x_1^2, x_2^2, x_1x_2, x_1, x_2) $
このように5次元に拡張したりできる。
そこで前述の最適化問題(双対問題)を解く。
($ \phi $ で一部書き換えている)
$ \max \ \lbrace \ \tilde{L}(\alpha) = \sum_{i=1}^n \alpha_i - \frac{1}{2} \sum_{i=1}^n \sum_{j=1}^n \alpha_i \alpha_j y_i y_j \phi(\boldsymbol{x_i})^T \phi(\boldsymbol{x_j}) \rbrace $
$ \sum_{i=1}^n \alpha_i y_i = 0, \ \ 0 < \alpha_j < C, \ \ i = 1, 2, ..., n $
ここで問題になるのは、
$ \phi(\boldsymbol{x_i})^T \phi(\boldsymbol{x_j}) $ は次元rが大きい場合は計算が困難となること。(時間がかかりすぎる)
そこでカーネル法を使う。
$ \phi(\boldsymbol{x}) $ を直接計算しなくても済ませる方法。
ある特定の条件を満たす関数を使うと、 $ \phi(\boldsymbol{x}) $ を計算せずに $ \phi(\boldsymbol{x})_i^T \phi(\boldsymbol{x})_j^T $ を計算できる。
このような関数を、 カーネル関数 という。
よく使われるカーネル関数
☆ ガウスカーネル
☆ 多項式カーネル
☆ シグモイドカーネル
多クラス分類への応用
2クラス分類器を複数組み合わせてなんとかする方法と、
他クラス分類可能なモデルに拡大する方法と、2つある。
回帰問題への拡張
- $ \varepsilon $ - 不感損失関数という損失関数を使う。
- カーネル法によって非線形回帰を効率化する(?)
- ただしSVMの回帰は特異なモデルなので、一般的には最小二乗法+正則化がよく使われている。
#11 後半の演習
・主成分分析
・サポートベクターマシン
ノートブック
https://github.com/rkti498/e_shikaku/blob/main/02_machine_learning_enshu02.ipynb
表示されない場合はこちら
https://nbviewer.jupyter.org/github/rkti498/e_shikaku/blob/main/02_machine_learning_enshu02.ipynb
(githubのノートブックが表示されない場合、nbviewerで開くためのURL)