本文感知机(perceptron)主要讲解原理、相关的公式、算法并经过举例计算来理解感知机算法的过程,最后附上相关的python代码。若想要详细的了解感知机公式的每一步推导过程及证实,本文不适合您。python
感知机原理公式实例及Python代码
感知机是二类分类的线性分类模型,其中输入为实例的特征向量,输出为它的类别,能够取-1和+1两种。固然,输出也能够取其余的两种值,例如a和b,对和错,这里的-1和+1只是一个标签而已。git
感知机对应于特征空间(能够是二维,三维,...,n维)中将实例划分为正负两类的分离超平面,属于判别模型,是神经网络与支持向量机的基础。它是Rosenblatt在1957年提出的。github
本文中包括三部分:一、感知机模型;二、感知机的学习策略;三、感知机学习算法。算法
一、感知机模型
感知机定义:网络
感知机的几何解释:线性方程app
对应于特征空间中的一个超平面S,其中w是超平面的法向量,b是超平面的截距。这个超平面将特征空间划分为两个部分。位于两部分的点分别被分为正、负两类。所以,超平面称为分离超平面(separating hyperplane),以下图所示:机器学习
感知机学习,由训练数据集(实例的特征向量及类别)函数
二、感知机学习策略
2.1 数据集的线性可分性定义
2.2 感知机学习策略
数据集线性可分是感知机模型构建的前提。感知机学习的目标是求得一个可以将训练集正负实例点彻底正确分开的分离超平面,即肯定感知机模型参数w和b,那么须要肯定一个学习策略,定义(经验)损失函数并将损失函数极小化。学习
损失函数的一个天然选择是误分类点的总数,但这样的损失函数不是参数w和b的连续可导函数,不易优化。损失函数的另外一个选择是误分类点到超平面S的总距离,这是感知机所采用的。为此,首先写出输入空间中任意一点x0到超平面的距离(该公式是点到直线间的距离公式):优化
感知机的学习策略是在假设空间中选取使损失函数式最小的模型参数w和b,即感知机模型。
三、感知机学习算法
3.一、感知机学习算法的原始形式
这种学习算法直观解释以下:当一个实例点被误分类,即位于分离超平面的错误一侧时,则调整w,b的值,使分离超平面向该误分类点的一侧移动,以减少该误分类点与超平面间的距离,直到超平面越过该误分类点使其被正确分类。
感知机学习算法的原始形式的代码以下所示:
import numpy as np; import pandas as pd; import matplotlib.pyplot as plt; df=pd.read_excel("D:\pythondata\perceptrondata.xls");#读取原题数据 df=pd.DataFrame(df); x=df.values[:,:-1];#x表明全部行的第一列到倒数第二列的数据,即分类实例的全部特征向量 y=df.values[:,-1];#y表明df的倒数第一列数据,即分类实例的全部类别 a=x.shape; n=a[0];#n表明x特征向量的行数 m=a[1];#m表明x特征向量的列数 w=[];#建立空列表,w表明分离超平面中的法向量 for i in range(m): w.append(0);#列表的长度与特征向量的特征个数相同 #若直接命令w[0]=0,w[1]=0时,会报错,直接按照索引向列表内添加东西时,由于空的列表不能直接指定其位置。 b=0;#b表明分离超平面的截距 k=1;#用来判别是否找到最优的超平面。假设值为1,即未找到 while (k==1): k=0; for i in range(n): t=np.dot(w,x[i]);#用来计算w*x if (y[i]*(t+b)<=0): w=w+np.dot(y[i],x[i]); b=b+y[i]; k=1; print("分离超平面的法向量w={0},截距b={1}".format(w,b)); ########可视化结果 # def plot_and_scatter(df=None,w=0,b=0): xmin=df.values[:,:-1].min(); xmax=df.values[:,:-1].max(); xdiff=(xmax-xmin)*0.5; xx=np.linspace((xmin-xdiff),(xmax+xdiff),100); yy=-b-w[1]*xx; plt.figure(); plt.xlabel("X(1)"); plt.ylabel("X(2)");#设置坐标轴的文字标签 ax=plt.gca();# get current axis 得到坐标轴对象 ax.spines["right"].set_color("none"); ax.spines["top"].set_color("none"); # 将右边 上边的两条边颜色设置为空 其实就至关于抹掉这两条边 ax.xaxis.set_ticks_position("bottom"); ax.yaxis.set_ticks_position("left"); ax.spines["bottom"].set_position(("data",0)); ax.spines["left"].set_position(("data",0));#指定 data设置的bottom(也就是指定的x轴)绑定到y轴的0这个点上 plt.plot(xx,yy,"r"); color_list=["blue","green","black","pink","orange"]; y=df.values[:,-1]; a=set(y); a=list(a); y_num=len(a); t=0; for j in range(y_num): tt=a[j]; y_index=[i for i,y in enumerate(y) if y==tt]; x_group1=df.values[y_index,0]; x_group2=df.values[y_index,1]; plt.scatter(x_group1,x_group2); t=t+1; plot_and_scatter(df,w,b); plt.show();
感知机学习算法因为采用不一样的初值或选取不一样的误分类点,解能够不一样。正如例一图中所示的那样,有两条分离超平面都可以分离正负两类线性可分的点。
线性可分数据集感知机学习算法原始形式收敛,即通过有限次迭代能够获得一个将训练数据集完整正确划分的分离超平面及感知机模型,证实过程见李航《统计学习方法》书中第二章所示。
3.3 感知机学习算法的对偶形式
感知机学习算法的对偶形式的代码以下所示:
import numpy as np; import pandas as pd; import matplotlib.pyplot as plt; df=pd.read_excel("D:\pythondata\perceptrondata.xls"); df=pd.DataFrame(df); x=df.values[:,:-1];#切片,分割特征向量x和对应的类别y y=df.values[:,-1]; xy=x.shape;#输出x的行数和列数 n=xy[0];#表明特征向量x的行数 m=xy[1];#表明特征向量x的列数 a=[]; b=0; for i in range(n): a.append(0); g=np.zeros((n,n)); for i in range(n): for j in range(n): for l in range(m): g[i][j]=g[i][j]+x[i][l]*x[j][l];#计算Gram矩阵 k=1; while (k==1):#当样本中存在误分点时 k=0;#本次循环中样本假设不存在误分点 for i in range(n): t=0; for j in range(n): t=t+g[i][j]*y[j]*a[j]; if (y[i]*(t+b)<=0): a[i]=a[i]+1;#计算a[i]的值 b=b+y[i];#计算b的值 k=1;#样本中存在误分点 w=[]; for j in range(m): w.append(0); for j in range(m): for i in range(n): w[j]=w[j]+a[i]*x[i][j]*y[i]; print("分离超平面的法向量w=",w,",截距b=",b) def plot_and_scatter(df=None,w=0,b=0): xmin=df.values[:,:-1].min(); xmax=df.values[:,:-1].max(); xdiff=(xmax-xmin)*0.5; xx=np.linspace((xmin-xdiff),(xmax+xdiff),100); yy=-b-w[1]*xx; plt.figure(); plt.xlabel("X(1)"); plt.ylabel("X(2)");#设置坐标轴的文字标签 ax=plt.gca();# get current axis 得到坐标轴对象 ax.spines["right"].set_color("none"); ax.spines["top"].set_color("none"); # 将右边 上边的两条边颜色设置为空 其实就至关于抹掉这两条边 ax.xaxis.set_ticks_position("bottom"); ax.yaxis.set_ticks_position("left"); ax.spines["bottom"].set_position(("data",0)); ax.spines["left"].set_position(("data",0));#指定 data设置的bottom(也就是指定的x轴)绑定到y轴的0这个点上 plt.plot(xx,yy,"r"); color_list=["blue","green","black","pink","orange"]; y=df.values[:,-1]; a=set(y); a=list(a); y_num=len(a); t=0; for j in range(y_num): tt=a[j]; y_index=[i for i,y in enumerate(y) if y==tt]; x_group1=df.values[y_index,0]; x_group2=df.values[y_index,1]; plt.scatter(x_group1,x_group2); t=t+1; plot_and_scatter(df,w,b); plt.show();
结果和例1一致,迭代步骤也是相互对应的。与原始形式同样,感知机学习算法对偶形式的迭代也是收敛的,存在多个解。
感知机学习算法数据和代码相关的github连接
参考文献:
[1] 李航. 《统计学习方法》第二版
[2] Rosenblatt, Frank (1957). "The Perceptron—a perceiving and recognizing automaton". Report 85-460-1. Cornell Aeronautical Laboratory.
本文中的理论知识和例题主要来自于李航《统计学习方法》第二版第二章中,若是您须要系统的学习机器学习的理论知识,强烈推荐您看该书。主要的创新点在于代码彻底是本身写的,理论部分加入了一点点本身的理解。