机器学习系列 02:感知机

  本内容将介绍机器学习中的 感知机模型,并说明感知机学习算法的原始形式和对偶形式。

  感知机(perceptron)是二分类线性分类模型,属于判别模型,是一种监督学习算法
  其输入为实例的特征向量,输出为实例的类别,取 +1 和 -1 二值。感知机对应于输入空间(特征空间)中将实例划分为正负两类的分离超平面,属于判别模型。感知机学习旨在求出将训练数据进行线性划分的分离超平面,为此,导入基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,求得感知机模型。感知机学习算法具有简单而易于实现的优点,分为原始形式对偶形式。感知机预测是用学习得到的感知机模型对新的输入实例进行分类。感知机 1957 年由 Rosenblatt 提出,是神经网络支持向量机的基础。

一、感知机模型

  假设输入空间(特征空间)是 X ⊆ R n \mathcal{X} \subseteq \mathbf{R}^n XRn,输出空间是 Y = { + 1 , − 1 } \mathcal{Y}=\{+1,-1\} Y={+1,1}。输入 x ∈ X x\in\mathcal{X} xX 表示实例的特征向量,对应于输入空间(特征空间)的点;输出 y ∈ Y y\in\mathcal{Y} yY 表示实例的类别。由输入空间到输出空间的如下函数:

f ( x ) = s i g n ( w ⋅ x + b ) ( 1.1 ) f(x)=sign(w\cdot x+b) (1.1) f(x)=sign(wx+b)1.1

称为感知机。其中, w w w b b b 为感知机模型参数, w ∈ R n w\in \mathbf{R}^n wRn 叫作权值(weight)或权值向量(weight vector), b ∈ R b\in \mathbf{R} bR 叫作偏置(bias), w ⋅ x w\cdot x wx 表示 w w w x x x 的点积。sign 是符号函数,即

s i g n ( x ) = { + 1 , x ≥ 0 − 1 , x < 0 ( 1.2 ) sign(x)=\left \{\begin{array}{cc}+1, &x\geq0\\ -1,& x<0 \end{array}\right. (1.2) sign(x)={+1,1,x0x<01.2

  感知机模型的假设空间是定义在特征空间中的所有线性分类模型(linear classification model)或线性分类器(linear classifier),即函数 { f ∣ f ( x ) = w ⋅ x + b } \{f|f(x)=w\cdot x+b\} {ff(x)=wx+b}

二、感知机学习策略

  假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练集中正实例点和负实例点完全正确分开的分离超平面。为了找出这样的超平面,即确定感知机模型参数 w w w b b b,需要确定一个学习策略,即定义(经验)损失函数并将损失函数极小化。
  感知机将误分类点到超平面 S S S 的总距离作为损失函数。输入空间 R n \mathbf{R}^n Rn 中任一点 x 0 x_0 x0 到超平面 S S S 的距离:

1 ∣ ∣ w ∣ ∣ ∣ w ⋅ x 0 + b ∣ \frac{1}{||w||}|w\cdot x_0+b| w1wx0+b

其中, ∣ ∣ w ∣ ∣ ||w|| w w w w L 2 L_2 L2 范数。
  另外,误分类的数据 ( x i , y i ) (x_i,y_i) (xi,yi) 满足

− y i ( w ⋅ + b ) > 0 -y_i(w\cdot+b)>0 yi(w+b)>0

  因此,误分类点 x i x_i xi 到超平面 S S S 的距离是

− 1 ∣ ∣ w ∣ ∣ y i ( w ⋅ x i + b ) -\frac{1}{||w||}y_i(w\cdot x_i+b) w1yi(wxi+b)

  假设超平面 S S S 的误分类点集合为 M M M,那么所有误分类点到超平面 S S S 的总距离为

− 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M y i ( w ⋅ x i + b ) -\frac{1}{||w||}\sum_{x_i\in M}y_i(w\cdot x_i+b) w1xiMyi(wxi+b)

如果假设 ∣ ∣ w ∣ ∣ = 1 ||w|| = 1 w=1,就得到感知机学习的损失函数

L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) ( 1.3 ) L(w,b)=-\sum_{x_i\in M}y_i(w\cdot x_i+b)(1.3) L(w,b)=xiMyi(wxi+b)1.3

其中 M M M 为误分类点的集合。这个损失函数就是感知机学习的经验风险函数。
  对一个特定的样本点的损失函数:在误分类时是参数 w w w b b b 的线性函数,并且大于0,在正确分类时是 0。因此,给定训练数据集 T T T,损失函数 L ( w , b ) L(w,b) L(w,b) w w w b b b 的连续可导函数,并且是非负的。
  感知机学习的策略是在假设空间中选取使损失函数式(1.3)最小的模型参数 w w w b b b ,即感知机模型。

三、感知机学习算法

  感知机学习问题转化为求解损失函数式(1.3)的最优化问题,最优化的方式是随机梯度下降法。感知机学习算法分为原始形式和对偶形式。

3.1 感知机学习算法的原始形式

  感知机学习算法是对以下最优化问题的算法。给定一个训练集

T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) } T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\} T={(x1,y1),(x2,y2),,(xN,yN)}

