1. 程式人生 > >寫給大家看的機器學習書【Part3】直觀易懂的感知機學習演算法PLA

寫給大家看的機器學習書【Part3】直觀易懂的感知機學習演算法PLA

本篇綜述

圖片描述

前兩篇我們已經學習了機器學習的概念和組成:

學習演算法 (Learning Algorithm) 根據訓練資料,從假設集合 (Hypothesis Set) 中選出最優的那個對映g : χ → Y 作為最終學得的模型,使得 g 越接近 f 越好( gf )。

這一篇,我們要具體地講一個學習演算法,把它用在有好貨這個場景,看看這個演算法到底是怎麼樣從使用者日誌中尋找規律,學得模型的。一旦學得模型以後就可以對未來做出預測 —— 預測使用者是否會點選某個商品,預測人生的巔峰、世界的和平、一起學習機器學習的女朋友…

這個學習演算法的名字叫 PLA,全稱 Perceptron Learning Algorithm。其中 Perceptron 譯作感知機

,它是人工神經網路中最基礎的兩層神經網路模型。學好Perceptron Learning Algorithm,你離入門人工神經網路也就不遠啦。

具體來說,這一篇我們將首先介紹PLA的假設集合,看看PLA的假設集合中等著被挑選的候選函式長什麼樣。看過PLA假設集合的函式表示之後,重要的是理解PLA假設集合的直觀解釋,事實上之所以把PLA作為第一個學習演算法,就是因為它有著非常直觀的理解方式。

接著將看到PLA的細節,PLA 是一個相當簡潔的演算法,演算法過程僅有4步,我寫的Python 編碼含註釋不到30行。學習PLA的重點應該放在理解PLA演算法的第三步,理解PLA之所以被設計成這樣,背後的含義其實樸素又直觀。

然後,我們將討論學習演算法兩個很重要的問題——學習演算法能最終停止並學到東西嗎?如果能,學習演算法需要執行多久呢?這時我們將驚訝於經典PLA的兩點性質:(1)演算法可能永遠也無法執行結束,會迷失在茫茫的訓練資料中永遠找不到出口。(2)哪怕知道PLA最終能找到出口,我們也無法事先知道學習需要花多久。不過別急於換臺,我們緊接著就會給出一版升級的PLA演算法,只需在經典PLA的基礎上增加簡單兩步,就可以解決上面的問題。

好,我們開始吧。

1. PLA 的假設集合 (Hypothesis Set)

首先,我們從有好貨的使用者日誌中得到訓練資料如下(考慮資料安全,資料當然是我Mock的):

圖片描述

如第二篇第2小節所述,每一條樣本表示為x = (x1

, x2),其中x1表示年齡,x2表示商品價格。樣本標註用y表示,y=1表示使用者點選,y=-1表示使用者沒點選。(這裡我們只選了年齡和商品價格兩個維度的特徵,當然是為了方便講解和作圖做得簡化,實際應用中會使用到多得多的特徵)

PLA 的基本想法是每個特徵都有個權重wi ,表示該特徵的重要程度。綜合所有的特徵和權重計算一個最終的分數,如果分數超過某個閾值 (threshold ),就表示使用者會點選,否則則不會點選。

我們將特徵的權重記作w=(w1,w2),w1代表了年齡這維特徵的重要性,w2代表了商品價格這維特徵的重要性。於是判斷一個使用者會不會點選,就變成了下面這個函式:

圖片描述

如果

圖片描述

大於threshold ,那麼我們判斷使用者會點選。

如果

圖片描述

小於threshold,我們判斷使用者不會點選。

該函式經過簡單變換,可以表示得更簡潔。如下所示,其中sign(x) 是求表示式的符號,當x大於0時,sign(x) 就等於1。當x小於0時,sign(x) 就等於-1:

圖片描述

注意,在演算法完成學習之前,函式中的withreshold 是未知的,不同的withreshold 值對應了不同的函式,事實上所有可能的withreshold 所代表的函式集合,構成了PLA的假設集合(Hypothesis Set),叫做 Perceptron Hypothesis 。而 PLA 演算法要做的,就是根據訓練資料找到最優的w和threshold

2. Perceptron Hypothesis 的直觀解釋

