感知机(perceptron)于1957年由Rosenblatt提出,是神经网络与支持向量得基础。其输入为实例得特征向量,输出为实例得类别,是二类分类的线性分类模型,属于判别模型。感知机的学习旨在求出将训练数据进行线性划分的超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得感知机模型。
感知机定义 假设输入空间(特征空间)是 X ∈ R n \it{X}\in{R^n} X∈Rn,输出空间是 Y ∈ { + 1 , − 1 } Y \in \{+1,-1\} Y∈{+1,−1} 。输入 x ∈ X x\in X x∈X 表示实例的特征向量,对应于输入空间(特征空间)的点;输出 y ∈ Y y\in Y y∈Y 表示实例的类别,则输入空间到输出空间的映射:
f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w\cdot x+b) f(x)=sign(w⋅x+b)
上述称为感知机。 w w w 叫做权值或权向量 和 b b b 叫做偏置,均为感知机模型参数, w ⋅ x w \cdot x w⋅x 表示内积。 s i g n sign sign是符号函数,即
s i g n ( x ) = { + 1 , x ≥ 0 − 1 , x < 0 sign(x)=\begin{cases} +1, & x \geq 0 \\ -1 , & x < 0 \end{cases} sign(x)={+1,−1,x≥0x<0
感知机模型的假设空间是定义在特征空间中的所有线性分类模型(linear classification model)或线性分类器(linear classifier),即函数集合 f ∣ f ( x ) = s i g n ( w ⋅ x + b ) f|f(x)=sign(w\cdot x+b) f∣f(x)=sign(w⋅x+b)。 w ⋅ x + b = 0 w\cdot x+b=0 w⋅x+b=0 称为分类超平面。
假设训练数据集是线性可分(线性可分指存在超平面 w ⋅ x + b = 0 w\cdot x+b=0 w⋅x+b=0 可将数据集正负例完全正确地划分至超平面两侧),其学习目标就是求得这样一个超平面。为了求得这个超平面,其策略为定义一个损失函数,并将损失函数极小化。
感知机采用的损失函数是误分类点到超平面 S S S 的总距离。因此,输入空间 R n R^n Rn中任一点 x 0 x_0 x0 到超平面的距离为(假设超平面上的一点为 x x x,则有 w ⋅ x + b = 0 w\cdot x+b=0 w⋅x+b=0):
d 0 = ∣ w ∣ ∣ w ∣ ∣ ( x 0 − x ) ∣ = 1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ d_0= |\frac{w}{||w||}(x_0-x)|=\frac{1}{||w||}|w\cdot x_0 + b| d0=∣∣∣w∣∣w(x0−x)∣=∣∣w∣∣1∣w⋅x0+b∣
其中, ∣ ∣ w ∣ ∣ ||w|| ∣∣w∣∣ 是 w w w 的 L 2 L_2 L2范数。
对于误分类的数据 ( x i , y i ) (x_i, y_i) (xi,yi) 来说,假设 ( x i , y i ) (x_i, y_i) (xi,yi)输入正样本即 y i = + 1 y_i= +1 yi=+1,但由于误分类总有 w ⋅ x i + b ≤ 0 w \cdot x_i + b \leq 0 w⋅xi+b≤0 ;同理 ( x i , y i ) (x_i, y_i) (xi,yi)输入负样本即 y i = − 1 y_i= -1 yi=−1, 但由于误分类总有 w ⋅ x i + b > 0 w \cdot x_i + b > 0 w⋅xi+b>0, 因此有下式成立:
− y i ( w ⋅ x i + b ) > 0 - y_i (w \cdot x_i + b) >0 −yi(w⋅xi+b)>0
故误分类点 ( x i , y i ) (x_i, y_i) (xi,yi)到超平面的距离可表示为:
d i = − 1 ∣ ∣ w ∣ ∣ y i ( w ⋅ x i + b ) d_i= -\frac{1}{||w||}y_i(w\cdot x_i + b) di=−∣∣w∣∣1yi(w⋅xi+b)
假设超平面S的误分类点集合为 M M M,那么所有误分类点的超平面的总距离为
d = − 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M ( w ⋅ x i + b ) d= -\frac{1}{||w||}\sum_{x_i \in M}{(w\cdot x_i + b)} d=−∣∣w∣∣1xi∈M∑(w⋅xi+b)
由于感知机的学习是基于误分类驱动的,即只需要判断 y i ( w ⋅ x i + b ) y_i (w \cdot x_i + b) yi(w⋅xi+b)的正负即可,与 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1 无关,且 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1是用来归一化超平面法向量,得到几何间隔,因此可以不考虑 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} ∣∣w∣∣1,只考虑其函数间隔,这样得到感知机的(经验)损失函数:
L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) L(w,b)= -\sum_{x_i \in M}{y_i(w\cdot x_i + b)} L(w,b)=−xi∈M∑yi(w⋅xi+b)
感知机学习算法是为了使得误分类点的个数最少化,则这个问题就可以转换为对损失函数极小化的问题,即求解损失函数最小时对应的超平面
min w , b L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) \min_{w,b}{L(w,b)}= -\sum_{x_i \in M}{y_i(w\cdot x_i + b)} w,bminL(w,b)=−xi∈M∑yi(w⋅xi+b)
感知机学习算法是误分类驱动的,具体采用随机梯度下降法(stochastic gradient descent, SGD)。
假设误分类点集合 M M M固定的, 那么损失函数的梯度可表示为
∇ w L ( w , b ) = − ∑ x i ∈ M y i x i \nabla_{w}L(w,b)=-\sum_{x_i \in M}{y_i x_i} ∇wL(w,b)=−xi∈M∑yixi
∇ b L ( w , b ) = − ∑ x i ∈ M y i \nabla_{b}L(w,b)= -\sum_{x_i \in M}y_i ∇bL(w,b)=−xi∈M∑yi
随机选取一个误分类点 ( x i , y i ) (x_i,y_i) (xi,yi), 对 w w w, b b b进行更新:
w ⟵ w + η y i x i w \longleftarrow w+\eta y_ix_i w⟵w+ηyixi b ⟵ b + η y i b \longleftarrow b + \eta y_i b⟵b+ηyi
式中 η ( 0 < η ≤ 1 ) \eta(0<\eta \leq 1) η(0<η≤1) 是步长, 又称学习率(learning rate). 这样通过迭代可以期待损失函数不断减小,直至为0.
原始形式算法可总结为如下:
输入: 训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } T= \{ (x_1,y_1),(x_2,y_2), \dotsi,(x_N,y_N) \} T={(x1,y1),(x2,y2),⋯,(xN,yN)} 其中 x i ∈ X = R n x_i \in X=R^n xi∈X=Rn , y i ∈ Y = { − 1 , + 1 } , i = 1 , 2 , … , N y_i \in Y=\{-1,+1\},i=1,2,\dotsc,N yi∈Y={−1,+1},i=1,2,…,N ; 学习率 η ( 0 < η ≤ 1 ) \eta(0<\eta \leq 1) η(0<η≤1) ;
输出: w , b w,b w,b; 感知机模型 f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w\cdot x+b) f(x)=sign(w⋅x+b).
# 例2.1简单求解,不全面
import numpy as np
X = np.array([[1,1],[4,3],[3,3]])
Y = np.array([[-1],[1],[1]])
eta = 0.5
w = np.zeros((1, X.shape[1]))
b = np.zeros((1))
for epoch in range(15):
for x,y in zip(X,Y):
x = x.reshape((-1,1))
if y * (np.dot(w,x) + b) <= 0:
w = w + eta * y * x.T
b = b + eta * y
print(w,b)
print((np.multiply(Y,np.dot(X,w.T) + b)).reshape((1,-1)))
N o v i k o f f \tt{Novikoff} Novikoff 定理表明, 当数据集线性可分时,误分类的次数是有上界的,经过有限次搜索可以找到将训练数据完全分开的分离超平面.也就是说,感知机学习算法原始形式迭代是收敛的.但这种算法有很多可能解,这些解即依赖于算法初值的选择,也依赖于迭代过程中误分类点的选择顺序.
在原始形式中,通过逐步更新 w , b w,b w,b 来求出超平面,对偶形式的基本想法是: 将 w w w 和 b b b 表示为实例 x i x_i xi 和标记 y i y_i yi 的线性组合的形式,通过求解其系数而求得 w w w 和 b b b.
对偶形式算法可总结为如下:
输入: 训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } T= \{ (x_1,y_1),(x_2,y_2), \dotsi,(x_N,y_N) \} T={(x1,y1),(x2,y2),⋯,(xN,yN)} 其中 x i ∈ X = R n x_i \in X=R^n xi∈X=Rn , y i ∈ Y = { − 1 , + 1 } , i = 1 , 2 , … , N y_i \in Y=\{-1,+1\},i=1,2,\dotsc,N yi∈Y={−1,+1},i=1,2,…,N ; 学习率 η ( 0 < η ≤ 1 ) \eta(0<\eta \leq 1) η(0<η≤1) ;
输出: α , b \alpha,b α,b; 感知机模型 f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w\cdot x+b) f(x)=sign(w⋅x+b).
#例2.2 简单求解,不全面
import numpy as np
X = np.array([[1,1],[4,3],[3,3]])
Y = np.array([[-1],[1],[1]])
eta = 1
alpha = np.zeros((X.shape[0], 1))
b = np.zeros((1))
for epoch in range(50):
for idx in range(len(Y)):
xi = X[idx,:].reshape((-1,1))
yi = Y[idx]
temp = np.zeros((1,2))
for i in range(len(Y)):
temp += alpha[i]* Y[i] * X[i,:]
if yi * (temp.dot(xi) + b)<= 0:
alpha[idx] = alpha[idx] + eta
b += eta * yi
w = np.zeros((1,2))
for i in range(len(Y)):
w += alpha[i]* Y[i] * X[i,:]
print(w, b)