機器學習——感知機


1 介紹

  感知機是1957年,由Rosenblatt提出會,是神經網絡和支持向量機的基礎。
  感知機 (Perceptron)是二分類的線性分類模型,其輸入為實例的特征向量,輸出為實例的類別,取+1和-1。感知機對應於輸入空間(特征空間)中將實例划為正負兩類的分離超平面,屬於判別模型。感知機預測是用學習得到的感知機模型對新的輸入實例進行分類,是神經網絡與支持向量機的基礎。

  

2 感知機模型

2.1 點到直線的距離

  設直線方程為 $Ax+By+C=0$ ,其上一點為 $(x_{0},y_{0})$
  距離為 ${\large d=\frac{A*x_{0}+B*y_{0}+C}{\sqrt{A^{2}+B^{2}}}} $ 

2.2 樣本到超平面距離

   假設超平面是 $h=w\cdot x+b$ ,其中 $w=(w_{0}, w_{1}, w_{2}......w_{n})$, $x=(x_{0}, x_{1}, x_{2}......x_{n})$,樣本點 $x' $ 到超平面的距離:${\large d=\frac{w*x^{'}+b}{||d||}} $ ,輸入空間 $\mathbb{R}^n$ 。
  在$2$維空間中的超平面是一條線,在$3$維空間中的超平面是一個平面。

