1.前言
感知机1957年由Rosenblatt提出,是神经网络与支持向量机(Support Vector Machine, SVM)的基础。
2.基础知识
2.1.超平面
超平面是指n维线性空间中维度为n-1的子空间。它可以把线性空间分割成不相交的两部分。
例如:一维直线可以通过零维点分割成两部分。二维平面可以通过一维直线分割成两部分。三维空间中通过二维平面分割成两部分。
法向量是垂直于超平面的向量
在维空间中,超平面的方程:
其中超平面内任意一点记为
现在任意选择超平面内的两个点,向量
由于在超平面内,所以满足:
两式相减得:
即:
其中
由于是超平面内任意一个向量,所以是超平面的法向量,超平面可写成:
2.2.点到超平面的距离
现需要求超平面外某一点离超平面的距离
距离为红色部分,取平面任意一点,由三角函数可知:
而且与所成夹角正好就是,所以两向量点积为:
由于法向量可能反向,所以给左边加上绝对值,联立可得:
由于在平面内,满足,带入上式得任意一点到超平面距离公式:
3.感知机模型
假设输入空间(特征空间)是,输出空间是。输出表示实例的特征向量,对应于输入空间的点,输出实例的类别。由输出空间到输出空间的函数为:
称为感知机。其中和称为感知机模型参数,叫做权值或者权值向量,称为偏置。
函数为符号函数,即:
感知机是一种线性分类模型,属于判别模型。感知机模型的假设空间是定义在特征空间中的所有线性分类模型或线性分类器,即函数集合。
如图,这个超平面将两类不同的点分成正、负两类,因此也被称之为分离超平面。对于感知机而言,目的就是求出该超平面,之后对于给定的输入,就可以判断该点到底是属于哪一个类别。
4.感知机学习策略
4.1.线性可分
数据集的线性可分性:给定数据集,其中,如果存在某个超平面,能够将数据集的正实例点和负实例点完全正确划分到超平面的两侧,即对于所有的点满足,对于所有的点满足,则称数据集为线性可分数据集,否则称之为线性不可分。
4.2.感知机学习策略
目标:找到超平面,也就是确定参数,我们需要定义学习策略,即定义经验损失函数,并将损失函数极小化。
损失函数:误分类点到超平面S的总距离。也就是误分类点的距离越小,损失函数就越小,分类效果就越好。
由之前可知任意一点到超平面距离
对于分类正确的点满足,因此对于误分类点
所以对于误分类点的距离可以写成
那么所有的误分类点到超平面的距离是:
其中是误分类点的集合。
然后忽略,定义感知机学习损失函数:
由函数可知,损失函数非负,当正确分类时,损失函数为0。
4.3.为什么可以忽略
本答案综合网上回答
不忽略的话计算的是几何间隔,忽略的话计算的是函数间隔。(具体概念此处不展开)
1、由于我们只需要进行分类即可,忽略之后不会影响误分类点的判定。
2、因为最终损失函数变成了0,所以与大小是无关的,加上反而计算麻烦。
5.感知机学习算法
5.1.感知机学习算法原始形式
感知机学习算法是对以下最优化问题的算法。给定一个训练数据集
其中,求参数,使其为以下损失函数极小化问题的解
其中是误分类点的集合。
感知机学习算法是误分类驱动的,具体采用随机梯度下降法。首先任意选择一个超平面,然后用梯度下降法不断极小化目标函数。极小化过程不是一次使中所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。
假设误分类点集合是固定的,那么损失函数的梯度由
随机选取一个误分类点,对进行更新:
其中是步长,也叫学习率。通过迭代可以使得损失函数不断减少,直到为0。
算法流程:
输入:线性可分的训练数据集,其中 ,学习率
输出:;感知机模型
-
选取初值
-
在训练集中选取数据
-
如果,即该点误分类,则更新:
-
转到2,直到不存在误分类点。
5.2.算法的收敛性
为了便于推导,将偏置并入权重向量,记作,同样的也将输入向量进行扩充,加入常数1,记作,这样,显然:
设训练数据集是线性可分的,其中 ,则
(1)存在满足条件的超平面将训练数据集完全正确分开;且存在,对所有都满足:
(2)令,则感知机算法5.1在训练数据集上的误分类次数满足不等式
证明:
(1)由于训练数据集是线性可分的,按照定义可知存在超平面可将训练数据集完全分开,取此超平面为,使。由于对均有:
所以存在
使得
(2)感知机算法从开始,如果实例被误分类,则更新权重。令是第个误分类实力之前的扩充权重向量,即
则第个误分类实例的条件是:
如果是被误分类的数据,则和的更新是:
即
然后推导两个不等式:
首先推导:
由于,所以
根据这个递推式可知:
然后推导:
由于,所以
根据这个递推式可知
最后:
由于前提条件,所以:
所以
最终得证。
由上述可知,误分类的次数是存在上界的,经过有限次搜索可以找到将训练数据完全正确分开的分离超平面。
5.3.感知机学习算法对偶形式
对偶形式的基本想法是,将和表示为实例和标记的线性组合的形式, 通过求解其系数而求得和。
原始形式是设置初始值和 均为0,对于误分类点进行更新:
逐步修改,这样可以发现对于来说,就是的线性组合,那么我们假设点误分类的次数记为,那么记,这样最后的为:
这里。
算法流程:
输入:线性可分的训练数据集,其中 ,学习率
输出:;感知机模型
其中
-
在训练集中选取数据
-
如果
更新
-
转至2直到不存在误分类点
对偶形式中训练实例以内积的形式出现,为了方便,可以预先将训练集中两两内积结果计算出来,也就是Gram矩阵。
两种形式的比较
原始形式,对于误分类点的判定是:
时间复杂度是,为向量维度,之后更新时间复杂度是,所以一次迭代的时间复杂度是
对偶形式,对于误分类点的判定是:
由于提前求出两两点积,也就是的时间复杂度是查表可知,更新时间复杂度是,所以一次迭代的时间复杂度是,是样本个数。
如果特征空间维度大于训练集样本数量时,使用对偶形式是更优的。
6.代码实践
6.1.例2.1
给定正例点,负例点,利用感知机学习算法的原始形式求感知机模型。这里。
感知机示例计算过程可以参考《统计学习方法》P40-41
代码
附加文件2_1.csv
x1,x2,y
3,3,1
4,3,1
1,1,-1
导入库,读取文件
import numpy as np
import pandas as pd
##读取文件
df = pd.read_csv('2_1.csv', encoding='utf-8')
print(df)
'''
输出:
x1 x2 y
0 3 3 1
1 4 3 1
2 1 1 -1
'''
点的分布图
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
%matplotlib inline
plt.figure('点分布')
#绘制Positive的点
plt.scatter(df[df.y==1]['x1'].values, df[df.y==1]['x2'].values,color='red',marker='o',label='Positive')
#绘制Negative的点
plt.scatter(df[df.y==-1]['x1'].values, df[df.y==-1]['x2'].values,color='blue',marker='x',label='Negative')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc = 'upper left')
plt.show()
点的分布图
当前样本的
x = df.values[::,:-1:]
y = df.values[::,-1::]
n = df.shape[1] - 1#获取特征数量
m = df.shape[0]#样本数量
print(x)
print(y)
'''
输出:
[[3 3]
[4 3]
[1 1]]
[[ 1]
[ 1]
[-1]]
'''
开始训练
#初始化w,b
w = np.zeros(n, dtype=int)
b = 0
eta = 1#学习率
#print(n,m)
#不断迭代
Time = 0
while True:
update = False
for i in range(m):
Time
#满足则说明分类错误,进行梯度下降
if y[i] * (w.dot(x[i])+b) <= 0:
w = w + eta * y[i] * x[i]
b = b + eta * y[i]
update = True
print(w, b)
#如果没有更新,说明全部分类正确,直接
if Time > 10**9 or update == False:
break
'''
输出:
[3 3] [1]
[2 2] [0]
[1 1] [-1]
[0 0] [-2]
[3 3] [-1]
[2 2] [-2]
[1 1] [-3]
'''
绘制结果
def predict(all):
return np.sign(all.dot(w.T) + b)
ans = np.array([], dtype = int)
for every in all:
if w.dot(every)+b < 0:
ans = np.append(ans, -1)
else:
ans = np.append(ans, 1)
return ans
def plot_decision_regions(x, y):
x1_min,x2_min = x.min(axis = 0)-1
x1_max,x2_max = x.max(axis = 0)+1
x1 = np.linspace(x1_min, x1_max, 500)
x2 = np.linspace(x2_min, x2_max, 500)
x1, x2=np.meshgrid(x1, x2) # 生成网格采样点
x_show = np.stack((x1.flat, x2.flat), axis=1) # 测试点
y_predict=predict(x_show)##将所有点求出正确的y
colors = ('lightgreen', 'LightPink', 'red', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
plt.pcolormesh(x1, x2, y_predict.reshape(x1.shape), cmap=cmap)
plt.xlim(x1.min(), x1.max())
plt.ylim(x2.min(), x2.max())
#绘制Positive的点
plt.scatter(df[df.y==1]['x1'].values, df[df.y==1]['x2'].values,color='red',marker='o',label='Positive')
#绘制Negative的点
plt.scatter(df[df.y==-1]['x1'].values, df[df.y==-1]['x2'].values,color='green',marker='x',label='Negative')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc = 'upper left')
plt.show()
predict(x)
plot_decision_regions(x,y)
分类结果
6.2.例2.2
计算过程可以参考《统计学习方法》P45
6.3.鸢尾花
数据下载
链接:https://pan.baidu.com/s/1icV0yZmyIp0cCZHZhNM3tQ 提取码:bc0m
导入库,读取文件
import numpy as np
import pandas as pd
df = pd.read_csv('iris2.data')
点的分布图
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
%matplotlib inline
#绘制Iris-setosa的点
plt.scatter(df[df.Class=='Iris-setosa']['sepal_len'].values, df[df.Class=='Iris-setosa']['petal_len'].values,color='green',marker='o',label='Iris-setosa')
#绘制Iris-versicolor的点
plt.scatter(df[df.Class=='Iris-versicolor']['sepal_len'].values, df[df.Class=='Iris-versicolor']['petal_len'].values,color='red',marker='x',label='Iris-versicolor')
plt.xlabel('sepal_len')
plt.ylabel('petal_len')
plt.legend(loc = 'upper left')
plt.show()
点的分布图
当前样本的
x = df.values[::,0:-1:2] ##此处只取第0列和第3列
y = df.values[::,-1::]
y[y=='Iris-setosa'] = -1
y[y=='Iris-versicolor'] = 1
x = np.array(x, dtype=float)
y = np.array(y, dtype=float)
n = 2#获取特征数量
m = df.shape[0]#样本数量
#初始化w,b
w = np.random.random(n)
b = 0
eta = 1#学习率
开始训练
#不断迭代
Time = 0
while True:
update = False
for i in range(m):
Time
#满足则说明分类错误,进行梯度下降
if y[i] * (w.dot(x[i])+b) <= 0:
w = w + eta * y[i] * x[i]
b = b + eta * y[i]
update = True
print(w, b)
#如果没有更新,说明全部分类正确,直接
if Time > 10**9 or update == False:
break
'''
输出:
[-4.31809634 -0.81533251] [-1.]
[2.68190366 3.88466749] [0.]
[-2.41809634 2.48466749] [-1.]
[4.58190366 7.18466749] [0.]
[-0.51809634 5.78466749] [-1.]
[-5.41809634 4.38466749] [-2.]
[1.58190366 9.08466749] [-1.]
[-3.51809634 7.68466749] [-2.]
'''
绘制结果
def predict(all):
return np.sign(all.dot(w.T) + b)
ans = np.array([], dtype = int)
for every in all:
if w.dot(every)+b < 0:
ans = np.append(ans, -1)
else:
ans = np.append(ans, 1)
return ans
def plot_decision_regions(x, y):
x1_min,x2_min = x.min(axis = 0)-1
x1_max,x2_max = x.max(axis = 0)+1
x1 = np.linspace(x1_min, x1_max, 500)
x2 = np.linspace(x2_min, x2_max, 500)
x1, x2=np.meshgrid(x1, x2) # 生成网格采样点
x_show = np.stack((x1.flat, x2.flat), axis=1) # 测试点
y_predict=predict(x_show)##将所有点求出正确的y
colors = ('lightgreen', 'LightPink', 'red', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
plt.pcolormesh(x1, x2, y_predict.reshape(x1.shape), cmap=cmap)
plt.xlim(x1.min(), x1.max())
plt.ylim(x2.min(), x2.max())
#绘制Iris-setosa的点
plt.scatter(df[df.Class=='Iris-setosa']['sepal_len'].values, df[df.Class=='Iris-setosa']['petal_len'].values,color='green',marker='o',label='Iris-setosa')
#绘制Iris-versicolor的点
plt.scatter(df[df.Class=='Iris-versicolor']['sepal_len'].values, df[df.Class=='Iris-versicolor']['petal_len'].values,color='red',marker='x',label='Iris-versicolor')
plt.xlabel('sepal_len')
plt.ylabel('petal_len')
plt.legend(loc = 'upper left')
plt.show()
plot_decision_regions(x,y)
分类结果图
7.思考题
7.1.习题2.1
问:感知机为什么不能表示异或?
答:因为异或线性不可分。
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
感知机模型:
在本题中可以定义
可以将异或的四种情况绘制成上图,可发现线性不可分。
7.2.习题2.2
问:模仿例题2.1,构建从训练数据集求解感知机模型的例子。
略,直接可以参考第6节代码实践。
7.3.习题2.3
证明:样本集线性可分的充分必要条件是正实例点集所构成的凸壳与负实例点所构成的凸壳互不相交。
凸壳
设集合,是由中的个点所组成的集合,即。定义的凸壳为:
凸壳是一个集合,包含最外层的“壳”,还包括所有在“壳”内的所有元素。
线性可分
概念见4.1
必要性:线性可分->凸壳不相交
设数据集中的正实例点为,的凸壳为,负实例点为,的凸壳为。
若数据集线性可分,则一定存在超平面:
能够将分离。
假设对所有正实例点有:
显然。
假设对所有负实例点有:
显然。
对于凸壳中的点而言:
对于凸壳中的所有点有:
因此:
对于凸壳中所有点有:
假设的凸壳相交,等价于存在一点同时满足,所以:
产生矛盾,所以凸壳一定不相交。
充分性:凸壳不相交->线性可分
设数据集中的正实例点为,的凸壳为,负实例点为,的凸壳为,且与不相交,定义两个点之间的距离为:
定义与的距离为:
设,也就是说这两个点的距离就是两个凸壳之间的距离。
则对于任意的有。
则对于任意的有。
存在超平面,其中
对于任意的正例点
只需要证明即可,也就是证明:
利用反证法,假设,由上文可知,就有。
为了更好理解,绘制出二维平面的三个点,其中
由边的比例大小关系,在之间存在一点满足。由于,所以,但是显然。
这就违反了之前的假设:对于任意的有。
所以假设错误,命题得证。对于负例点也是如此可以证明。
8.扩展
8.1 训练过程图示
可以从下图了解感知机的训练过程
线性可分 线性不可分9.参考资料
[1]李航.统计学习方法[M].清华大学出版社:,2012
[2]如何理解超平面:https://www.jianshu.com/p/ba02b92baaaf
[3]感知机原理:https://www.cnblogs.com/huangyc/p/9706575.html
[4]感知机学习视频:https://www.bilibili.com/video/BV1C7411T79U、https://www.bilibili.com/video/BV197411T7i6
[5]知乎讨论——感知机的损失函数为什么可以采用函数间隔:https://www.zhihu.com/question/36241719
[6]感知机为什么不能表示异或:https://www.jianshu.com/p/e79169493d75
[7]凸壳与线性可分:https://blog.csdn.net/y954877035/article/details/52210734
网友评论