其中 x i ∈ X = R n x_i\in \mathcal{X}=\mathbf{R}_n xiX=Rn y i ∈ Y = { − 1 , + 1 } y_i\in \mathcal{Y}=\{-1,+1\} yiY={1,+1} i = 1 , 2 , ⋯   , N i=1,2,\cdots,N i=1,2,,N,求参数 w w w b b b,使其为以下损失函数极小化问题的解

min ⁡ w , b L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) ( 1.4 ) \min_{w,b}L(w,b)=-\sum_{x_i\in M}y_i(w\cdot x_i+b)(1.4) w,bminL(w,b)=xiMyi(wxi+b)1.4

其中 M M M 为误分类点的集合。
  感知机学习算法是误分类驱动的,具体采用随机梯度下降法(stochastic gradient descent)。首先,任意选取一个超平面 w 0 w_0 w0 b 0 b_0 b0,然后用梯度下降法不断地极小化目标函数(1.4)。极小化过程中不是一次使 M M M 中所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。
  假设误分类点集合 M M M 是固定的,那么损失函数 L ( w , b ) L(w,b) L(w,b) 的梯度由

∇ w L ( w , b ) = − ∑ x i ∈ M y i x i \nabla_{w}L(w,b)=-\sum_{x_i\in M}y_ix_i wL(w,b)=xiMyixi

∇ b L ( w , b ) = − ∑ x i ∈ M y i \nabla_{b}L(w,b)=-\sum_{x_i\in M}y_i bL(w,b)=xiMyi

给出。
  随机选取一个误分类点 ( w i , y i ) (w_i,y_i) (wi,yi),对 w w w b b b 进行更新:

w ← w + η y i x i w\leftarrow w+\eta y_ix_i ww+ηyixi

b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi

式中 η ( 0 < η ≤ 1 ) \eta(0<\eta\leq1) η(0<η1) 是步长,在统计学习中又称为学习率(learning rate)。这样,通过迭代可以期待损失函数 L ( w , b ) L(w,b) L(w,b) 不断减小,直到为 0。综上所述,得到如下算法:

  算法 1.1 (感知机学习算法的原始形式)

输入:训练数据集 T = ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) T={(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)} T=(x1,y1),(x2,y2),,(xN,yN),其中 x i ∈ X = R n x_i\in \mathcal{X}=\mathbf{R}_n xiX=Rn y i ∈ Y = { − 1 , + 1 } y_i\in \mathcal{Y}=\{-1,+1\} yiY={1,+1} i = 1 , 2 , ⋯   , N i=1,2,\cdots,N 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(wx+b)

训练步骤:

(1)选取初值 w 0 w_0 w0 b 0 b_0 b0

(2)在训练集中选取数据 ( x i , y i ) (x_i,y_i) (xi,yi)

(3)如果 y i ( w ⋅ x i + b ) ≤ 0 y_i(w\cdot x_i+b)\leq0 yi(wxi+b)0,则更新 w w w b b b

w ← w + η y i x i w\leftarrow w+\eta y_ix_i ww+ηyixi

b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi

(4)跳转到(2),直至训练集中没有误分类点。

  这种学习算法直观上有如下解释:当一个实例点被误分类,即位于分离超平面的错误一侧时,则调整 w w w b b b 的值,使分类超平面向该误分类点的一侧移动,以减少该误分类点与超平面的距离,直至超平面越过该误分类点使其被正确分类。

  Python 代码实现:

import numpy as np
import matplotlib.pyplot as plt


class Perceptron:
    def __init__(self):
        pass

    def processData(self, datas):
        xArr = np.array([x[0] for x in datas])
        yArr = np.array([x[1] for x in datas])
        return xArr, yArr

    def train(self, train_datas, learning_rate = 1):
        xArr, yArr = self.processData(train_datas)
        self.w = np.zeros(xArr.shape[1])
        self.b = 0
        self.learning_rate = learning_rate
        num = 0
        while(True) :
            num = 0
            for i in range(len(train_datas)):
                # num += 1
                loss = yArr[i] * (np.dot(self.w, xArr[i]) + self.b)
                print('loss = ', loss)
                if loss <= 0:
                    self.w += learning_rate*yArr[i]*xArr[i]
                    self.b += learning_rate*yArr[i]
                    break
                num += 1
            print('num = ', num)
            if num >= len(train_datas):
                break;

    def predict(self, x):
        return np.where(np.dot(self.w, x) + self.b >= 0.0, 1, -1)