2.3 函數模型

  由輸入空間到輸出空間的如下函數被稱為感知機:
    $f(x)=\operatorname{sign}(w \cdot x+b)$
  其中 $w$ 和 $b$ 屬於感知機模型參數,$w \in R^{n}$ 叫作權值或權值向量(weight vector), $b \in R$ 叫作偏置 (bias) 。
  $w \cdot x $ 為 $w$ 和 $x$ 的內積。 $ \operatorname{sign}$ 是符號函數,即
    $\operatorname{sign}(x)=\left\{\begin{array}{l} +1, x \geq 0 \\ -1, x<0 \end{array}\right.$
  感知機模型的假設空間定義在特征空間中的所有線性分類模型或線性分類器(linear classifier ) , 即函數集合
    $\{f \mid f(x)=w \cdot x+b\}$

2.4 幾何解權

  感知機有如下幾何解釋:線性方程
    $w \cdot x+b=0$
  對應於特征空間中的超平面 $S$ ,其中 $\mathbf{w} $ 是超平面的法向量, $ \mathbf{b} $ 為截距,超平面 $S$ 將特征向量分為正、 負兩類, $S$ 也被稱為分離超平面 。【PS:在二維空間是一條線,上開至多維度則為平面。】

  

  思考1:在這里為什么 $w$ 是超平面法向量?
  證明:超平面為 $w \cdot x+b=0$ ,設超平面上兩點 $x_1$,$x_2$ 兩點,則有

    $\left\{\begin{matrix} \mathbf{w \cdot  x_1} =0 \quad...(1)\\ \mathbf{w \cdot x_2} =0\quad...(2) \end{matrix}\right.$

  由  $(1)-(2)$ 得:

    $\left\{\begin{matrix} \mathbf{w\cdot( x_1-x_2)} =0 \\ \mathbf{x_1} -\mathbf{x_2} =\mathbf{x_2x_1 } \end{matrix}\right.$

  則
    $\mathbf{w}$ 與 $ \mathbf{x_2x_1}$ 垂直。

  訓練感知機模型就是通過訓練集數據學習參數 $w$ 和 $b$ ,然后訓練好的感知機模型就能對新的輸入實例進行類別的預測。

3 感知機學習策略

3.1 數據集的線性可分性

  給定數據集 $T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\}$,其中$ x_{i} \in \mathcal{X}=\mathbf{R}^{n}$,  $y_{i} \in \mathcal{Y}=\{+1,-1\}$,$i=1,2, \cdots, N $,如果存在某個超平面 $S$ 滿足:

    $w \cdot x+b=0$

  能將數據集的正實例點和負實例點完全正確地划分到超平面的兩側,即對所有 $y_{i}=+1$ 的實例 $x_i$,有 $ w \cdot x_{i}+b>0$ ;對所有 $y_{i}=-1$ 的實例 $x_i$,有 $w \cdot x_{i}+b<0 $,則 稱數據集 $T$ 為線性可分數據集 ;否則,稱數據集 $T$ 線性 不可分。
  在學習感知機模型中,需要確保數據集線性可分,才能夠找到一個完全將正實例點和負實例點正確分開的分離超平面,即才能夠確定感知機模型參數 $w,b$。

3.2 感知機學習策略

  在我們知道感知機模型之后,機器學習方法三要素中的模型已經確定好,下面就需要制定我們的學習策略,即定義經驗損失函數並將其最小化。所以下一步需要找到感知機模型的損失函數。

3.2.1 基於誤分類點數量的策略

  首先損失函數容易想到采用誤分類點的數量作為損失函數,因為誤分類點數量在不斷優化下會越來越少,我們只需要通過算法將其數目優化到 $ 0$ 自然就得到了最優模型。
  但是這樣的損失函數並不是 $w, b$ 連續可導(根本無法用函數形式來表達出誤分類點的個數),所以無法進行優化。
  因此采取誤分類點到平面的總距離作為損失函數,直觀上來看,總距離越小越好。

3.2.2 基於誤分類點總距離的策略

  首先,輸入空間中任意一點到超平面的距離公式為: (類比於點到直線的距離)

    $\frac{1}{\|w\|}\left|w \cdot x_{0}+b\right|$

  這里, $\|w\| $ 為 $w$ 的 L2范數。
  而我們知道每一個誤分類點都滿足:

    $-y_{i}\left(w \cdot x_{i}+b\right)>0$

  因為當數據點正確值為 $+1$ 的時候,誤分類了,那么判斷為 $-1$,則有 $ \left(w \cdot x_{i}+b\right)<0 $, 所以滿足 $-y_{i}\left(w \cdot x_{i}+b\right)>0 $,當數據點是正確值為 $-1$ 的時候,誤分類了,那么判斷為 $+1$,則有 $ \left(w \cdot x_{i}+b\right)>0$,所以滿足 $ -y_{i}\left(w \cdot x_{i}+b\right)>0 $。

  表2.1 關系表

  
  因此,一個誤分類點到超平面 $S$ 的距離為:

    ${\large -\frac{1}{|| w \mid} y_{i}\left(w \cdot x_{0}+b\right)} $

  然后,因為求的是總距離,所以假設誤分類點集合為 $M$,那么總距離為:

    ${\large -\frac{1}{\|w\|} \sum \limits _{x_{i} \in M} y_{i}\left(w \cdot x_{0}+b\right)} $

  最后,不考慮 $\frac{1}{\|w\|}$ , 求得最終的感知機損失函數即經驗風險函數:

    $L(w, b)=-\sum \limits _{x_{i} \in M} y_{i}\left(w \cdot x_{0}+b\right)$

  總結一下,我們現在的工作已經將感知機模型確定,並且需要一個學習策略來不斷的學習參數 $w$ 和 $b$,但是誤分類點數量不可求導,因此我們選擇了一個連續可導的損失函數即誤分類點到超平面 的總距離作為我們的損失函數。

  思考2:為什么了不用考慮 ${\large \frac{1}{\left \| w\right \|}} $?
  1、${\large \frac{1}{\left \| w\right \|}} $ 不影響 $y_i(w\cdot {x_i}+b)$ 的正負判斷,由於感知機算法是誤分類驅動,這里的"誤分類驅動"指的是只需要判斷 $y_i(w\cdot {x_i}+b)$ 的正負,而 ${\large \frac{1}{\left \| w\right \|}} $ 對正負不影響。
  2、${\large \frac{1}{\left \| w\right \|}} $  不影響感知機算法的最終結果。感知機算法的終止條件是所有的輸入輸出都被正確分類,即不存在誤分類點,最終損失為 $0$ 。對於 損失函數 $-\frac{1}{\left \| w \right \|} \sum \limits_{x_i\in M} y_i (w\cdot x_i+b)$,可以看出分子為 $0$,${\large \frac{1}{\left \| w\right \|}} $ 對分子並無影響。
  總結:不考慮  ${\large \frac{1}{\left \| w\right \|}} $  可以減少計算量,對感知機算法無任何影響。

4 感知機學習算法

   感知機學習算法是對上述損失函數進行極小化,求得 $w$ 和 $ b$。用普通的基於所有樣本的梯度和的均值的批量梯度下降法(BGD)是行不通的,原因在於我們的損失函數里面有限定,只有誤分類的 $M$ 集合里面的樣本才能參與損失函數的優化。所以我們不能用最普通的批量梯度下降,只能采用隨機梯度下降(SGD)。目標函數如下:

  $\underset{w,b}{min}  \ \   L(w, b)=-\sum \limits _{x_{i} \in M} y_{i}\left(w \cdot x_{i}+b\right)$

4.1 原始形式算法

  求參數 $ \mathrm{w}, \mathrm{b} $,求以下損失函數極小化問題的解:

    $ {\large \underset{w,b}{min}  \ \    L(w, b)=-\sum \limits _{x_{i} \in M} y_{i}\left(w \cdot x_{i}+b\right)} $

  因為我們需要不斷學習 $\mathrm{w} , \mathrm{b}$ ,因此我們采取隨機梯度下降法不斷優化目標函數,在這里,隨機梯度下降過程中,每一次僅用一個誤分類點樣本來使其梯度下降。
  首先,我們求解梯度,分別對 $\mathrm{w}  , \mathrm{b}$ 求偏導:

    $\begin{array}{l} \nabla_{w} L(w, b)=\frac{\partial}{\partial w} L(w, b)=-\sum \limits _{x_{i} \in M} y_{i} x_{i} \\ \nabla_{b} L(w, b)=\frac{\partial}{\partial b} L(w, b)=-\sum \limits_{x_{i} \in M} y_{i} \end{array}$

  然后,隨機選取一個誤分類點對 $w , b$ 進行更新: (同步更新)
    $w \leftarrow w+\eta y_{i} x_{i}$
    $b \leftarrow b+\eta y_{i}$
  其中,$ \eta $ 為學習率,通過這樣迭代使損失函數 $\mathrm{L}(\mathrm{w}, \mathrm{b}) $ 不斷減小,直至最小化。
  算法步驟
  輸入:訓練數據集 $T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}$,$y_i\in{\{-1,+1\}}$,學習率 $\eta(0<\eta<1)$
  輸出:$w$ 和 $b$; 感知機模型 $f(x)=sign(w\cdot {x}+b)$
  步驟:
  (1)、賦初值 $w_0$,$b_0$ ;
  (2)、選取數據點 $(x_i,y_i)$ ;
  (3)、判斷該數據點是否為當前模型的誤分類點,即判斷若 $y_i(w\cdot {x_i}+b)<=0$ 則更新
    $w={w+\eta{y_ix_i}}$
    $b={b+\eta{y_i}}$
  (4)、轉到(2),直到訓練集中沒有誤分類點。

  其中,$w$ 和 $b$ 的初值一般選擇為 $0$,方便計算。根據算法,我們很容易能夠編寫出 Python程序,重點關注循環迭代。
  代碼實戰:

import numpy as np class Model:#定義感知機學習類
    def __init__(self): #構造時初始值化w = (0 ,0), b = 0
        self.w = np.zeros(len(data[0]) - 1,dtype=np.float32) #初始化參數 w , b,和學習率
        self.b = 0 #學習率=1
        self.l_rate = 100# self.data = data
    def sign(self,x, w,b): #定義感知機模型函數
        y = np.dot(x,w) + b return y #隨機梯度下降法
    def fit(self, X_train, y_train): is_wrong = False #判斷是否有誤分類點
        while not is_wrong: wrong_count = 0 #記錄誤分類點數目
            for d in range( len( X_train) ): x= X_train[d] y = y_train[d] #選取—個點進行判斷
                if y * self.sign(x, self.w,self.b)<=0: #判斷是不是誤分類點的標志
                    self.w = self.w + self.l_rate * np.dot(y,x)#更新參數
                    self.b = self.b + self.l_rate * y wrong_count += 1 #誤分類點數目加一
            if wrong_count == 0: is_wrong = True  #沒有誤分類點
        return ' Perceptron Model! '

4.2 算法收斂性

4.2.1 Novikoff定理

  為了便於敘述與推導,將偏置 $b$ 並入權重向量 $w$ ,記作 $\hat{w}=(w^{\mathrm{T}}, b)^{\mathrm{T}}$ 同樣也將輸入向量加以擴充,加進常數 $1$,記作 $\hat{x}=(x^{\mathrm{T}}, 1)^{\mathrm{T}} $ 這樣, $\hat{x} \in \mathbf{R}^{n+1}, \hat{w} \in \mathbf{R}^{n+1} $。顯然,$ \hat{w} \cdot \hat{x}=w \cdot x+b_{c} $
  定理 2.1 (Novikoff)  設訓練數據集 $T=\{(x_{1}, y_{1}),(x_{2}, y_{2}),\cdots,(x_{N}, y_{N})\} $ 是線性可分的,其中 $ x_{i} \in \mathcal{X}=\mathbf{R}^{n}, y_{i} \in \mathcal{Y}=\{-1,+1\}, i=1,2, \cdots, N$ ,則
  (1)存在滿足條件 $ \|\hat{w}_{\mathrm{opt}}\|=1$ 的超平面 $\hat{w}_{\mathrm{opt}} \cdot \hat{x}=w_{\mathrm{opt}} \cdot x+b_{\mathrm{opt}}=0$ 將訓練數據集完全正確分開;且存在 $\gamma>0$ , 對所有 $ i=1,2, \cdots, N $

    $y_{i}(\hat{w}_{\mathrm{opt}} \cdot \hat{x}_{i})=y_{i}(w_{\mathrm{opt}} \cdot x_{i}+b_{\mathrm{opt}}) \geqslant \gamma$

  (2)令 $R=\max _{1 \leqslant i \leqslant N}\|\hat{x}_{i}\|$ , 則感知機算法 2.1 在訓練數據集上的誤分類次數 $k$ 滿足 不等式

    $k \leqslant(\frac{R}{\gamma})^{2}$

  根據這兩個定理可知,只要對於線性可分的數據集,感知機學習算法原始形式就能夠在有限次的 迭代更新中能夠得到一個能正確划分的分離超平面和感知機模型。

4.2.2 定理證明

  定理(1):
  這個定理的證明較為簡單,首先數據集線性可分,按照之前線性可分性定義,那我們就必然能夠找到一個超平面將數據正確分開。
  令超平面為:

    $\hat{w}_{\mathrm{opt}} \cdot \hat{x}=w_{\mathrm{opt}} \cdot x+b_{\mathrm{opt}}=0, \text { 使 }\|\hat{w}_{\mathrm{opt}}\|=1$

  思考3: 為什么 $ \|\widehat{w}_{o p t}\|=1$ ?
  法向量可以任意伸縮,所以總可以找到 $w_{opt}$ 的模長$=1$,並且方便計算。
  權重向量 $w$ 會和 $x$ 向量相乘組成一個超平面$w^Tx=0$。這里權重向量 $w$ 即為超平面的系數向量。而將系數向量除以其范數 (即轉換為單位向量) 不會改變這個超平面,就像是 $2 x+2 y+1=0$ 與 $ 2 / 3 x+2 / 3 y+1 / 3=0 $ 表示同一個直線。
  接下來又因為下列式子是在原本的分類點上永遠是一個非負數,因為 $y$ 是正分類的時候,那么括號中的 表達式也是非負的(線性可分性定義)

    $y_{i}(\hat{w}_{\mathrm{opt}} \cdot \hat{x}_{i})=y_{i}(w_{\mathrm{opt}} \cdot x_{i}+b_{\mathrm{opt}})>0$

  所以我們就能夠在上述非負數集合中找到一個最小的非負數,如下:
  所以存在

    $\gamma=\min _{i}\{y_{i}(w_{\mathrm{opt}} \cdot x_{i}+b_{\mathrm{opt}})\}$

  使

    $y_{i}(\hat{w}_{\mathrm{opt}} \cdot \hat{x}_{i})=y_{i}(w_{\mathrm{opt}} \cdot x_{i}+b_{\mathrm{opt}}) \geqslant \gamma$

  定理 (2) :

  (2) 感知機算法從 $\hat{w}_{0}=0$ 開始,如果實例被誤分類,則更新權重。令 $\hat{w}_{k-1} $ 是第 $k$ 個誤分類實例之前的擴充權重向量, 即
    $\hat{w}_{k-1}=\left(w_{k-1}^{\mathrm{T}}, b_{k-1}\right)^{\mathrm{T}}$
  首先總觀全部推導過程我們需要證明兩個不等式,才能得出最后的關於有限次的 $k$ 不等式:
  不等式(1)

    $\hat{w}_{k} \cdot \hat{w}_{\mathrm{opt}} \geqslant k \eta \gamma$

  不等式(2)

    $\left\|\hat{w}_{k}\right\|^{2} \leqslant k \eta^{2} R^{2}$

  現在我們對於不等式(1)先把左邊拆開成:

    $\hat{w}_{k}=\hat{w}_{k-1}+\eta y_{i} \hat{x}_{i}$

  然后將其代入不等式(1)得:

    $\left(\tilde{w}_{k-1}+\eta y_{i} x_{i}\right) \cdot \tilde{w}_{o p t}$

  進行運算,並根據定理 (1), 將 $y_{i} w_{\mathrm{opt}} \cdot x_{i}$ 替換,我們可以代換得到:

    $\begin{aligned} \hat{w}_{k} \cdot \hat{w}_{\mathrm{opt}} &=\hat{w}_{k-1} \cdot \hat{w}_{\mathrm{opt}}+\eta y_{i} w_{\mathrm{opt}} \cdot x_{i} \\ & \geqslant \hat{w}_{k-1} \cdot \hat{w}_{\mathrm{opt}}+\eta \gamma \end{aligned}$

  由上述結果遞推我們可以得到下面不等式(因為采用的梯度下降, 所以反過來就會每一步增加 $1$ 個 $\eta$ , 總的增加$k$個$\eta Y)$:
    $\hat{w}_{k} \cdot \hat{w}_{\mathrm{opt}} \geqslant \hat{w}_{k-1} \cdot \hat{w}_{\mathrm{opt}}+\eta \gamma \geqslant \hat{w}_{k-2} \cdot \hat{w}_{\mathrm{opt}}+2 \eta \gamma \geqslant \cdots \geqslant k \eta \gamma$
  第一個不等式已經推導完畢並得到了一個不等式結果,下面我們開始不等式(2)的推導。由書上公 式 (2.11) 得:
    $\left\|\tilde{w}_{k}\right\|^{2}=\left\|\tilde{w}_{k-1}+\eta y_{i} x_{i}\right\|^{2}$
  然后平方和公式展開,由書上公式 (2.10) 得(其中$y_i$的平方為 $1$ 省去):
    $\begin{aligned} \left\|\hat{w}_{k}\right\|^{2} &=\left\|\hat{w}_{k-1}\right\|^{2}+2 \eta \hat{w}_{k-1} \cdot \hat{x}_{i}+\eta^{2}\left\|\hat{x}_{i}\right\|^{2} \\ & \leqslant \left\|\hat{w}_{k-1}\right\|^{2}+\eta^{2}\left\|\hat{x}_{i}\right\|^{2} \\& \leqslant\left\|\hat{w}_{k-1}\right\|^{2}+\eta^{2} R^{2} \\ & \leqslant\left\|\hat{w}_{k-2}\right\|^{2}+2 \eta^{2} R^{2} \leqslant \cdots \\ & \leqslant k \eta^{2} R^{2} \end{aligned}$
  最后,綜合不等式(1)和(2),紅色方框處利用柯西不等式的向量形式得:
    $\begin{array}{l} k \eta \gamma \leqslant \hat{w}_{k} \cdot \hat{w}_{\mathrm{opt}} \leqslant\left\|\hat{w}_{k}\right\|\left\|\hat{w}_{\mathrm{opt}}\right\| \leqslant \sqrt{k} \eta R \\ k^{2} \gamma^{2} \leqslant k R^{2} \end{array}$
    $k \leqslant\left(\frac{R}{\gamma}\right)^{2}$
  所以,根據定理表明,誤分類的次數 $k$ 是有上界的,經過有限次訓練可以得到正確的分離超平面即當數據線性可分,感知機學習算法原始形式是收斂的。

4.3 對偶形式算法

  對偶問題簡單來說就是從一個不同的角度去解答相似問題,但是問題的解是相通的。在這里感知機的對偶形式是將 $w$ 和 $b$ 表示為了 $x_i$ 和 $y_i$ 的線性表示。
  由於$w$、$b$ 的梯度更新公式:
    $w={w+\eta{y_ix_i}}$
    $b={b+\eta{y_i}}$
  我們的 $w$、$b$,經過了 $n$ 次修改后的,參數可以變化為下公式,其中 $\alpha_{i}=n_{i} \eta$:
    $w=\sum \limits_{x_i\in M}\eta{y_ix_i}=\sum \limits_{i=1}^n\alpha_iy_ix_i$
    $b=\sum \limits_{x_i\in M}\eta{y_i}=\sum \limits_{i=1}^n\alpha_iy_i$
  這樣我們就得出了感知機的對偶算法。
  可以理解為從原始形式中的不斷更新參數 $w$ 和 $b$ 變成了學習某一點被誤分類的次數$a_i$即 $n_i $ (第個點 由於誤分進行更新的次數),並且在對偶形式中引入了$Gram$ 矩陣來存儲內積,可以提高運算速度, 而反觀原始形式,每次參數改變,所有的矩陣計算全部需要計算,導致計算量比對偶形式要大很多, 這就是對偶形式的高效之處。
  $Gram$ 矩陣定義如下:
    $G=\left[\begin{array}{cccc} x_{1} x_{1} & x_{1} x_{2} & \ldots & x_{1} x_{N} \\ x_{2} x_{1} & x_{2} x_{2} & \ldots & x_{2} x_{N} \\ \ldots & \cdots & \ldots & \cdots \\ x_{N} x_{1} & x_{N} x_{1} & \ldots & x_{N} x_{N} \end{array}\right]$
  輸入:訓練數據集$T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}$,$y_i\in{\{-1,+1\}}$,學習率$\eta(0<\eta<1)$
  輸出:$\alpha,b$ ;感知機模型$f(x)=sign(\sum \limits_{j=1}^n\alpha_jy_jx_j\cdot {x}+b)$ ,其中$\alpha=(\alpha_1,\alpha_2,...,\alpha_n)^T$
  步驟:
  1、賦初值$\alpha_0,b_0$ 。
  2、選取數據點$(x_i,y_i)$。
  3、判斷該數據點是否為當前模型的誤分類點,即判斷若$y_i(\sum \limits_{j=1}^n\alpha_jy_jx_j\cdot {x_i}+b)<=0$則更新
    $\alpha_i={\alpha_i+\eta}$
    $b={b+\eta{y_i}}$
  4、轉到2,直到訓練集中沒有誤分類點
  為了減少計算量,我們可以預先計算式中的內積,得到Gram矩陣
  $G=[x_i,x_j]_{N×N}$

  代碼:

