机器学习的简要笔记(四)——感知机的算法

1、什么是感知机(Perception)

感知机是生物神经细胞的简单抽象。神经细胞结构大致可分为:树突、突触、细胞体及轴突。单个神经细胞可被视为一种只有两种状态的机器——激动时为‘是’(+1,表示),而未激动时为‘否’(-1表示)。神经细胞的状态取决于从其它的神经细胞收到的输入信号量(变量X),及突触的强度(抑制或加强,参数W)(函数F(X))。当信号量总和超过了某个阈值时,细胞体就会激动,产生电脉冲。电脉冲沿着轴突并通过突触传递到其它神经元。为了模拟神经细胞行为,与之对应的感知机基础概念被提出,如权量(突触)、偏置(阈值)及激活函数(细胞体)。

整个过程可以用下图抽象

由于感知机有两个状态:激动状态(+1)或者不激动状态(-1),因此感知机可以用于二分类。

感知机是一个相当简单的模型,是支持向量机(通过简单地修改一下损失函数)、神经网络(通过简单的叠加)的基础。

2、感知机的数学模型

线性可分:对于一个数据集感知机:从原理到训练(xi为输入,yi为标签),如果存在一个超平面Π,能够将D中正负样本(对于某个样本(xi,yi),若 y=1 则称其为正样本,若 yi =-1 则称其为负样本,且标签 y只能取正负 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\

 
 

猜你喜欢

转载自www.cnblogs.com/milliard/p/9492853.html