if __name__ == "__main__":
    datas = [[(1,2),-1],[(2,1),-1],[(2,2),-1],[(1,4),1],[(3,3),1],[(5,4),1],[(3, 3), 1], [(4, 3), 1], [(1, 1), -1],[(2, 3), -1], [(4, 2.5), 1]]
    perceptron = Perceptron()
    perceptron.train(datas, 0.1)

    print("w = ", perceptron.w, ", b = ", perceptron.b)

    fig = plt.figure('Input Figure')
    xArr = np.array([x[0] for x in datas])
    yArr = np.array([x[1] for x in datas])
    pPlotx, pPloty, nPlotx, nPloty = [], [], [], []
    for i in range(len(datas)):
        if yArr[i] > 0:
            pPlotx.append(xArr[i][0])
            pPloty.append(xArr[i][1])
        else :
            nPlotx.append(xArr[i][0])
            nPloty.append(xArr[i][1])
    pPlot, nPlot = plt.plot(pPlotx, pPloty, 'b+', nPlotx, nPloty, 'rx')
    plt.legend(handles=[pPlot, nPlot], labels=['Positive Sample', 'Negtive Sample'], loc='upper center')

    x0_max, x0_min = max(xArr[:, 0])+1, min(xArr[:, 0])-1
    x1_max, x1_min = max(xArr[:, 1])+1, min(xArr[:, 1])-1
    x = np.arange(x0_min, x0_max, 0.1)
    plt.plot(x, (-perceptron.b-perceptron.w[0]*x)/perceptron.w[1], 'b')

    plt.show()

运行以上代码,将得出以下的拟合图:
机器学习系列 02:感知机_第1张图片
  当训练数据集线性可分时,感知机学习算法原始形式迭代是收敛的。对于不同的选择初值,以及迭代过程中误分类点的不同选择顺序,感知机算法会存在多个不同的解。当训练集线性不可分时,感知机学习算法不收敛,迭代结果会发生震荡。

3.2 感知机学习算法的对偶形式

  对偶形式的基本思想是: w w w b b b 表示为实例 x i x_i xi 和标记 y i y_i yi 的线性组合的形式,通过求解其系数而求得 w w w b b b。不失一般性,在原始形式的算法中可假设初始值 w 0 w_0 w0 b 0 b_0 b0均为0。对误分类点 ( x i , y i ) (x_i,y_i) (xi,yi) 通过

w ← w + η y i x i w\leftarrow w+\eta y_ix_i ww+ηyixi

b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi

逐步修改 w w w b b b,设修改 n n n 次,则 w w w b b b 关于 ( x i , y i ) (x_i,y_i) (xi,yi) 的增量分别是 α i y i x i \alpha_iy_ix_i αiyixi α i y i \alpha_iy_i αiyi,这里 α i = n i η \alpha_i=n_i\eta αi=niη。这样,从学习过程中不难看出,最后学习到的 w w w b b b 可以分别表示为

w = ∑ i = 1 N α i y i x i w=\sum_{i=1}^{N}\alpha_iy_ix_i w=i=1Nαiyixi

b = ∑ i = 1 N α i y i b=\sum_{i=1}^{N}\alpha_iy_i b=i=1Nαiyi

这里, α i ≥ 0 \alpha_i\geq0 αi0 i = 1 , 2 , ⋯   , N i=1,2,\cdots,N i=1,2,,N
  算法 1.2 (感知机学习算法的对偶形式)

输入:训练数据集 T = ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x N , y N ) T={(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)} T=(x1,y1),(x2,y2),,(xN,yN),其中 x i ∈ X = R n x_i\in \mathcal{X}=\mathbf{R}_n xiX=Rn y i ∈ Y = { − 1 , + 1 } y_i\in \mathcal{Y}=\{-1,+1\} yiY={1,+1} i = 1 , 2 , ⋯   , N i=1,2,\cdots,N i=1,2,,N;学习率 η ( 0 < η ≤ 1 ) \eta(0<\eta \leq 1) η(0<η1)

输出 α , b \alpha,b α,b;感知机模型 f ( x ) = s i g n ( ∑ j = 1 N α j y j x j ⋅ x + b ) f(x)=sign\Big(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x+b\Big) f(x)=sign(j=1Nαjyjxjx+b)。其中 α = ( α 1 , α 2 , ⋯   , α N ) T \alpha=(\alpha_1,\alpha_2,\cdots,\alpha_N)^T α=(α1,α2,,αN)T

训练步骤:

(1) α ← 0 \alpha\leftarrow0 α0 b ← 0 b\leftarrow0 b0

(2)在训练集中选取数据 ( x i , y i ) (x_i,y_i) (xi,yi)

(3)如果 y i ( ∑ j = 1 N α j y j x j ⋅ x + b ) ≤ 0 y_i\Big(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x+b\Big)\leq0 yi(j=1Nαjyjxjx+b)0,则更新 α i \alpha_i αi b b b

α i ← α i + η \alpha_i\leftarrow \alpha_i+\eta αiαi+η

b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi

(4)跳转到(2),直至训练集中没有误分类点。

  对偶形式中训练实例仅以点积的形式出现。为了方便,可以预先将训练集中实例间的点积计算出来并以矩阵的形式存储,这个矩阵就是所谓的 Gram 矩阵(Gram matrix)。

参考:
[1] 李航《统计学习方法》

你可能感兴趣的:(01_机器学习,机器学习系列)