def fit( self,X,y): #權重和偏置初始化
    self.alpha = np.zeros ( X.shape[0]) self.b =0 train_complete_flag = False Gram = np.dot(X, X.T) #存放樣本兩兩內積的Gram矩陣(特點)
    while not train_complete_flag: error_count = 0 for i in range ( X.shape[0]): x_, y_ = X[i],y[i] #有—個點當分類錯誤時,更新alpha_i和偏置
            tmp_sum = np.dot(np.multiply(self.alpha,y),Gram[ :, i]) #進行誤分類點判斷
            if y_* (tmp_sum+ self.b) <= 0: self.alpha[i] += self.lr self.b += self.lr * y_ error_count += 1
        if not error_count: train_complete_flag = True#訓練完成后計算權重
            self.w = np.dot(np.multiply (self.alpha,y),X)

4.4 原始形式和對偶形式的選擇

  • 在向量維數(特征數)過高時,計算內積非常耗時,應選擇對偶形式算法加速。
  • 在向量個數(樣本數)過多時,每次計算累計和就沒有必要,應選擇原始算法

5 訓練過程

  我們大概從下圖看下感知機的訓練過程。

  線性可分的過程:

  

   線性不可分的過程:

  

6 編程實現

  例子:如圖所示,正實例點是$x_1=(3,3)^T , x_2=(4,3)^T$,負實例點是$x_3=(1 , 1)^T$,,使用感知機算法求解感知機模型 f(x)=sign(w⋅x+b) 。這里$w = (w^{(1)},w^{(2)}),x=(x^{(1)},x^{(2)})$

  

   這里我們取初值$w_0=0,b_0=0$取$\eta=1$

   原始形式代碼如下:

