最小二乗法をPythonで実装
最小二乗法では、重みはこうなります。
\begin{align}
w\bf = (X^TX)^{-1}X^Ty\bf
\end{align}
#適当な6点のx,y座標 px = np.array([0,1,2,3,4,5]) py = np.array([1,5,6,8,9,9]) e = np.array([1,1,1,1,1,1]) #成分が全て1のベクトル X = np.array([px, e]).T #6点のx成分と1を縦に並べた行列(最小二乗法に必要) #最小二乗法による重みの解 w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(py) #点を全てプロット plt.scatter(px, py) #-3から7まで0.1刻みでnumpy配列で用意 x = np.arange(-3, 7, 0.1) #得られた重みを用いて、直線の式を作る y = w[0]*x + w[1] #得られた直線を引く plt.plot(x, y) plt.show()
ちなみに、Windrow-Hoffアルゴリズムという最小二乗法を解く手法も紹介する
#適当な6点のx,y座標 px = np.array([0,1,2,3,4,5]) py = np.array([1,5,6,8,9,9]) #重みは0で初期化 w = np.array([0, 0]) #学習率 適当に小さく eta = 0.001 #Widrow-Hoffアルゴリズムで最小二乗法を解く for _ in range(1000): for i in range(6): w = w - eta*(w[0]*px[i] + w[1] - py[i])*np.array([px[i], 1]) #点を全てプロット plt.scatter(px, py) #-3から7まで0.1刻みでnumpy配列で用意 x = np.arange(-3, 7, 0.1) #得られた重みを用いて、直線の式を作る y = w[0]*x + w[1] #得られた直線を引く plt.plot(x, y) plt.show()
点に沿ったいい感じの直線が引けてて気持ちいいね!