【感知机】
1957年由Rosenblatt提出,是神经网络与支持向量机的基础。
感知机旨在求出将训练数据进行线性划分的分离超平面。(判别模型)
(存在一个线性函数分离的超平面能将训练数据划分为正负两类。解不唯一,依赖于初始值的选择。若要唯一,请看线性支持向量机。)
1.模型
wx+b是一个n维空间中的超平面S,其中w是超平面的法向量,b是超平面的截距,这个超平面将特征空间划分成两部分,位于两部分的点分别被分为正负两类,所以,超平面S称为分离超平面。
2.策略
定义(经验)损失函数,并将损失函数极小化。
2.1 函数间隔和几何间隔
单独计算一个点x0与超平面S之间距离的公式:
这里,||w||是w的L2范数。|wx+b|叫函数间隔,除模长||w||之后叫几何间隔。几何间隔可以认为是物理意义上的实际长度,无论怎么放大缩小,物理距离保持不变。在机器学习中求距离时,通常是使用几何间隔的,否则无法求出解。
(点x0到超平面S:wx+b=0的距离d的计算过程如下:)
假设超平面S的误分类点集合为M,那么所有误分类点到超平面S的总距离:
2.2 损失函数:
误分类点到超平面S的总距离(不考虑1/||w||)
(为什么不考虑—1/||w||(L2范数)?原因如下:)
①不影响正负判断(即不影响中间过程);
②不影响学习算法的最终结果。因为学习算法的终止条件是不存在误分类的点,损失函数为0,即分子为0。
(正则化:)
▶正则化是结构风险最小化策略的实现。
▶奥卡姆剃刀(Occam’s razor)原理 :“如无必要,勿增实体”,即简单有效原理。在所有可能选择的模型中,能够很好地解释已知数据并且十分简单才是最好的模型。(降低模型复杂度→提高模型泛化能力)
▶从Bayes角度来看,正则相当于对模型参数引入先验分布:
L1使一些特征的系数变小,甚至为0;L2在不抛弃任何一个特征的情况下,缩小了回归系数。
不同优点原因:因为L1不可导(次梯度、次微分);L2缩放。
2.3 学习策略
感知机学习的策略是在假设空间中选取使损失函数式(2.4)最小的模型参数w、b,即感知机模型。
3.算法
感知机学习问题转化为求解损失函数式(2.4)的最优化问题,最优化的方法是随机梯度下降法(感知机学习算法是误分类驱动的,因此采用随机梯度下降法(我们每次仅仅需要使用一个误分类的点来更新梯度))。
3.1 随机梯度下降法(计算速度快,内存开销小)
步骤:首先任意选取一个超平面w0,b0,然后用梯度下降法不断地极小化目标函数。极小化的过程是一次随机选取一个误分类点使其梯度下降。
(梯度下降法:)
在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。
每走到一个位置的时候,求解当前位置的梯度,沿着梯度的负方向(why?方向导数的角度/最优化的角度),也就是当前最陡峭的位置向下走一步,然后继续求解当前位置梯度,直到一步步走到最低点。(梯度下降不一定能够找到全局的最优解,有可能是一个局部最优解。如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。)
梯度算子▽的读音:
“纳布达”(Nabla)。(Nabla 原指一种希伯来竖琴,外形酷似倒三角。)
3.2 原始形式
3.3 对偶形式
对偶形式的基本想法是,将w和b表示为实例xi和标记yi的线性组合的形式,通过求解其系数而求得w和b。
4.代码
def perceptron(dataArr, labelArr, iter=50):
'''
感知器训练过程
:param dataArr:训练集的数据 (list)
:param labelArr: 训练集的标签(list)
:param iter: 迭代次数,默认50
:return: 训练好的w和b
'''
print('start to trans')
#将数据转换成矩阵形式(在机器学习中因为通常都是向量的运算,转换称矩阵形式方便运算)
#转换后的数据中每一个样本的向量都是横向的
dataMat = np.mat(dataArr)
#将标签转换成矩阵,之后转置(.T为转置)。
#转置是因为在运算中需要单独取label中的某一个元素,如果是1xN的矩阵的话,无法用label[i]的方式读取
#对于只有1xN的label可以不转换成矩阵,直接label[i]即可,这里转换是为了格式上的统一
labelMat = np.mat(labelArr).T
#获取数据矩阵的大小,为m*n
m, n = np.shape(dataMat)
#创建初始权重w,初始值全为0。
#np.shape(dataMat)的返回值为m,n -> np.shape(dataMat)[1])的值即为n,与
#样本长度保持一致
w = np.zeros((1, np.shape(dataMat)[1]))
#初始化偏置b为0
b = 0
#初始化步长,也就是梯度下降过程中的n,控制梯度下降速率
h = 0.0001
#进行iter次迭代计算
for k in range(iter):
#对于每一个样本进行梯度下降
#李航书中在2.3.1开头部分使用的梯度下降,是全部样本都算一遍以后,统一
#进行一次梯度下降
#在2.3.1的后半部分可以看到(例如公式2.6 2.7),求和符号没有了,此时用
#的是随机梯度下降,即计算一个样本就针对该样本进行一次梯度下降。
#两者的差异各有千秋,但较为常用的是随机梯度下降。
for i in range(m):
#获取当前样本的向量
xi = dataMat[i]
#获取当前样本所对应的标签
yi = labelMat[i]
#判断是否是误分类样本
#误分类样本特诊为: -yi(w*xi+b)>=0,详细可参考书中2.2.2小节
#在书的公式中写的是>0,实际上如果=0,说明改点在超平面上,也是不正确的
if -1 * yi * (w * xi.T + b) >= 0:
#对于误分类样本,进行梯度下降,更新w和b
w = w + h * yi * xi
b = b + h * yi
#打印训练进度
print('Round %d:%d training' % (k, iter))
#返回训练完的w、b
return w, b
REFERENCE
《统计学习方法》李航