train = [[(3, 3), 1], [(4, 3), 1], [(1, 1), -1]] w = [0, 0] b = 0 # 使用梯度下降法更新權重
def update(data): global w, b w[0] = w[0] + 1 * data[1] * data[0][0] w[1] = w[1] + 1 * data[1] * data[0][1] b = b + 1 * data[1] print(w, b) # 計算到超平面的距離
def cal(data): global w, b res = 0 for i in range(len(data[0])): res += data[0][i] * w[i] res += b res *= data[1] return res # 檢查是否可以正確分類
def check(): flag = False for data in train: if cal(data) <= 0: flag = True update(data) if not flag: print("The result: w: " + str(w) + ", b: "+ str(b)) return False flag = False for i in range(1000): check() if check() == False: break
View Code

  可以得到如下結果:

[3, 3] 1 [2, 2] 0 [1, 1] -1 [0, 0] -2 [3, 3] -1 [2, 2] -2 [1, 1] -3 The result: w: [1, 1], b: -3

  對偶形式代碼如下:

import numpy as np train = np.array([[[3, 3], 1], [[4, 3], 1], [[1, 1], -1]]) a = np.array([0, 0, 0]) b = 0 Gram = np.array([]) y = np.array(range(len(train))).reshape(1, 3)# 標簽
x = np.array(range(len(train) * 2)).reshape(3, 2)# 特征

