機器學習的簡要筆記(四)——感知機的算法
1、什麽是感知機(Perception)
感知機是生物神經細胞的簡單抽象。神經細胞結構大致可分為:樹突、突觸、細胞體及軸突。單個神經細胞可被視為一種只有兩種狀態的機器——激動時為‘是’(+1,表示),而未激動時為‘否’(-1表示)。神經細胞的狀態取決於從其它的神經細胞收到的輸入信號量(變量X),及突觸的強度(抑制或加強,參數W)(函數F(X))。當信號量總和超過了某個閾值時,細胞體就會激動,產生電脈沖。電脈沖沿著軸突並通過突觸傳遞到其它神經元。為了模擬神經細胞行為,與之對應的感知機基礎概念被提出,如權量(突觸)、偏置(閾值)及激活函數(細胞體)。
整個過程可以用下圖抽象
由於感知機有兩個狀態:激動狀態(+1)或者不激動狀態(-1),因此感知機可以用於二分類。
感知機是一個相當簡單的模型,是支持向量機(通過簡單地修改一下損失函數)、神經網絡(通過簡單的疊加)的基礎。
2、感知機的數學模型
線性可分:對於一個數據集(xi為輸入,yi為標簽),如果存在一個超平面Π,能夠將D中正負樣本(對於某個樣本(xi,yi),若 yi =1 則稱其為正樣本,若 yi =-1 則稱其為負樣本,且標簽 yi 只能取正負 1 這兩個值)分開,那麽就稱 D 是線性可分的。否則,就稱是線性不可分的。
如果數據集線性可分,那麽感知機一定能夠將數據集的每個數據區分開。
感知機模型:
f(X)=sign(w*X+b),其中sign是符號函數。
感知機模型,對應著一個超平面w*X+b=0,這個超平面的參數是(w,b),w是超平面的法向量,b是超平面的截距。
目標就是找到一個(w,b),能夠將線性可分的數據集T中的所有的樣本點正確地分成兩類。
如果有某個點(Xi, yi),使得yi(w*Xi)<0,則稱超平面w*X對該點分類失敗。采用所有誤分類的點到超平面的距離來衡量分類失敗的程度。
W為常數,所以
所以尋找(w,b)問題轉化為最小化損失函數,即轉化為一個最優化問題。(損失函數越小,說明誤分類的樣本點“越少”---或者說分類失敗的程度越低)
3、計算推導
4 感知機的對偶形式
w,b都取零,那麽叠代多次後,有
其中 ni 是指某個樣品{ Xi,yi}被使用了 ni 次,若設 ai=ηni,那麽
那麽更新 w.b 就相當於更新 ai<--η(ni+1)
這裏涉及計算: Xi*Xj 可通過實現計算好的 gram 矩陣直接調用 Gij
1 #coding:utf-8 2 3 ‘‘‘ 4 author@令狐蔥 5 date:08/17/2018 6 ‘‘‘ 7 8 import numpy as np 9 #感知機原始形式進行編程,求解李航<統計機器學習實例> 10 11 class Perception_primitive: 12 def __init__(self,X,y,eta=1,iternum=1000):###初始化,輸入X,y,以及叠代次數 13 self.X=np.array(X) ##轉化為 Numpy 陣列 14 self.y=np.array(y) ##轉化為 Numpy 陣列 15 self.b=0 ##偏置為零 16 self.eta=eta ##學習率,默認為1 17 col=self.X.shape[1] 18 self.W=np.zeros((col))###權重,默認為0 19 self.iternum=iternum ###最大叠代次數 20 ####初始化結果 21 print("#####START######") 22 print("X=",self.X,"\ny=",self.y,"\nW=",self.W,"\nb=",self.b) 23 print("###############") 24 def update(self,Xi,yi): ###叠代更新, w,b 25 self.W=self.W+yi*Xi*self.eta 26 self.b=self.b+yi*self.eta 27 28 29 def fit(self): ##擬合 30 length=len(self.X) 31 print("iter", "X ","y ","W ","b ") 32 iter_num=0 33 for j in range(self.iternum): 34 count=0##判斷每次更新參數後,記錄分類錯誤的次數 35 36 37 for i in range(length): 38 temp=self.predictive(self.X[i],self.y[i])###計算損失函數 39 40 if temp < 0: ##分類錯誤時,更新參數 41 count+=1 42 self.update(self.X[i],self.y[i]) 43 iter_num+=1 44 print(iter_num ,self.X[i], self.y[i], self.W,self.b) 45 if count==0: ###在新參數下,所有的分類都是正確的 46 print("$$$$$$END$$$$$$$$$") 47 return self.W,self.b 48 break 49 def predictive(self,Xi,yi): 50 temp=yi*(np.dot(Xi,self.W)+self.b) 51 if temp <=0: return -1 52 if temp >0: return 1 53 54 55 if __name__=="__main__": 56 X=np.array([[3,3],[4,3],[1,1]]) 57 y=np.array([1,1,-1]) 58 p=Perception_primitive(X,y) 59 p.fit() 60 print("W=",p.W,"\nb=",p.b)
測試結果
#####開始###### X= [[3 3] [4 3] [1 1]] y= [ 1 1 -1] W= [0. 0.] b= 0 ############### iter X y W b 1 [3 3] 1 [3. 3.] 1 2 [1 1] -1 [2. 2.] 0 3 [1 1] -1 [1. 1.] -1 4 [1 1] -1 [0. 0.] -2 5 [3 3] 1 [3. 3.] -1 6 [1 1] -1 [2. 2.] -2 7 [1 1] -1 [1. 1.] -3 $$$$$$$$$$$$$$$$$$$$$ W= [1. 1.] b= -3
4\
機器學習的簡要筆記(四)——感知機的算法