感知器学习算法PLA

笔记参考及引用了部分机器学习基石内容及 https://zhuanlan.zhihu.com/p/25358695

近期在看林轩田的机器学习基石,第一个模型就是这个最基础的PLA算法 (Perceptron Learning Algorithm)。虽然视频中已经讲的比较详细了,但是对于公式推理的许多细节还是一脸懵。反反复复看了几遍,查了资料,才有比较清晰的理解。所以整理了一下,并对里面一些卡住我的细节作一些补充。

1.补充笔记(机器学习流程图)


这里写图片描述

这里f表示最理想的方案。x为特征值,y为结果值。
我们认为训练集D是由理想方案f生成的。g为我们求解的用来预测的假设,H包括的所有的预测函数,称为假设空间。通过学习算法,我们希望得到可以无限接近f的预测函数g。

2.感知器


首先,我们有用户数据如下(这段数据引用文首博主的文章数据)

年龄 x 1 x_{1} x1商品价格 x 2 x_{2} x2是否点击y(1为是,-1为否)
10300-1
15377-1
501371
65921
45528-1
615421
26394-1
37703-1
392441
413981
534951
321191

先看训练的目标:我们希望通过样本集,找到用户年龄与商品价格与用户是否点击商品的联系,从而为每个用户推送其最有可能点击的商品。

样本集包含两项特征:年龄,商品价格。我们将每一样本表示为x=( x 1 x_{1} x1, x 2 x_{2} x2), x 1 x_{1} x1 x 2 x_{2} x2分别代表年龄和商品价格。用y表示用户是否点击商品。y=1为点击,y=-1为未点击。(特征值可以有更多)

