データの完全な分離ができない場合、
誤差を最小にするように、識別関数の重みベクトルを計算する。
(定式化)
教師信号と識別関数の値の差を誤差と定義
この誤差の2乗和を考える
これについて、すべての学習パターンについて総和をとる。
やることは、このJを最小にする重みベクトルの計算。
最急降下法を用いると、更新式は
だから、
# coding: utf-8 import numpy as np import matplotlib.pyplot as plt from pylab import * # サンプルデータの生成(2次元正規分布) mean1 = [0,0]; cov1 = [[4,0],[0,100]]; N1 = 1000 X1 = np.random.multivariate_normal(mean1,cov1,N1) mean2 = [30,-30]; cov2 = [[1,20],[20,50]]; N2 = 1000 X2 = np.random.multivariate_normal(mean2,cov2,N2) X = np.concatenate((X1,X2)) # 描画 x,y = X.T plt.plot(x,y,'k.'); plt.axis('equal'); #plt.show() #識別関数 g(x,y)=w0 + w1*x + w2*y #初期値 w0 = 60 w1 = 4 w2 = -1.0 rho = 0.00001 #Widrow-Hoffの学習規則を適用 i=0 for k in range(100): sum0 = 0 sum1 = 0 sum2 = 0 for p in range(2000): dot = w0*1 + w1*X[p][0] + w2*X[p][1] #print X[p][0] if p < 1000: sum0 += (dot - 1) * 1.0 sum1 += (dot - 1 ) * X[p][0] sum2 += (dot - 1) * X[p][1] else: sum0 += dot * 1.0 sum1 += dot * X[p][0] sum2 += dot *X [p][1] w0 = w0 - rho * sum0 w1 = w1 - rho * sum1 w2 = w2 - rho * sum2 print w0,w1,w2 #得られた線形識別関数を描画 xsamp = linspace(-20,60,1000) ysamp = -1.0*w1/w2 * xsamp -1.0 * w0/w2 plt.plot(xsamp,ysamp) plt.show()
実行結果
どうやら最急降下法のコードが間違ってるらしい。
勘違いしてるところを書き直した。
# coding: utf-8 import numpy as np import matplotlib.pyplot as plt from pylab import * # サンプルデータの生成(2次元正規分布) mean1 = [0,0]; cov1 = [[4,0],[0,100]]; N1 = 1000 X1 = np.random.multivariate_normal(mean1,cov1,N1) mean2 = [30,-30]; cov2 = [[1,20],[20,50]]; N2 = 1000 X2 = np.random.multivariate_normal(mean2,cov2,N2) X = np.concatenate((X1,X2)) # 描画 x,y = X.T plt.plot(x,y,'k.'); plt.axis('equal'); #plt.show() #識別関数 g(x,y)=w0 + w1*x + w2*y #初期値 w0 = 60 w1 = 4 w2 = -1.0 rho = 0.0008 #Widrow-Hoffの学習規則を適用 #ある点xiにおける識別関数 g(x,y) #gi = w0 + w1*X[i][0] + w2*X[i][1] #誤差の和 for p in range(2000): gi = w0 + w1*X[p][0] + w2*X[p][1] sum_gi_0 = 0 sum_gi_1 = 0 sum_gi_2 = 0 #0<p<1000のとき gi-1 if p < 1001: sum_gi_0 += (gi-1) sum_gi_1 += (gi-1)*X[p][0] sum_gi_2 += (gi-1)*X[p][1] #1000<p<2000のとき gi if p > 1000: sum_gi_0 += gi sum_gi_1 += gi *X[p][0] sum_gi_2 += gi *X[p][1] w0 = w0 - rho * sum_gi_0 w1 = w1 - rho * sum_gi_1 w2 = w2 - rho * sum_gi_2 print w0,w1,w2 #得られた線形識別関数を描画 xsamp = linspace(-20,60,1000) ysamp = -1.0*w1/w2 * xsamp -1.0 * w0/w2 plt.plot(xsamp,ysamp) plt.show()