nanoseeingの技術系ブログ

機械学習・競プロなど。アウトプットが目的。

重回帰分析を実装する【機械学習アウトプット第2回】

重回帰分析とは

教師データとして、m次元の説明変数xと、 それに対応する目的変数yが与えられたとき、

\hat{y}={w}_{0}{x}_{0} + {w}_{1}{x}_{1} + ... + {w}_{n}{x}_{m}

と近似できるパラメータ、

\boldsymbol{w}=[{w}_{0},{w}_{1},{w}_{2},...,{w}_{m}]

を求める問題。

自作データをプロットしてみる

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline

np.random.seed(seed=32)
plot_num = 50

x1 = np.random.rand(plot_num) * 10 - 5 
x2 = np.random.rand(plot_num) * 10 - 5 
y = 3 * x1 - 2 * x2 + 7
y += 5 * np.random.randn(plot_num)
fig = plt.figure(figsize=(6, 6))
ax = Axes3D(fig)
ax.plot(x1, x2, y, marker="o", linestyle='None')
plt.show()

f:id:nanoseeing:20210202165048p:plain

目的変数y=3{x}_{1} - 2{x}_{2} + 7とし、教師データの作成時には 正規分布に従う誤差を加えた。

求めたい正解のパラメータは、

\boldsymbol{w}=[7,3,-2]

である。

自力で数式から実装

m次元の教師データ(\boldsymbol{x},y)の組がn組与えられたとする。

このとき、

 \boldsymbol{X} =
\begin{pmatrix}
x_{10}&x_{11}&x_{12}&...&x_{1m}\\
x_{20}&x_{21}&x_{22}&...&x_{2m}\\
...\\
x_{n0}&x_{n1}&x_{n2}&...&x_{nm}\\

\end{pmatrix}


とおくと、求めたいパラメータ \boldsymbol{w}は、

\boldsymbol{w}=(\boldsymbol{X^{T}}\boldsymbol{X})^{-1}\boldsymbol{X^{T}}\boldsymbol{y}

で求まる。

これは、二乗和誤差を行列のノルム形式で表して、偏微分して、ごちゃごちゃ変形した結果である。 具体的な計算過程は参考サイトに任せる。

実際に実装するとこうなる。

x0 = np.ones(plot_num).reshape(plot_num,1)
x1 = x1.reshape(plot_num,1)
x2 = x2.reshape(plot_num,1)
y = y.reshape(plot_num,1)
X = np.concatenate([x0, x1, x2], 1)
W = np.dot(np.dot(np.linalg.inv(np.dot(X.transpose(), X)), X.transpose()), y)
print(W)
>>
[[ 7.15745485]
 [ 2.83263504]
 [-2.35856492]]

正解のパラメータ \boldsymbol{w}=[7,3,-2]に近いことが確認できる。

sklearnで実装

sklearnのLinearRegression()を使えば一発。

from sklearn import linear_model

X = np.concatenate([x1, x2], 1)
clf = linear_model.LinearRegression()
clf.fit(X, y)
print(clf.coef_)
print(clf.intercept_)
>>[[ 2.83263504 -2.35856492]]
[7.15745485]

切片の値w_{0}は「clf.intercept_」に、それ以外のパラメータは「clf.coef_」に入っている。 自力実装と同じ値が出力された。

参考サイト