感知机介绍感知机(perceptron)是一种二元分类的线性模型。它的输入是实例的特征向量,输出是实例的类别,取+1或-1的两个值。感知器属于分类超平面的判别模型,在输入空间(特征空间)中将实例分为正类和负类。感知器学习旨在找到一个线性划分训练数据的超平面。感知器具有简单易实现的优点,是神经网络和支持向量机的基础。假设输入空间(特征空间)为$x\subseteq\mathcal{R}_n$,输出空间为$\gamma=\{+1,-1\}$。输入$x\in\chi$表示实例的特征向量,对应输入空间(特征空间)点;输出$y\in\gamma$表示实例的类别。以下从输入空间到输出空间的函数$$f(x)=sign(w\cdotx+b)\tag{1}$$称为感知器。其中,w和b是感知器模型的参数,$w\inR^n$称为权重或权重向量,$b\inR$称为偏置,wx表示w和的内积X。sign为符号函数,即$$\begin{align}sign(x)=\begin{cases}+1,&x\geq0\\\-1,&x<0\end{cases}\end{align}$$Perceptron是线性分类模型,属于判别模型。感知机模型的假设空间是特征空间中定义的所有线性分类模型或线性分类器,即函数集$$\{f|f(x)=wx+b\}$$的学习策略感知机给定一个数据集$T=\{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\}$,其中$x_i\in\chi=R^n,y_i\in\gamma=\{+1,-1\},i=1,2,...,N$,如果存在超平面S$$w\cdotx+b=0\tag{3}$$的数据集的真实实例点和负实例点都可以正确分配到超平面的两边,即对于$y_i=+1$的所有实例i,$w\cdotx_i+b>0$,对于所有$y_i=-1$实例i,$w\cdotx_i+b<0$,则称数据集T为线性可分数据集(Linearseparabledataset);否则,称数据集T是不可分的。假设数据集T是线性可分的,感知器学习的目的是学习一个能够完全正确分离正负样本的超平面S,如下图所示。确定超平面意味着确定模型参数w和b。需要确定并最小化模型的损失函数。损失函数最直接的选择之一是错误分类样本的数量(类似于L0正则化),但这样的损失函数并不容易求解。另一种选择是将误分类点到超平面的总距离作为损失函数,可以得到输入空间$R^n$中任意点$x_0$到超平面的距离。$$\frac{1}{||w||}|w\cdotx_0+b|\tag{4}$$$||w||$是权重w的L2范数。对于错误分类的例子,下面的公式成立:$$-y\cdot(w\cdotx+b)>0\tag{5}$$当$w\cdotx+b>0$,$y_i$=-1;当$w\cdotx+b<0$时,$y_i$=+1。因此,误分类点$x_i$到超平面S的距离为$$-\frac{1}{||w||}y_i\cdot(w\cdotx_i+b)\tag{6}$$所以that得到所有错误分类实例到超平面的总距离$$-\frac{1}{||w||}\sum_{x_i\inM}y_i\cdot(w\cdotx_i+b)\tag{7}$$M是误分类实例的集合,不管$\frac{1}{||w||}$,得到感知器的损失函数$sign(w\cdotx+b)$。$$L(w,b)=-\sum_{x_i\inM}y_i\cdot(w\cdotx_i+b)\tag{8}$$感知器学习的策略是选择假设中的损失函数space(8)最小的模型参数w,b,即感知器模型。感知器算法步骤感知器算法由错误分类驱动,使用随机梯度下降。即先随机选择一个超平面(w,b),然后使用梯度下降法最小化目标函数$$min_{w,b}L(w,b)=-\sum_{x_i\inM}y_i\cdot(w\cdotx_i+b)\tag{9}$$最小化过程不是一次使用所有误分类点的梯度下降,而是一次随机选择一个误分类点,使其梯度下降。假设误分类点集合M是固定的,那么损失函数L(w,b)的梯度由$$\begin{equation}\tag{10}\begin{cases}\bigtriangledown_wL(w,b)=-\sum_{x_i\inM}y_ix_i\\\bigtriangledown_bL(w,b)=-\sum_{x_i\inM}y_i\end{cases}\end{equation}$$给出。随机选取一个误分类点$(x_i,y_i)$,更新参数w和b:$$w\leftarroww+\etay_ix_i\tag{11}$$$$b\leftarrowb+\etay_i\tag{12}$$$\eta$表示步长,也叫学习率。对于数据集$T=\{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\}$,其中$x_i\inx=R^n,y_i\iny={+1,-1},i=1,2,...,N,0<\eta<1$。由此,我们可以写出感知机算法的初始化模型参数w、b的过程。计算错误分类点的集合。使用误分类点的数据,使用公式(11)和公式(12)更新参数w和b。转到第2步,直到误分类点集为空。感知器的代码加载数据并对其进行预处理。这里我们使用sklearn自带的iris数据集。我们只是利用数据集中的萼片长度和萼片宽度这两个特征来构建感知器模型。#加载数据data=load_iris()x,y=data['data'],data['target']#只选择标签为0和1的样本mask=y<2x,y=x[mask],y[mask]idx0=(y==0)idx1=(y==1)#只选择萼片长度和萼片宽度两个特征x=x[:,:2]#将标签0和1替换为-1和1y=np.where(y==1,1,-1)构建感知器模型类Perceptron:def__init__(self,x,y,lr=0.1):self.x=xself.y=yself.w=np.ones(x.shape[1],dtype=np.float32)self.b=0self.lr=lr#一次训练整个错误分类的样本集deftrain1(self):whileTrue:y_pred=self.y*(self.x@self.w)mask=(y_pred<=0).reshape((-1,))error_num=np.count_nonzero(mask)iferror_num==0:breakelse:self._update(self.x[mask],self.y[mask])#单样本训练deftrain(self):whileTrue:error_num=0foriinrange(self.x.shape[0]):X=self.x[i]Y=self.y[i]如果self.y[i]*(X@self.w+self.b)<=0:self.w=self.w+self.lr*Y*Xself.b=self.b+self.lr*Yerror_num+=1如果error_num==0:break#参数更新def_update(self,x,y):self.w+=self.lr*x.T@y/len(y)视觉感知器分类结果net=Perceptron(x,y)net.train()fig,ax=plt.subplots()ax.scatter(x[idx0,0],x[idx0,1],label='0')ax.scatter(x[idx1,0],x[idx1,1],标签='1')ax.plot(x[:,0],-(x[:,0]*net.w[0]+net.b)/net.w[1],c='red',label='fit')ax.legend()plt.show()从图中可以看出,拟合错分集得到的超平面并不是最优超平面,因为恰好以完全正确分类为临界条件,所以模型正好满足这个条件。另外需要注意的是,在大多数情况下,梯度下降只能得到不可行解,而不是最优解。总结1.感知器是一种线性模型,根据输入实例的特征向量x进行二分类,$f(x)=sign(w\cdotx+b)$,感知器对应于超平面中输入空间$w\cdotx+b=0$。2.感知器的策略是最小化损失函数:$$min_{w,b}L(w,b)=-\sum_{x_i\inM}y_i\cdot(w\cdotx_i+b)$$损失函数对应于被误分类的点到超平面的距离。3、感知机学习算法是一种基于随机梯度下降的损失函数优化算法,有原形和对偶形式(这里只介绍原形)。该算法简单易行。在原始形式中,首先任意选择一个超平面,然后通过梯度下降法不断地最小化目标函数。在这个过程中,每次随机选择一个误分类点,使其梯度下降。4.当训练数据集线性可分时,感知机学习算法收敛。*当训练数据集线性可分时,感知器学习算法有无穷多个解,解可能因初始值不同或迭代序列不同而不同。参考《李航统计学习方法》统计学习方法——感知器