将特征与结果的联系公式化,每个特征值 x i x_{i} xi都会有对应的权重 w i w_{i} wi,表示该特征对结果影响的程度。通过计算所有特征值与权重的乘积和,也可以称作分数,当分数超过某个阈值,则用户会点击该商品,否则不会。这样就得到了以下的公式
y = { 1 i f ∑ i = 1 n w i x i > t h r e s h o l d − 1 i f ∑ i = 1 n w i x i < t h r e s h o l d y = \left\{\begin{matrix} 1 & if \sum_{i=1}^{n}w_{i}x_{i} > threshold\\ -1 & if \sum_{i=1}^{n}w_{i}x_{i} <threshold \end{matrix}\right. y={11ifi=1nwixi>thresholdifi=1nwixi<threshold

我们将加权后的特征分数与阈值相减,再取其符号(sign 是取符号函数, sign(x) = 1 if x>0, -1 otherwise),即可得到结果值y。这一过程使用线性函数h(x)表示为。

$h(x) = sign((\sum_{i=1}^{n}w_{i}x_{i})-threshold) $

因为实际上我们不知道各个特征的权值与阈值的最优取值,所以w和阈值的取值存在无穷的可能性,由此会产生无穷种h。所有情况的h(x)函数构成了假设空间。而我们需要在假设空间中找出最优解。
为了方便实现,将负阈值看作w的第0维收入公式中进行化简,这样我们找到了最优的h(x),就等于是找到了w (结尾乘积和简化成向量的内积, W T W^T WT为w列表的转置矩阵)
这里写图片描述

那这个函数的图像究竟是怎样的?

我们将样本数据的特征值表示为n维空间中的点,h(x)=0为分割正负两类的线或者平面。
以上面的用户数据集为例
h ( x ) = s i g n ( w 0 + w 1 x 1 + w 2 x 2 ) h(x) = sign(w_{0} +w_{1}x_{1} + w_{2}x_{2}) h(x)=sign(w0+w1x1+w2x2)

h ( x ) = s i g n ( w 1 x 1 + w 2 x 2 − t h r e s h o l d ) h(x) = sign(w_{1}x_{1} + w_{2}x_{2}-threshold) h(x)=sign(w1x1+w2x2threshold)

红点代表点击,蓝叉代表未点击,学习算法后得到的理想模型用图像表示如下图,。图像中的直线为h(x) = 0。直线往左为h(x) = -1,往右为h(x) = 1,h(x)刚好将数据分成两类。
这里写图片描述

3.感知器学习算法


PLA属于二值分类算法。一开始没有弄明白这一点,所以对h(x)函数的定位有些云里雾里。
PLA的目标:通过PLA求得的g应该要与理想的f十分接近,可以根据用户数据的特征值推测用户是否点击商品,且至少要保证这一推测在训练的样本集中是准确的。
基本的算法 一共有三步

  1. 随意选择一个初始向量 w 0 w_{0} w0,可以设置为0向量
  2. 找到 w t w_{t} wt向量中分错的点 ( x n ( t ) , y n ( t ) ) (x_{n(t)},y_{n(t)}) (xn(t),yn(t)) (t表示第t轮迭代 。即对于错误点 s i g n ( w t T x n ( t ) ) ≠ y n ( t ) sign(w_{t}^T x_{n(t)}) \neq y_{n(t)} sign(wtTxn(t))=yn(t)
  3. 修正偏差 w t + 1 ← w t + y n ( t ) x n ( t ) w_{t+1} \leftarrow w_{t} + y_{n(t)}x_{n(t)} wt+1wt+yn(t)xn(t)

不断重复第2,3步。直到再没有错误的点,算法结束。

>>为什么修正偏差是 w t + y n ( t ) x n ( t ) w_{t} + y_{n(t)}x_{n(t)} wt+yn(t)xn(t)

我们分两种情况可以更加清楚地讨论。

  • 用户点击了商品
    此时 y n ( t ) y_{n(t)} yn(t)应该为1, s i g n ( w t T x n ( t ) ) > 0 sign(w_{t}^T x_{n(t)}) > 0 sign(wtTxn(t))>0,这说明w与x之间的夹角大于90°。但是它被分在了-1一边,使 s i g n ( w t T x n ( t ) ) = − 1 < 0 sign(w_{t}^T x_{n(t)}) = -1 <0 sign(wtTxn(t))=1<0,于是夹角错误地小于90°。此时我们希望通过使其夹角变大来进行修正,通过向量的运算原理, w t + y n ( t ) x n ( t ) w_{t} + y_{n(t)}x_{n(t)} wt+yn(t)xn(t) = w t − x n ( t ) w_{t} - x_{n(t)} wtxn(t),夹角增大。
    这里写图片描述

  • 用户没有点击商品
    此时 y n ( t ) y_{n(t)} yn(t)应该为-1, s i g n ( w t T x n ( t ) ) < 0 sign(w_{t}^T x_{n(t)}) < 0 sign(wtTxn(t))<0,这说明w与x之间的夹角小于90°。但是它被分在了1一边,使 s i g n ( w t T x n ( t ) ) = 1 > 0 sign(w_{t}^T x_{n(t)}) = 1 >0 sign(wtTxn(t))=1>0,于是夹角错误地大于90°。此时我们希望通过使其夹角变小来进行修正,通过向量的运算原理, w t + y n ( t ) x n ( t ) w_{t} + y_{n(t)}x_{n(t)} wt+yn(t)xn(t) = w t + x n ( t ) w_{t} + x_{n(t)} wt+xn(t),夹角缩小。
    这里写图片描述

>>为什么h(x)是w取法向量?

这里写图片描述
机器学习基石中有给出简单的算法运行过程。其中算法确认了 w 0 w_{0} w0后,取其法向量作为分割线,再判断错误点。有人疑惑为什么会取法向量。
前面我们知道这条分割线实际上为h(x)=0。也就是说 s i g n ( W T x ) sign(W^Tx) sign(WTx)=0。两个向量相乘为0说明w和x互相垂直。故找到w后就可以知道分割线的位置,从而对错误进行修正。

>> y n W t + 1 T x n ≥ y n W t T x n y_{n}W^{T}_{t+1}x_{n} \geq y_{n}W^{T}_{t}x_{n} ynWt+1TxnynWtTxn ??

s i g n ( w t T x n ) ≠ y n sign(w_{t}^T x_{n}) \neq y_{n} sign(wtTxn)=yn w t + 1 ← w t + y n x n w_{t+1} \leftarrow w_{t} + y_{n}x_{n} wt+1wt+ynxn两条规则下,该等式一定成立。因为算法的修正一定会使修正后的结果更加接近目标值。如果 y n y_{n} yn是负的,而 W t T x n W^{T}_{t}x_{n} WtTxn是正的。如果成功修正为负,那么 y n W t + 1 T x n y_{n}W^{T}_{t+1}x_{n} ynWt+1Txn是正数肯定比原本的大。即使没有成功修正,修正也使他向负的靠齐, W t T x n W^{T}_{t}x_{n} WtTxn值变小,与 y n y_{n} yn也会比原来的乘积大。

4.PLA一定会结束吗


答案当然是不一定。训练数据可以分为两种,线性可分与线性不可分。假如数据是线性可分的,我们证明一下PLA是否一定能找到最优值。
假设我们找到了完美的 w f w_{f} wf,此时所有的点都在对应的一边,任意一个点的 y n ( t ) w f T x n ( t ) y_{n(t)}w^{T}_{f}x_{n(t)} yn(t)wfTxn(t)都大于0。可以得到如下的公式:
             y n ( t ) w f T x n ( t ) ≥ m i n n   y n w f T x n > 0 y_{n(t)}w^{T}_{f}x_{n(t)}\geq \underset{n}{min}\,y_{n}w^{T}_{f}x_{n} >0 yn(t)wfTxn(t)nminynwfTxn>0

两个向量的夹角越小,他们的内积就越大。我们计算 w f T w t + 1 w_{f}^{T}w_{t+1} wfTwt+1的内积
这里写图片描述
发现 w w w与理想值的内积越来越大,这很可能说明他们越来越接近。为什么说是很可能,因为还有可能是向量模变大了。下面证明他们确实是越来越接近的
数学无能,实在是不会推导,所以证明过程引用某同学的听课笔记
这里写图片描述

我们定义 R 2 = m a x n ∥ x n ∥ 2 R^{2}=\underset{n}{max}\left \| x_{n} \right \|^{2} R2=nmaxxn2, ρ = m i n n   y n w f T ∥ w f ∥ x n \rho =\underset{n}{min}\,y_{n}\frac{w_{f}^{T}}{\left \|w_{f} \right \|}x_{n} ρ=nminynwfwfTxn
最多需要 R 2 ρ 2 \frac{R^{2}}{\rho^{2}} ρ2R2轮,算法就可以停止。

5.PLA python实现


刚刚接触python,借助文首提到的博主github上的代码学习了一下。有些不懂的地方一看代码都明白了。她的代码用python2实现,所以稍微的修改了一下使其可以在python3运行,原po代码链接在此
关键代码如下

def PLA(trainingData):
    #矩阵 转置
    w = np.mat([1,2127,205]).transpose() # Step 1: 向量w赋初值

    k = 0 # 第k轮计数
    while True:
        k += 1

        (status, x, y) = noMistakePoint(trainingData, w)
        draw(trainingData, w, k, x) # 画图
        if status == 'YES': # Step 2: 切分正确,学习完成
            return w
        else:
            w = w + y*x # Step 3: 修正w

sign = lambda x:1 if x > 0 else -1 if x < 0 else -1

def mSign(m):
    '''判断某个矩阵的[0][0]元素正负.大于0返回1,否则返回-1'''
    x = m.tolist()[0][0]
    return 1 if x > 0 else -1 if x < 0 else -1


def noMistakePoint(training_data, w):
    '''训练数据中是否有点被切分错误'''
    status = 'YES'
    for (x, y) in training_data:
        if mSign(w.transpose() * x) != sign(y):
            status = 'NO'
            return (status, x, y)

    return status, None, None

6.pocket 算法


如果我们知道训练的数据是线性可分的,那么我们可以用PLA算法进行训练。但是一般来说,我们并不知道我们拥有的数据集是否线性可分,也不知道需要多长时间才能成功训练。所以有了对PLA算法改进的pocket算法。
pocket算法中,分割线不需要将两类的数据完全分割开。它认为数据中可能存在一些错误的数据,称为噪声。分割数据时可以忽略噪声的存在。
算法值在PLA基础上增加了最优w的变量

  1. 随意选择一个初始向量 w 0 w_{0} w0,可以设置为0向量,初始化最优的权值 w ^ \hat{w} w^
  2. 随机找一 w t w_{t} wt向量中分错的点 ( x n ( t ) , y n ( t ) ) (x_{n(t)},y_{n(t)}) (xn(t),yn(t)) (t表示第t轮迭代 。即对于错误点 s i g n ( w t T x n ( t ) ) ≠ y n ( t ) sign(w_{t}^T x_{n(t)}) \neq y_{n(t)} sign(wtTxn(t))=yn(t)
  3. 修正偏差 w t + 1 ← w t + y n ( t ) x n ( t ) w_{t+1} \leftarrow w_{t} + y_{n(t)}x_{n(t)} wt+1wt+yn(t)xn(t)
  4. 如果 w t + 1 w_{t+1} wt+1错误比 w ^ \hat{w} w^少,则 w t + 1 w_{t+1} wt+1成为新的 w ^ \hat{w} w^

循环2-4步,最终 w ^ \hat{w} w^代表的h(x)就是g。
使用pocket算法可以解决部分非线性可分的数据集,但会消耗更多的计算时间

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值