感知機的原理
感知機是二分類的線性模型,其輸入是實例的特征向量,輸出的是事例的類別,分別是+1和-1,屬於判別模型。
假設訓練數據集是線性可分的,感知機學習的目標是求得一個能夠將訓練數據集正實例點和負實例點完全正確分開的分離超平面。如果是非線性可分的數據,則最后無法獲得超平面。感知機由Rosenblatt於1957年提出的,是神經網絡和支持向量機的基礎。
1: 感知機模型
定義.感知機:假設輸入空間 ,輸出空間
。輸入
表示實例的特征向量,對應於輸入空間的點;輸出
表示實例的類別。由輸入空間到輸出空間的函數
稱為感知機。其中, 和
為感知機模型參數,
叫做權值或權值向量,
叫偏置,
表示
和
的內積。
是符號函數,即
感知機是一種線性分類模型,屬於判別模型。感知機模型的假設空間是定義在特征空間中的所有線性分類模型或線性分類器,即函數集合 。
線性方程
對應於特征空間 中的一個超平面
,其中
是超平面的法向量,
是超平面的截距。超平面
將特征空間划分為兩部分,位於其中的點被分為正、負兩類,超平面
稱為分離超平面。
2: 感知機學習策略
2.1 數據集的線性可分
給定數據集
其中, ,如果存在某個超平面
能夠將數據集的正實例和負實例完全正確地划分到超平面的兩側,即對所有 的實例
,有
,對所有
的實例
,有
,則稱數據集
為線性可分數據集 linearly separable data set ;否則,稱數據集
線性不可分。
2.2 感知機學習策略
輸入空間 中的任一點
到超平面
的距離:
其中 是
的
范數。
對於誤分類數據 ,當
時,
,當
時,
,有
誤分類點 到分離超平面的距離:
假設超平面 的誤分類點集合為
,則所有誤分類點到超平面
的總距離:
給定訓練數據集
其中, 。感知機
的損失函數定義為
其中, 為誤分類點的集合。
注:對於這里損失函數少了 可以先這么理解:我們目的是要找個超平面
,可以增加一個特征:
,因此超平面可以簡化為
,用向量表示為
,則所有誤分類點到超平面
的總距離:
。這樣可以發現,分子和分母都含有
,當分子的
擴大
倍時,分母的
范數也會擴大
倍。也就是說,分子和分母有固定的倍數關系。那么我們可以固定分子或者分母為1,然后求另一個即分子自己或者分母的倒數的最小化作為損失函數,這樣可以簡化我們的損失函數。在感知機模型中,我們采用的是保留分子,即最終感知機模型的損失函數簡化為:
3: 感知機學習算法
3.1 感知機學習算法的原始形式
給定訓練數據集
其中, 。求參數
和
,使其為以下損失函數極小化問題的解
其中, 為誤分類點的集合。
感知機學習算法是誤分類驅動的,采用隨機梯度下降法 stochastic gradient descent。極小化過程中不是一次使用$M$中所有誤分類點的梯度下降,而是一次隨機選取一個誤分類點使其梯度下降。
假設誤分類點集合 是固定的,則損失函數
的梯度
隨機選取一個誤分類點 ,對
進行更新:
其中, 是步長,稱為學習率。
感知機算法(原始形式):
輸入:訓練數據集 ,其中
;學習率
。
輸出: ;感知機模型
1. 選取初值
2. 在訓練集中選取數據
3. 如果
4. 轉至2,直至訓練集中沒有誤分類點。
直觀解釋:當一個實例點被誤分類,即位於分離超平面的錯誤一側,則調整 的值,使分離超平面向該誤分類點的一側移動,以減少該誤分類點與超平面的距離,直至超平面越過該分類點使其被分類正確。
例1
對於訓練數據集,其中正例點是x1=(3,3)T,x2=(4,3)T,負例點為x3=(1,1)T,用感知機學習算法的原始形式求感知機模型f(x)=w·x+b。這里w=(w(1),w(2))T,x=(x(1),x(2))T
解:構建最優化問題:
按照算法求解w, b。η=1
(1)取初值w0=0, b0=0
(2)對於(3,3):-(0+0)+0=0未被正確分類。更新w,b
w1=w0+1*y1·x1 = (0,0)T+1(3,3)T=(3,3)T
b1=b0+y1=1
得到線性模型w1x+b1 = 3x(1)+3x(2)+1
(3)返回(2)繼續尋找yi(w·xi+b)≤0的點,更新w,b。直到對於所有的點yi(w·xi+b)>0,沒有誤分類點,損失函數達到最小。
分離超平面為x(1)+x(2)-3=0
感知機模型為 f(x)=sign(x(1)+x(2)-3)
在迭代過程中,出現w·xi+b=-2,此時,取任意一個點,都會是其小於0,不同的取值順序會導致最終的結果不同,因此解並不是唯一的。為了得到唯一的超平面,需要對分離超平面增加約束條件,這就是支持向量機的想法。
__author__ = 'Administrator' #! /usr/bin/python <br> # -*- coding:utf8 -*- import numpy as np class Perceptron(object): """ Perceptron classifier. Parameters(參數) ------------ eta : float Learning rate (between 0.0 and 1.0) 學習效率 n_iter : int Passes over the training dataset(數據集). Attributes(屬性) ----------- w_ : 1d-array Weights after fitting. errors_ : list Number of misclassifications in every epoch(時間起點). """ def __init__(self, eta=0.01, n_iter=10): self.eta = eta self.n_iter = n_iter def fit(self, X, y): ''' Fit training data. Parameters ---------- X : {array-like}, shape = [n_samples, n_features] X的形式是列矩陣 Training vectors, where n_samples is the number of samples and n_features is the number of features. y : array-like, shape = [n_samples] Target values. Returns ------- self : object ''' self.w_ = np.zeros(1 + X.shape[1]) # zeros()創建了一個 長度為 1+X.shape[1] = 1+n_features 的 0數組 #初始化權值為0 # self.w_ 權向量 self.errors_ = [] for _ in range(self.n_iter): errors = 0 for xi, target in zip(X,y): update = self.eta * (target - self.predict(xi)) self.w_[1:] += update * xi self.w_[0] += update #更新權值,x0 =1 errors += int(update != 0.0) self.errors_.append(errors) #每一步的累積誤差 return self def net_input(self, X): """Calculate net input""" return (np.dot(X, self.w_[1:])+self.w_[0]) def predict(self, X): """return class label after unit step""" return np.where(self.net_input(X) >= 0.0, 1, -1)
3.2 算法的收斂性
定理.Novikoff 設訓練數據集 是線性可分的,其中,
,則:
(1)存在滿足條件 的超平面
將訓練數據集完整正確分開;並存在
,對所有
(2)令 ,則感知機算法在訓練集上的誤分類次數
滿足不等式:
3.3 感機學習算法的對偶形式
上面的感知機模型的算法形式我們一般稱為感知機模型的算法原始形式。對偶形式是對算法執行速度的優化。
通過上一節感知機模型的算法原始形式 可以看出,我們每次梯度的迭代都是選擇的一個樣本來更新
向量。最終經過若干次的迭代得到最終的結果。對於從來都沒有誤分類過的樣本,他被選擇參與
迭代的次數是0,對於被多次誤分類而更新的樣本
,它參與
迭代的次數我們設置為
。如果令
向量初始值為0向量,
修改n次,則
關於
的增量分別是
和
,其中
。
可表示為
其中,
感知機算法(對偶形式):
輸入:訓練數據集 ,其中
;學習率
。
輸出: ;感知機模型
,其中
1.
2. 在訓練集中選取數據
3. 如果
4. 轉至2,直至訓練集中沒有誤分類點。
4.3 原始形式和對偶形式的選擇
- 在向量維數(特征數)過高時,計算內積非常耗時,應選擇對偶形式算法加速。
- 在向量個數(樣本數)過多時,每次計算累計和就沒有必要,應選擇原始算法
5. 訓練過程
我們大概從下圖看下感知機的訓練過程。
線性可分的過程:
線性不可分
6. 小結
感知機算法是一個簡單易懂的算法,自己編程實現也不太難。前面提到它是很多算法的鼻祖,比如支持向量機算法,神經網絡與深度學習。因此雖然它現在已經不是一個在實踐中廣泛運用的算法,還是值得好好的去研究一下。感知機算法對偶形式為什么在實際運用中比原始形式快,也值得好好去體會。
參考文獻:感知機原理小結