感知機(jī)作為最經(jīng)典的學(xué)習(xí)算法僻造,其基本原理就不再冗述。本片文章對藍(lán)皮書P33~34頁的對偶算法進(jìn)行了實(shí)現(xiàn)馆纳。
Part i 算法詳解
=================感知機(jī)對偶形式偽代碼=====================
輸入:線性可分?jǐn)?shù)據(jù)集X敌厘,標(biāo)簽y滴须,學(xué)習(xí)率η
輸出:輸出α舌狗,b;以及決策界面:
=======================================================
Step.1 α ← 0扔水,b←0
Step.3 判斷該樣本是否為誤分樣本, 判斷條件如下:
如果是痛侍,則對α,b按照以下規(guī)則更新:
Step.4 重復(fù)步驟2魔市、3主届,直至沒有誤分類的樣本
=======================================================
Part ii Python實(shí)現(xiàn)
- 定義一個
perception()
類,輸入?yún)?shù)X,y和η
并初始化內(nèi)積矩陣Gram待德,拉格朗日系數(shù) α以及偏置b
def __init__(self,x,y,yta=1.0):
self.__x = x
self.__y = y
# 初始化gamm矩陣
Gram = np.zeros([x.shape[0],x.shape[0]])
for i in range(x.shape[0]):
for j in range(x.shape[0]):
Gram[i,j] = np.dot(x[i,:],x[j,:].T )
self.__Gram = Gram
# 初始化訓(xùn)練處置
self.a = np.zeros([x.shape[0]])
self.b = 0
self.__yta = yta
self.w = np.zeros([x.shape[1]])
- 在類中定義一個判斷函數(shù)
Condition(self,t)
君丁,用于判斷某個樣本是否為誤分類樣本。
def Condition(self,t):
result = 0
yi = self.__y[t]
coni = np.sum( self.a * self.__y * self.__Gram[:,t]) + self.b
if yi * coni <= 0:
result = 1
return result
- 接著就可以開始訓(xùn)練感知機(jī)了将宪,定義訓(xùn)練函數(shù)
def fit(self)
def fit(self):
Num = self.__x.shape[0]
Out = False
# 訓(xùn)練
while True:
for i in range(Num):
if self.Condition(i):
self.a[i] += self.__yta
self.b += self.__yta * self.__y[i]
break
else:
Out = True
if Out:
break
# 計(jì)算權(quán)重w
for i in range(Num):
self.w += self.a[i] * self.__x[i,:] * self.__y[i]
- 到此為止绘闷,一個感知器的訓(xùn)練程序基本上已經(jīng)完成了,但是為了能夠讓感知機(jī)對新的數(shù)據(jù)進(jìn)行測試较坛,還得加入一個預(yù)測函數(shù)
predict(self,x)
def predict(self,x):
return np.sign( np.dot(x,self.w )+self.b )
- 當(dāng)然了印蔗,為了能夠清楚的觀察到?jīng)Q策界面,所以又增加了一個可視化決策界面的函數(shù)丑勤。但是對于人類這種三維生物华嘹,只有低于三維的世界才有著絕對的上帝視角,所以咱的可視化函數(shù)也只對三維以下的數(shù)據(jù)集有效
def plot_decision_surface(self,x = None):
if self.__x.shape[1] >2:
return None
else:
import matplotlib.pyplot as plt
plt.figure()
plt.scatter(self.__x[:,0],self.__x[:,1],c=self.__y,marker='p',s=200)
# 計(jì)算超平面
mgx = np.arange(-5,5,0.01)
mgy = -self.b-self.w[0]*mgx
mgy /= self.w[1]
# 畫出超平面
plt.plot(mgx,mgy)
try:
plt.scatter(x[:,0],x[:,1],c='r',marker='s',s = 50)
except:
x = None
Part iii 感知機(jī)實(shí)驗(yàn)運(yùn)行結(jié)果
- 隨機(jī)設(shè)置了一些坐標(biāo)點(diǎn)和標(biāo)簽,正反例反別用 紫色和黃色區(qū)分
x = np.array([[-3,3],[4,3],[1,1],[2,5],[3,5],[1,2],[2,3]])
y = np.array([-1,1,-1,-1,1,-1,-1])
- 并且設(shè)置了兩個預(yù)測樣本法竞,用紅色表示
x_test = np.array([[0,0],[5,5]])
調(diào)用part ii 中的編寫的感知機(jī)函數(shù)耙厚,進(jìn)行預(yù)測
from Perception import perception
per = perception(x,y)
per.fit()
y_pred = per.predict( x_test )
per.plot_decision_surface(x_test)
最終實(shí)驗(yàn)結(jié)果: