引言
本文主要介绍了感知机引入,并且附有一些实例代码和恰当的图片,让大家更容易理解。
首先介绍下什么是感知机。
感知机
感知机是二类分类的线性模型,其输入为实例的特征向量,输出为实例的类别,类别取+1,-1二值。
感知机对应于输入空间(特征空间)中将实例划分为正负两类的分离超平面,属于判别模型。
感知机分为原始形式和对偶形式。
感知机模型
假设输入空间时
X⊆Rn,输出空间时
Y={+1,−1}。由输入空间到输出空间的如下函数:
f(x)=sign(w⋅x+b)
其中
w∈Rn(属于
n维实数集)叫权值(weight,或叫权重,通常是个向量),
b∈R,叫偏置(或偏差)。
w⋅x表示这两个向量的内积。
sign是符号函数,即
{+1,x≥0−1,x<0
感知机是一种线性分类模型,其假设空间时定义在特征空间中的所有线性分类模型(或线性分类器),即函数集合
{f∣f(x)=w⋅x+b}
它的几何解释是线性方程
w⋅x+b=0,该方程对应于特征空间
Rn的一个超平面
S,
w是超平面的法向量,
b是超平面的截距。
超平面是n维欧氏空间中余维度等于一的线性子空间,也就是必须是(n-1)维度。这是平面中的直线、空间中的平面之推广(n大于3才被称为“超”平面)。
该超平面将特征空间划分为两个部分。位于两部分的点分贝被分为正、负两类。因此,超平面
S称为分离超平面。
感知机学习的训练数据集(实例的特征向量及类别)是这样的:
T={(x1,y1),(x2,y2),⋯,(xN,yn)}
感知机学习策略
给定上面的数据集
T,如果存在某个超平面
S:w⋅x+b=0能将数据集的正实例点和负实例点完全正确地划分到超平面的两侧,即对所有
yi=+1的实例
i,都有
w⋅xi+b>0,对所有
yi=−1的实例
i有
w⋅xi+b<0 ,则称数据集
T为线性可分数据集;否则,线性不可分。
假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练集正实例点和负实例点完全正确分开的超平面。为了找出这样的超平面,即确定感知机模型参数
w,b,需要确定一个学习策略,即定义损失函数并最小化它。
损失函数一般是计算所有误分类点到超平面
S的总距离。为此,首先写出输入空间中任一点
x0到超平面的距离:
∣∣w∣∣1∣w⋅x0+b∣
这里
∣∣w∣∣是
w的
L2范数,或者说是模。
我们知道点
(x,y)到直线
Ax+by+C=0的距离为
A2+B2
Ax+by+C
可以看到它的分母是
A2+B2的开根号,也就是说,分母和截距无关。
拓展到
n维空间,
w⋅x+b=0,得
∣∣w∣∣∣w⋅x+b∣
∣∣w∣∣=w12+w22+⋯+wn2
因为距离是正的,所以取绝对值就得到了上面的式子。
对于误分类的数据
(xi,yi)来说,有
−yi(w⋅xi+b)>0。因为当
w⋅xi+b>0时,
yi=−1(注意是误分类点);而当
w⋅xi+b<0时,
yi=+1。它们乘起来在乘以
−1一定是大于
0的。
因此,我们把上面得到的距离公式乘以
−yi就得到了误分类点到超平面的距离公式:
−∣∣w∣∣1yi∣w⋅xi+b∣
因为
y的取值无非就是
+1,−1,然后上面又说了这个式子是一定大于0的,因此这个公式是成立的。
这样,假设超平面
S的误分类点集合为
M,那么所有误分类点到超平面
S的总距离为:
−∣∣w∣∣1xi∈M∑yi(w⋅xi+b)
如果不考虑
∣∣w∣∣1的话,就得到了感知机
sign(w⋅x+b)学习的损失函数:
L(w,b)=−xi∈M∑yi(w⋅xi+b)
注意,
M是误分类点的集合,如果是正确分类的点,其损失直接为0,就不需要参与计算。
感知机学习的策略是在假设空间中选取使损失函数最小的模型参数
w,b
感知机学习算法
感知机学习算法是误分类驱动的,采用随机梯度下降法。首先,任取一个超平面
w0,b0,然后用梯度下降法不断地极小化目标函数
L(w,b)=−∑xi∈Myi(w⋅xi+b)。极小化过程一次随机选取一个误分类点使其梯度下降。
损失函数
L(w,b)的梯度由:
∇wL(w,b)=−xi∈M∑yixi∇bL(w,b)=−xi∈M∑yi
简单的证明一下:
∂w∂L(w,b)=∂w∂(−∑xi∈Myi(w⋅xi+b))=∂w∂(−∑xi∈Myi(w⋅xi))+∂w∂(−∑xi∈Myib)=−xi∈M∑yixi
因为
yi,b是与
w无关的,所以微分就是
0,对
b求微分也同理。
随机选一个误分类点
(xi,yi)对
w,b进行更新:
w←w+ηyixib←b+ηyi
其中
η是学习率。
学习算法原始形式为:
- 选取初值
w0,b0;
- 在训练数据集中选取数据
(xi,yi);
- 如果
yi(w⋅xi+b)≤0 ,通过
w←w+ηyixi,b←b+ηyi更新:
- 跳转置2,直到训练集中没有误分类点
直观上的解释是:当一个实例点被误分类,也就是位于分离超平面的错误一侧时,调整
w,b的值,使分离超平面向该实例点的一侧移动,以减少误分类点与超平面的距离,直到超平面越过该误分类点使其被正确分类。
我们用iris数据集为例,用sepal length,sepal width作为特征。
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
只取里面的类别0和1,将它们的散点图画出来:
data = np.array(df.iloc[:100, [0, 1, -1]])
x, y = data[:,:-1], data[:,-1]
y = np.array([1 if i == 1 else -1 for i in y])
class Model:
def __init__(self):
self.w = np.ones(len(data[0])-1, dtype=np.float32)
self.b = 0
self.l_rate = 0.1
def sign(self, x, w, b):
y = np.dot(x, w) + b
return y
def fit(self, x_train, y_train):
is_done = False
while not is_done :
wrong_count = 0
for d in range(len(x_train)):
x = x_train[d]
y = y_train[d]
if y * self.sign(x, self.w, self.b) <= 0:
self.w = self.w + self.l_rate*np.dot(y, x)
self.b = self.b + self.l_rate*y
wrong_count += 1
if wrong_count == 0:
is_done = True
模型写好了,接下来画出预测的结果:
perceptron = Model()
perceptron.fit(x, y)
x_points = np.linspace(4, 7,10)
y_ = -(perceptron.w[0]*x_points + perceptron.b)/perceptron.w[1]
plt.plot(x_points, y_)
plt.plot(data[:50, 0], data[:50, 1], 'bo', color='blue', label='-1')
plt.plot(data[50:100, 0], data[50:100, 1], 'bo', color='orange', label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
感知机学习算法的对偶形式
对偶形式的基本想法是,将
w和
b表示为实例
xi和标记
yi的线性组合的形式,通过求解其系数而求得
w和
b。其实就是将当前的
w用之前的累计更新来表示。
不失一般性,设初始值
w0,b0均为
0,对误分类点
(xi,yi)通过
w←w+ηyixib←b+ηyi
如果某个误分类点
(xi,yi)被多次选中,那么它对当前的参数就进行了
n次更新,就会使
w,b改变如下:
Δw=nηyixiΔb=nηyi
对偶形式的参数更新就是更新某个误分类点参与更新的次数,就是更新这个
n。更新过程中被选中的每个误分类点都可以如上表示,将它们全部加起来,就可以表示由初始的
w0,b0到当前的
w,b之间的总变化,则
w的表示形式如下:
w=w0+n1ηy1x1+n2ηy2x2+⋯+niηyixi
这个式子包含了训练集所有的点,如果某个点未被选中,则
n=0。我们把上式中的
niη改写为
αi,而上面说了,初始值
w0,b0均为
0,所以可以写成:
w=i=1∑Nαiyixi
因此上面的感知机模型可以写成下面的式子:
f(x)=sign(j=1∑Nαjyjxj⋅x+b)
对偶形式的算法如下:
- 设置初值
α←0,b←0;
- 在训练集中选取数据
(xi,yi);
- 如果
yi(∑j=1Nαjyjxj⋅xi+b)≤0, 则
αi←αi+η,b←b+ηyi;
- 跳转到2直到没有误分类数据
b的更新方式和原始形式一样,这没问题。我们重点来看下
α的更新方式。
α表示的是
niη,当我们用上面的方式进行更新时,其实就是使
ni增加了
1,相当于
∑i=1Nαiyixi 增加了
ηyixi,也就是:
i=1∑Nαiyixi+ηyixi
再结合
w=∑i=1Nαiyixi
这里的更新就等价于
w←w+ηyixi
参考
- 李航.统计学习方法第二版