# 計算Gram矩陣
def gram(): g = np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]]) for i in range(len(train)): for j in range(len(train)): g[i][j] = np.dot(train[i][0], train[j][0]) return g # 更新權重
def update(i): global a, b a[i] = a[i] + 1 b = b + train[i][1] print(a, b) # 計算到超平面的距離
def cal(key): global a, b, x, y i = 0 for data in train: y[0][i] = data[1] i = i + 1 temp = a * y res = np.dot(temp, Gram[key]) res = (res + b) * train[key][1] return res[0] # 檢查是否可以正確分類
def check(): global a, b, x, y flag = False for i in range(len(train)): if cal(i) <= 0: flag = True update(i) if not flag: i = 0 for data in train: y[0][i] = data[1] x[i] = data[0] i = i + 1 temp = a * y w = np.dot(temp, x) print("The result: w: " + str(w) + ", b: "+ str(b)) return False flag = False Gram = gram()# 初始化Gram矩陣
for i in range(1000): check() if check() == False: break
View Code

  可以得到如下結果:

[1 0 0] 1 [1 0 1] 0 [1 0 2] -1 [1 0 3] -2 [2 0 3] -1 [2 0 4] -2 [2 0 5] -3 The result: w: [[1 1]], b: -3

7 小結

  感知機算法是一個簡單易懂的算法,自己編程實現也不太難。前面提到它是很多算法的鼻祖,比如支持向量機算法,神經網絡與深度學習。因此雖然它現在已經不是一個在實踐中廣泛運用的算法,還是值得好好的去研究一下。感知機算法對偶形式為什么在實際運用中比原始形式快,也值得好好去體會。

參考文獻:

1:點到直線的距離

2:感知機原理(Perceptron)

3:  機器學習入門之《統計學習方法》筆記整理——感知機

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM