【统计学习方法】学习笔记-第2章-感知机

【统计学习方法】学习笔记-第2章-感知机

【知乎:https://zhuanlan.zhihu.com/p/307094622

  • 感知机(perceptron)是一种二分类线性分类模型,对应于输入空间中将实例划分为正负两类的分离超平面,属于判别模型。感知机的学习就是基于误分类的损失函数,利用梯度下降法对损失函数进行极小化,得到线性划分的分离超平面。
  • 模型: f ( x ) = sign ( w ⋅ x + b ) f(x)=\text{sign}(w\cdot x+b) f(x)=sign(wx+b)
  • 策略:极小化损失函数 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)=xiMyi(wxi+b)
  • 算法:基于随机梯度下降法的对损失函数的最优化算法,有原始形式和对偶形式。

2.1 感知机模型

【定义2.1(感知机)】
在这里插入图片描述

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

2.2 感知机的学习策略

【定义2.2(数据集的线性可分性)】
在这里插入图片描述

  1. 感知机的损失函数,采用误分类点到超平面S的总距离,此时损失函数是参数 w w w b b b的连续可导函数
  • 输入空间 R n \mathrm{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
  • 误分类点 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)
  • 误分类点集合 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)
  • 则感知机 sign ( w ⋅ x + b ) \text{sign}(w\cdot x+b) sign(wx+b)学习的损失函数为

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)=xiMyi(wxi+b)

  1. 一个特定样本点的损失函数,在误分类时是参数w, b的线性函数,在正确分类时是0。因此,给定训练数据集 T T T,损失函数 L ( w , b ) L(w,b) L(w,b) w , b w,b w,b的连续可导函数

2.3 感知机学习算法

【算法2.1(感知机学习算法的原始形式)】
在这里插入图片描述

  • 学习的目标是求参数 w , b w,b w,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)=xiMyi(wxi+b)

  • 学习算法采用随机梯度下降法(stochastic gradient descent),从任意超平面 w 0 , b 0 w_0,b_0 w0,b0开始用梯度下降法不断极小化目标函数,每次随机选取一个误分类点进行
  • 给定 M M M,则损失函数 L ( w , b ) L(w,b) L(w,b)的梯度为
    • ▽ w L ( w , b ) = − ∑ w i ∈ M y i x i \triangledown_wL(w,b)=-\sum_{w_i \in M}y_ix_i wL(w,b)=wiMyixi
    • ▽ b L ( w , b ) = − ∑ x i ∈ M y i \triangledown_bL(w,b)=-\sum_{x_i\in M}y_i bL(w,b)=xiMyi
  • 则对任一误分类点 ( x i , y i ) (x_i,y_i) (xi,yi),按照学习率(learning rate) η ( 0 < η ≤ 1 ) \eta(0\lt\eta\le 1) η(0<η1) w , b w,b w,b进行更新:
    • w ← w + η y i x i w\leftarrow w+\eta y_i x_i ww+ηyixi
    • b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi
  1. 感知机学习算法由于采用不同的初值或选取不同的误分类点,解可以
    不同。
  2. 对于现行可分数据集感知机学习算法原始形式收敛,根据【定理2.1(Novikoff)】,误分类次数k是有上界的,经过有限次搜索可以找到将训练数据完全正确分开的分离超平面

在这里插入图片描述

  1. 当训练集线性不可分时,感知机学习算法不收敛,迭代结果会发生震荡

【算法2.2(感知机学习算法的对偶形式)】

在这里插入图片描述

  • 对偶形式的基本想法:将 w , b w,b w,b表示为实例 x i x_i xi和标记 y i y_i yi的线性组合的形式,通过求解其系数得到 w , b w,b w,b
  • 假设初始值 w 0 , b 0 w_0,b_0 w0,b0均为0,对误分类点 ( x i , y i ) (x_i,y_i) (xi,yi)按照 w ← w + η y i x i w\leftarrow w+\eta y_i x_i ww+ηyixi b ← b + η y i b\leftarrow b+\eta y_i bb+ηyi,逐步修改 w , b w,b w,b,修改n次,则 w , b w,b w,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η,对所有N个点,则最后得到
    • 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 , i = 1 , 2 , . . . , N \alpha_i \ge 0,i=1,2,...,N αi0,i=1,2,...,N
  • η = 1 \eta=1 η=1时,表示第i个实例点由于误分而进行更新的次数,更新次数越多,则该点离分离超平面越近,也越难正确分类,对结果影响更大
  • 【理解】 α i \alpha_i αi代指每个样本更新次数(所以每次更新 + η +\eta +η), y i x i y_ix_i yixi表示 w w w要更新的梯度
  • 【理解】 α i , i = 1 , 2 , . . , N \alpha_i,i=1,2,..,N αi,i=1,2,..,N确定了,则 w w w也确定了,所有更新 α i \alpha_i αi可以代替更新 w w w
  • 对偶形式的好处,训练实例仅以内积的形式出现,所以可以余弦将训练集中实例间的内积计算出来并以矩阵存储,即Gram矩阵(Gram Matrix): G = [ x i ⋅ x j ] N × N G=[x_i\cdot x_j]_{N\times N} G=[xixj]N×N

代码复现

模拟数据

  • 在-1~1之间生成随机点,并以 y = sign ( x 1 − 2 x 2 + 0.4 ) y=\text{sign}(x_1-2x_2+0.4) y=sign(x12x2+0.4)为分类超平面
import pandas as pd
import numpy as np
n=50
x1lst=[np.random.rand()*2-1 for x in range(n)]
x2lst=[np.random.rand()*2-1 for x in range(n)]
ylst=[1 if x1-2*x2+0.4>0 else -1 for x1,x2 in zip(x1lst,x2lst)]
df=pd.DataFrame({'x1':x1lst,'x2':x2lst,'y':ylst})

在这里插入图片描述

sklearn实现

import sklearn
from sklearn.linear_model import Perceptron
clf = Perceptron(max_iter=1000,shuffle=True)
clf.fit(df[['x1','x2']], df['y'])
print('w:',clf.coef_[0])
print('b:',clf.intercept_[0])

# w: [ 2.40777955 -5.1698278 ]
# b: 1.0

在这里插入图片描述

原始形式

import numpy as np 
class MyPerceptronBase(object):
    '''
    感知机的原始形式
    '''
    def __init__(self,eta=0.01,n_iter=100):
        self.eta=eta
        self.n_iter=n_iter
    def fit(self,X,y):
        self.w=np.zeros(X.shape[1])
        self.b=0
        
        self.errors=[]
        # 最多执行n_iter次
        for step in range(self.n_iter):
            # 每次遍历所有,是否存在错误样本
            error_num=0
            for xi,yi in zip(X,y):
                # 先判断是否符合计算条件
                is_update=self._update(xi,yi)
                _temp=self.eta*yi*is_update
                self.w+=_temp*xi
                self.b+=_temp
                error_num+=is_update
            # 不存在错误样本,就结束
            if error_num==0:
                break
        self.stop_step=step
                
    def sign(self,xi):
        return np.dot(xi, self.w) + self.b
    
    def _update(self,xi,yi):
        return np.where(yi*self.sign(xi)<=0,1,0)
    
    def predict(self, xi):
        return np.where(self.sign(xi) <= 0.0, -1, 1)

在这里插入图片描述

对偶形式

import numpy as np
class MyPerceptronDual(object):
    '''
    感知机的对偶形式
    '''
    def __init__(self,eta=0.01,n_iter=100):
        self.eta=eta
        self.n_iter=n_iter
    # Gram矩阵
    def gram_matrix(self,X):
        self.Gram=np.dot(X,X.T)
    # 条件判定
    def _update(self,X,y,i):
        # Gram矩阵中的一列,即xj
        g=self.Gram[:,i]
        # alpha_j*y_j*x_j*x_i
        _temp=self.alpha*y*g
        flag=y[i]*(np.sum(_temp)+self.b)
        return np.where(flag<=0,1,0)
    # 训练
    def fit(self,X,y):
        N,M=X.shape
        self.alpha=np.zeros(N)
        self.b=0
        
        self.gram_matrix(X)
        for step in range(self.n_iter):
            error_num=0
            for i in range(N):
                xi=X[i]
                yi=y[i]
                is_update=self._update(X,y,i)
                self.alpha[i]+=self.eta*is_update
                self.b+=self.eta*yi*is_update
                error_num+=is_update
            # 不存在错误样本,就结束
            if error_num==0:
                break
        self.stop_step=step

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值