感知机是《统计学习方法》的介绍的第 1 个算法,是神经网络与 SVM 的基础。
研究思路
1、模型:二分类问题,数据点分为“”类和“”类,“超平面”为所求;
2、策略:损失函数最小化,确定参数 和 ;
3、算法:随机梯度下降法。
策略:随机梯度下降
用普通的基于所有样本的梯度和的均值的批量梯度下降法(BGD)是行不通的,原因在于我们的损失函数里面有限定,只有误分类的 M 集合里面的样本才能参与损失函数的优化。所以我们不能用最普通的批量梯度下降,只能采用随机梯度下降(SGD)或者小批量梯度下降(MBGD)。
感知机学习的对偶形式
将 和 表示成实例 和 的线性组合。
1、 ,,则 和 就可以表示成 和 的线性组合;
2、实现技巧:向量化代替 for 循环。
对于损失函数的理解
感知机学习固定分母为 。我们研究可以发现,分子和分母都含有 ,当分子的 扩大 倍时,分母的 范数也会扩大 倍。也就是说,分子和分母有固定的倍数关系。那么我们可以固定分子或者分母为 ,然后求另一个即分子自己或者分母的倒数的最小化作为损失函数,这样可以简化我们的损失函数。在感知机模型中,我们采用的是保留分子,即最终感知机模型的损失函数简化为:
我的理解:反正最终都会收敛,所以损失函数收敛的时候一定为 ,因此分母是多少都无所谓,这就是书上说的“不考虑 ”。
手写笔记
编码实现
代码还可以在 这里 查看。
Python 代码:
import numpy as np
class Perceptron:
"""
感知机分类器:假设数据集是线性可分的
"""
def __init__(self, eta=0.01, n_iter=10):
"""
:param eta: 学习率,between 0.0 and 1.0,float
:param n_iter: 最大迭代次数,int
"""
self.eta = eta
self.n_iter = n_iter
def fit(self, X, y):
# 同李航《统计学习方法》P29
# "1" 表示偏置,即如果变量有 2 个,学习的权重就会有 3 个
# 感知机就是学习这一组参数向量
# 这里 y 只有两个取值,1 或者 -1
# target - self.predict(xi),predict 函数返回 1 或者 -1
# 如果相同,则上式 = 0,即分类正确的点对权重更新没有帮助
self.w_ = np.zeros(1 + X.shape[1])
# print(self.w_)
self.errors_ = []
for _ in range(self.n_iter):
# print('迭代次数', _)
# 表示这一轮分错的数据的个数
errors = 0
# 把所有的数据都看一遍
for xi, target in zip(X, y):
# 【注意】这个处理就包括了 target 和 self.predict 相等的情况,
# 如果相等,下面两行 self.w_[1:] 和 self.w_[0] 都不会更新
# 如果不等,相当于朝着父梯度方向走了一点点
# 随机梯度下降法,每次只使用一个数据更新权重
# print('实际',target,'预测',self.predict(xi))
if target == self.predict(xi):
continue
update = self.eta * target
# w
self.w_[1:] += update * xi
# b
self.w_[0] += update
errors += int(update != 0.0)
# 如果这一轮分类都正确,则感知机学习可以停止了
if errors == 0:
break
self.errors_.append(errors)
return self
def net_input(self, X):
"""
计算输出
:param X:
:return:
"""
# X 是 m * n 型
# self.w_[1:] 是 n * 1 型,可以 dot
# + self.w_[0] 发生了广播
return np.dot(X, self.w_[1:]) + self.w_[0]
def predict(self, X):
"""
预测类别变量,只返回 1 或者 -1
:param X:
:return:
"""
return np.where(self.net_input(X) >= 0.0, 1, -1)
示例
例1:鸢尾花数据集可视化
<iframe src="https://nbviewer.jupyter.org/github/liweiwei1419/Machine-Learning-is-Fun/blob/master/Perceptron-learning/notebook/%E9%B8%A2%E5%B0%BE%E8%8A%B1%E6%95%B0%E6%8D%AE%E9%9B%86%E5%8F%AF%E8%A7%86%E5%8C%96.ipynb" width="800" height="1000"></iframe>
例2:感知机算法的 Python 实现
<iframe src="https://nbviewer.jupyter.org/github/liweiwei1419/Machine-Learning-is-Fun/blob/master/Perceptron-learning/notebook/%E6%84%9F%E7%9F%A5%E6%9C%BA%E7%AE%97%E6%B3%95%E7%9A%84%20Python%20%E5%AE%9E%E7%8E%B0.ipynb" width="800" height="1000"></iframe>
参考资料
[1] 李航. 统计学习方法(第 2 版)第 2 章“感知机”. 北京:清华大学出版社,2019.
[2] 刘建平. 感知机原理小结、梯度下降(Gradient Descent)小结.
[3] 码农场. 感知机的学习.
[4] 知乎网友. 如何理解感知机学习算法的对偶形式?.
说明:对偶形式把累加变成了乘法运算,并且引入了 Gram 矩阵。
[5] Sebastian Raschka. Python 机器学习 第 2 章. 北京:机械工业出版社,2019.
(本节完)