前回,前々回から何が異なるのか?ほぼ同じです.1, 2次元が$D$次元になっただけです.
とはいえ,今回は今後の勉強のためにはとても重要な回になります.実用上は1次元や2次元の問題などないわけで,常に次元は問題によるからです.一般化して定式化し,何次元の問題でも同じコードを使えるようにすることが必要ですね.そのため,今回の教材のほとんどはコードではなく数式になります.ご容赦!
1次元の直線モデル,2次元の面モデルは,いずれも線形回帰モデルの一種です.$D$次元の線形回帰モデルは次のように表すことができます.
$$ y({\bf x}) = w_0 x_0 + w_1 x_1 + w_2 x_2 \cdots + w_{D-1} x_{D-1} + w_D $$最後の$w_D$はいわゆる切片なので,$x$は付きません.この式をベクトルで表せば,
$$ y({\bf x}) = \begin{bmatrix} w_0 & w_1 & \cdots & w_{D-1} & w_D \end{bmatrix} \begin{bmatrix} x_0 \\ x_1 \\ \vdots \\ x_{D-1} \\ 1 \end{bmatrix} = {\bf w}^T {\bf x} $$となります.まあ,${\bf w}$と${\bf x}$を逆にしてもいいのですが,いくつかの教科書に従ってこうしておきましょう.
ここで混乱しないように念を押しておきます.データベクトルである${\bf x}$は「1つのデータで1つのベクトル」です.要素である$x_0, x_1, \cdots, x_{D-1}$はある学生の身長,体重,BMI,体脂肪率,...であり,別の学生のデータは別のベクトルです.カリフォルニアのあるブロックの所得や家の築年数,ベッドルームの数などはベクトルの要素であり,ブロックAのデータが1つのベクトル,ブロックBのデータが別のベクトル...です.つまり,ブロックの数だけベクトルがあるのであり,学生の数だけベクトルがあるのです.したがって,${\bf x}$には本来添え字が付きます.データ番号(ブロック番号や学籍番号)に対応する添え字です.
次にやることは損失関数の定義です.色々変えると混乱するのでここでもMSEにしておきます.損失関数$J$は${\bf w}$の関数です.忘れないようにしてください.
$$ J({\bf w}) = \frac{1}{N} \Sigma_{n=0}^{N-1} \left( y({\bf x}_n) - t_n \right)^2 = \frac{1}{N} \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right)^2 $$$n$はデータの番号(ブロック番号,学籍番号など)です.注意すべきことは,${\bf x}_n$と${\bf w}$はベクトルですが,$y({\bf x}_n)$と$J({\bf w})$はスカラーだということです.$J$を最小化するような${\bf w}$を見つけるのですから,やることは偏微分です.$J$を$w_i$で偏微分しましょう.
$$ \frac{\partial J}{\partial w_i} = \frac{1}{N} \Sigma_{n=0}^{N-1} \frac{\partial}{\partial w_i} \left( {\bf w}^T {\bf x}_n - t_n \right)^2 = \frac{2}{N} \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) x_{n,i} $$$i$は0からいくらの範囲を動きますか?$N$ですか?$D$ですか?$D-1$ですか?考えてみましょう.
$x_{n,i}$はベクトル${\bf x}_n$のi番目の要素,という意味で使いました.あらゆる$i$について,
$$ \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) x_{n,i} = 0 $$となるような${\bf w}$を見つけるのがここでの仕事です.つまり,
$$ \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) x_{n,0} = 0 $$$$ \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) x_{n,1} = 0 $$$$ \vdots $$$$ \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) x_{n,D-1} = 0 $$を満たす${\bf w}$を探します.
そろそろ感づかれるかもしれませんが,このような式が出てきたら,エレガントに行列とベクトルの積で記述するのが近道です.どうでしょう.パッとわかりますか?各式は$\Sigma$が付いているので,前回,前々回の内容を覚えていれば,ベクトルの内積で書けそうだ,というのは気づくかもしれません.では$i=0$の場合だけ,ベクトルで書いてみましょう.
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 - t_0 & {\bf w}^T {\bf x}_1 - t_1 & \cdots & {\bf w}^T {\bf x}_{N-1} - t_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} \\ x_{1,0} \\ \vdots \\ x_{N-1,0} \end{bmatrix} = 0 $$では,$i=1$は??
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 - t_0 & {\bf w}^T {\bf x}_1 - t_1 & \cdots & {\bf w}^T {\bf x}_{N-1} - t_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,1} \\ x_{1,1} \\ \vdots \\ x_{N-1,1} \end{bmatrix} = 0 $$じゃあ,$i=D-1$は?
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 - t_0 & {\bf w}^T {\bf x}_1 - t_1 & \cdots & {\bf w}^T {\bf x}_{N-1} - t_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,D-1} \\ x_{1,D-1} \\ \vdots \\ x_{N-1,D-1} \end{bmatrix} = 0 $$ということは,両辺をそれぞれ横に並べると...
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 - t_0 & {\bf w}^T {\bf x}_1 - t_1 & \cdots & {\bf w}^T {\bf x}_{N-1} - t_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} & x_{0,1} & x_{0,D-1}\\ x_{1,0} & x_{1,1} & x_{1,D-1}\\ \vdots & \vdots & \vdots \\ x_{N-1,0} & x_{N-1,1} & x_{N-1,D-1} \end{bmatrix} = 0 $$になりました.もう少しです.
左側のベクトルには${\bf w}^T {\bf x}$の項と$t$の項があるので分けてみます.
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 & {\bf w}^T {\bf x}_1 & \cdots & {\bf w}^T {\bf x}_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots & x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots & x_{1,D-1}\\ \vdots & \vdots & \vdots & \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots & x_{N-1,D-1} \end{bmatrix} - \begin{bmatrix} t_0 & t_1 & \cdots & t_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots &x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots &x_{1,D-1}\\ \vdots & \vdots & \vdots & \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots &x_{N-1,D-1} \end{bmatrix} = 0 $$左辺第2項は次のように書き換えられますね.
$$ {\bf t}^T \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots& x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots& x_{1,D-1}\\ \vdots & \vdots & \vdots& \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots& x_{N-1,D-1} \end{bmatrix} , {\rm ただし} {\bf t} = \begin{bmatrix} t_0 \\ t_1 \\ \vdots \\ t_{N-1} \end{bmatrix} $$そして左辺第1項は,
$$ {\bf w}^T \begin{bmatrix} {\bf x}_0 & {\bf x}_1 & \cdots & {\bf x}_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots& x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots& x_{1,D-1}\\ \vdots & \vdots & \vdots& \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots& x_{N-1,D-1} \end{bmatrix} = {\bf w}^T \begin{bmatrix} {\bf x}_0 & {\bf x}_1 & \cdots & {\bf x}_{N-1} \end{bmatrix} \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots& x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots& x_{1,D-1}\\ \vdots & \vdots & \vdots& \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots& x_{N-1,D-1} \end{bmatrix} $$になります.
以上より,
$$ {\rm X} = \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots& x_{0,D-1}\\ x_{1,0} & x_{1,1} & \cdots& x_{1,D-1}\\ \vdots & \vdots & \vdots& \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots& x_{N-1,D-1} \end{bmatrix} $$とすれば,
$$ {\bf w}^T {\rm X}^T {\rm X} - {\bf t}^T {\rm X} = {\bf 0} $$に集約されます.右辺は零ベクトルなのでご注意ください.
ふぅ,やっと終わった,よかったよかった...ではありません.やるべきことは,この式を満たす${\bf w}$を見つけることですから,まだやることがあります.両辺転置します.
$$ \left( {\bf w}^T {\rm X}^T {\rm X} - {\bf t}^T {\rm X} \right)^T = {\rm X}^T {\rm X} {\bf w} - {\rm X}^T {\bf t} = {\bf 0} $$後は逆行列を左からかけるだけです.
$$ {\bf w} = \left( {\rm X}^T {\rm X} \right)^{-1} {\rm X}^T {\bf t} $$できた!!!!やっとです.${\rm X}^T {\rm X}$は必ず正方行列になります(納得できます?).だから逆行列を定義できます.
何かおかしいのに気づきましたか?${\bf w}$って何次元ベクトルでした?$D$次元ベクトルではなく,$D+1$次元ベクトルだったはずです.
$$ y({\bf x}) = \begin{bmatrix} w_0 & w_1 & \cdots & w_{D-1} & w_D \end{bmatrix} \begin{bmatrix} x_0 \\ x_1 \\ \vdots \\ x_{D-1} \\ 1 \end{bmatrix} = {\bf w}^T {\bf x} $$だったのですから.どこで消えたのでしょうか?それは偏微分の所です.${\bf x}$の$D+1$番目の要素は1ですから,
$$ \frac{\partial J}{\partial w_D} = \frac{1}{N} \Sigma_{n=0}^{N-1} \frac{\partial}{\partial w_D} \left( {\bf w}^T {\bf x}_n - t_n \right)^2 = \frac{2}{N} \Sigma_{n=0}^{N-1} \left( {\bf w}^T {\bf x}_n - t_n \right) = 0 $$です.つまり,
$$ \begin{bmatrix} {\bf w}^T {\bf x}_0 - t_0 & {\bf w}^T {\bf x}_1 - t_1 & \cdots & {\bf w}^T {\bf x}_{N-1} - t_{N-1} \end{bmatrix} \begin{bmatrix} 1 \\ 1 \\ \vdots \\ 1 \end{bmatrix} = 0 $$です.こう考えれば,あまり難しいことはありません.意識してこなかった${\bf x}_n$の$D+1$番目の要素をちゃんと考えればいいのですから,
$$ \begin{bmatrix} x_{0,D} \\ x_{1,D} \\ \vdots \\ x_{N-1,D} \end{bmatrix} = \begin{bmatrix} 1 \\ 1 \\ \vdots \\ 1 \end{bmatrix} $$にして,${\rm X}$に追加してしまえばいいのです.結局は${\rm X}$の中身が変わるだけなのです.
$$ {\rm X} = \begin{bmatrix} x_{0,0} & x_{0,1} & \cdots & x_{0,D-1} & x_{0,D} \\ x_{1,0} & x_{1,1} & \cdots & x_{1,D-1} & x_{1,D} \\ \vdots & \vdots & \vdots & \vdots & \vdots \\ x_{N-1,0} & x_{N-1,1} & \cdots & x_{N-1,D-1} & x_{N-1,D} \end{bmatrix} $$としたうえで,
$$ {\bf w} = \left( {\rm X}^T {\rm X} \right)^{-1} {\rm X}^T {\bf t} $$ですね.$\left( {\rm X}^T {\rm X} \right)^{-1} {\rm X}^T$をムーア・ペンローズの疑似逆行列と言います.
import pandas as pd
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing['target']
df.plot.scatter( x='MedInc', y='MedHouseVal', c='k' )
<AxesSubplot:xlabel='MedInc', ylabel='MedHouseVal'>
やろうとしているのは,この散布図に直線を引くことですが,1次元の「1」とか,1+1の「2」という数字を陽に使わずにやろうということですね.
import numpy as np
def linear_reg( x, t ):
'''
x: 説明変数ベクトル/行列
t: 目的変数ベクトル
'''
N = x.shape[0]
D = t.shape[1]
e = np.ones_like( x )
Xmat = np.hstack( (x,e) )
mp = np.linalg.inv(Xmat.T@Xmat)@Xmat.T
return mp@t, mp
N = df.MedInc.values.shape[0]
x = df.MedInc.values.reshape((N,1))
t = df.MedHouseVal.values.reshape((N,1))
w, mp = linear_reg( x,t )
w
array([[0.41793849], [0.45085577]])
どうでしょうか?それっぽい係数が得られていますか?関数linear_reg
の中では1や2を直打ちしていません.適切な行列x
とt
を関数に与えれば,然るべき数の係数を返してくれます.
今回の授業内容は,以下のテキストを参考にしました.
MedInc
,2番目の要素をHouseAge
とします.この場合,5番目のデータ(5番目のブロック)のHouseAge
は,うえで定義されたデータ行列${\rm X}$の中のどの要素に入っているでしょうか?mp
と比べてみましょう.