OK,上小節我們知道了 PLA 的假設集合 (Hypothesis Set) 就是所有可能的h(x),不過函式表示理解起來還是有點抽象,那麼 Perceptron Hypothesis 有沒有直觀的理解方式呢?有!

在有好貨的例子裡,x=(x1,x2)只有兩維特徵,於是我們先將函式簡化:

圖片描述

接著把所有訓練樣本x=(x1,x2)畫到二維平面上,紅圈表示點選,藍叉表示沒點選,如下圖所示:

圖片描述

由於方程w1·x1 + w2·x2 - threshold = 0就表示平面上的一條直線,且我們知道直線右邊所有的點都有w1·x1 + w2·x2 - threshold > 0,左邊所有的點都有w1·x1 + w2·x2 - threshold < 0 , 於是可以推出:

PLA假設集合中任意一個確定的h(x) ,都可視作一條直線將平面分隔成了兩個區域。線的左邊有h(x) = -1,右邊有h(x) = 1。

所以,學習演算法希望選中的模型g ,就是如上圖所示這樣的一條線,它正好將訓練資料分成兩個區域,右邊都是紅圈,左邊都是藍叉。也正因為這樣,Perceptron 是一種線性分類器(Linear Classifiers)。

3. PLA 怎麼選一條最好的線

直觀理解了 PLA 的 Hypothesis Set 之後,現在我們來看看 PLA 具體是如何確定最優的w和threshold ,得到最優的那條線的。

我們首先需要對公式做一些簡化變形:

圖片描述

圖片描述

這個變形的目的是把引數threshold 統一收進w,於是 PLA 找到最優的那條線就等價於找到最優的引數w。於是 PLA 演算法就可以寫得相當簡潔,僅有如下4步:

  • Step 1: 隨便找一條線,即任意找一個 n 維向量w0,賦初值令w = w0
  • Step 2: 如果這條線正好把訓練資料正確切分,Lucky!!訓練結束!!此時w代表的h(x) 就是我們學得的模型g
  • Step 3: 如果有任意一個樣本沒有被切分正確,即存在任意(x’, y’),使得sign( wT x’) ≠ y’,此時我們對w代表的線做一點點修正,令wt+1 = wt + y’x’
  • Step 4: 跳轉到Step 2

就是這麼簡單,PLA的基本思路就是:先隨便找一條線,如果沒能正確切分,就修正一點點,直到所有的紅圈都在右邊,藍叉都在左邊。

import numpy as np
import matplotlib.pyplot as plt


def PLA(trainingData):
    w = np.mat([1,2127,205]).transpose() # Step 1: 向量w賦初值
    while True: 
        (status, x, y) = noMistakePoint(trainingData, w)
        if status == 'YES': # Step 2: 切分正確,學習完成
            return w
        else:
            w = w + y*x # Step 3: 修正w


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


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

每對訓練資料進行一次迴圈遍歷我們稱為“一輪學習”,當w的初值設為w0=( 1,2127,205 )時,PLA僅需 7 輪就成功找到了能夠正確切分訓練資料的線(如下圖所示),最終PLA得到的w=( -1, 2169, -216 ),即學得的模型為g(x) = sign ( 2169 · x1 - 216 · x2 -1)。

圖片描述

PLA 演算法很簡單,學習的關鍵在於理解演算法的第3步,怎麼理解當發現一個樣本(x’, y’)沒被切分正確時,對 w 的修正是wt+1 = wt + y’x’呢?這個修正的含義是什麼呢?

分兩種情況來分析:

情況1:被錯分的點是紅圈。也就是說y’是+1,sign(wT x’)卻等於-1,使得sign(wT x’) ≠ y’。學過向量乘的同學都知道,兩個向量wT和x’相乘小於0,說明它們的夾角大於90°。如果希望它們相乘大於0,需要把夾角變小,而另w = w + y’x’(即w = w + x’)之後正是另兩個向量的夾角變小了——如下圖情況1所示。

情況2同理:被錯分的點是藍叉。也就是說y’是-1,sign( wT x’)卻等於+1,使得sign( wT x’) ≠ y’。說明 wT和x’的夾角小於90°,如果希望它們相乘小於0,需要把夾角變大,而另w = w+y’x’(即 w = w - x’)之後正是另兩個向量的夾角變大了——如下圖情況2所示。

這就是每次修正直線背後的含義。

圖片描述

4. PLA 一定會停嗎?PLA 多久會停?

當 PLA 停止計算時,就說明它找到了一條線能將所有的訓練資料切分正確。那麼問題來了,PLA 一定會停嗎?它一定能找到這樣的一條直線嗎?

答案是:不一定!

事實上,如果訓練資料本身就不存在任何一條線能將其正確切分,比如如下圖所示,那麼 PLA 無論如何也無法找到理想的直線。學習將進入永不停止的迴圈。

訓練資料至少存在一條直線能將其切分開,稱為訓練資料是線性可分的 (Linear Seperable) 。因此:

訓練資料是線性可分的 (Liner Seperable) ,是 PLA 能夠學習的必要條件。

圖片描述

好,如果假設訓練資料是線性可分的,PLA 的計算需要多久才能停呢?這裡省略具體推導過程(有興趣可觀看機器學習基石課程的推導),推導可得 PLA 最多需要R2 / ρ2輪就會停,其中

圖片描述

注意ρ的公式中用到了“上帝真相”f,而f是未知的,這就意味著哪怕我們知道PLA線上性可分的訓練資料上會停止,但具體多久會停止這個值無法計算出來 :(

5. PLA 搞雞毛啊!

這個時候有的朋友要罵娘啦,整了半天 PLA 的訓練資料必須線性可分,哪怕線性可分需要計算多久也不知道。PLA 搞雞毛啊!

不要急!!大招馬上出來。

我們再看看下面這張圖,這裡的訓練資料不是線性可分,是由其中兩個點導致的。在現實中,哪怕原本的訓練資料產生於某個“上帝真相”並且是線性可分的,在收集資料處理資料的過程中不可避免的會引入一些髒資料,這部分錯誤的訓練資料我們稱為噪聲(Noise)。針對這種噪聲資料引起的,原本線性可分的訓練資料變成了不是線性可分的情況,有一個升級版的 PLA 演算法,只需要增加簡單的兩步節能解決問題:

  • Step 1: 隨便找一條線,即任意找一個 n 維向量w0,賦初值另w0。同時用一個變數wbest表示在訓練資料上表現最好的線,初始有wbest= w0
  • Step 2: 如果這條線正好把訓練資料正確切分,Lucky!! 訓練結束!!此時w代表的h(x) 就是我們學得的模型g
  • Step 3: 如果有任意一個樣本沒有被切分正確,即存在任意(x’, y’),使得sign(wT x’) ≠ y’,此時我們對w代表的線做一點點修正,令wt+1 = wt + y’x’ 。
  • Step 4: 如果修正後的wt+1比wbest表現的更好,那麼修改wbest = wt+1
  • Step 5: 如果訓練輪數小於Ntrain,跳轉到Step 2。否則訓練結束,此時wbest代表的h(x)就是我們學得的模型g

圖片描述

升級版的 PLA 演算法來自於實際經驗,當噪聲較小時,經過一定次數的訓練之後並把表現最好的線記下來,也能得到一個不錯解。上面說wt+1和wbest表現的好壞,是指這條線在訓練資料上犯了多少錯,即

圖片描述

至此,升級版的 PLA 演算法無需要求訓練資料線性可分,訓練最多也會在Ntrain輪內結束。:)

試試動手寫寫看升級版的 PLA 演算法吧。

當然,如果你的訓練資料不是線性可分是下圖這種情況,作為線性分類器的 PLA 是無能為力的,這需要後面要講的非線性模型來搞定。期待一下吧。

圖片描述

預告和其它

下一篇我們將圍繞一個有關賺錢的機器學習問題展開討論。

你是否也有過那麼一時三刻的不自信:當你有一天成了機器學習專家,學會了從股市的歷史資料中學得模型,這個時候你敢跟著模型對股市的預測,進行真金白銀的投資嗎?

所謂“有史為鑑,可以知興亡”,從歷史中總結出的規律,真的能在未來的預測中被信賴嗎?為了做一個對未來負責的機器學習專家,我們下一篇將展開對這個問題的討論。

感謝您的閱讀,如果你希望收到後續文章的更新,可以考慮關注我。或者關注這個同名專欄,文章將會在您的通知中心推送更新。

再次感謝您的閱讀,這裡是《寫給大家看的機器學習書》,希望我有把事情說清楚,有任何疑惑或者問題,歡迎留言。

祝開心 :)

圖片描述

圖片描述