感知機:
假設輸入空間是\(\chi\subseteq R^n\),輸出空間是\(\gamma =\left( +1,-1\right)\)。輸入\(\chi\in X\)表示實例的特征向量,對應於輸入空間的點;輸出\(y\in \gamma\)表示實例的類別。由輸入空間到輸出空間的如下函數:
\[f\left( x\right) =sign\left( wx+b\right) \]稱為感知機。其中,w和b為感知機模型的參數,sign是符號函數,即:
\[sign\left( x\right) =\begin{cases}+1 &x\geq 0\\-1 &x<0 \end{cases} \]
感知機學習策略
假設訓練數據集是線性可分的,感知機學習的目標就是求得一個能夠將訓練集正實例點和負實例點完成正確分開的分離超平面。為了找出這樣的超平面,即確定感知機模型參數w,b,需定義損失函數並將損失函數極小化。
損失函數使用誤分類點到超平面S的總距離,因此輸入空間\(R^n\)中任何一點\(x_0\)到超平面S的距離為:
在這里,\(\left\| w\right\|\)是w的\(L_2\)范數。
對於誤分類的數據\(\left(x_i,y_i\right)\)來說,
成立。因為當\(wx_i + b >0\)時,\(y_i=-1\),而當\(wx_i + b < 0\)時,\(y_i=+1\),因此,誤分類點\(x_i\)到超平面S的距離是:
這樣,假設超平面S的誤分類點集合為M,那么所以誤分類點到超平面S的總距離為:
不考慮\(\dfrac {1}{\left\| w\right\| }\),就得到感知機學習的損失函數:
其中M為誤分類點的集合。
感知機算法原始形式
感知機算法是使得損失函數\(L(w,b)\)極小化的最優化問題,可以使用隨機梯度下降法來進行最優化。
假設誤分類點集合M是固定的,那么損失函數\(L(w,b)\)的梯度由
給出,隨機選取一個誤分類點\((x_i,y_i)\),對w,b進行更新:
其中\(\eta(0<\eta \leq1)\) 稱為學習率(learning rate),這樣通過迭代可以使得損失函數\(L(w,b)\)不斷減小,直到為0。
感知機算法原始形式的主要訓練過程:
def trainPerceptron(dataMat, labelMat, eta):
m, n = dataMat.shape
weight = np.zeros(n)
bias = 0
flag = True
while flag:
for i in range(m):
if np.any(labelMat[i] * (np.dot(weight, dataMat[i]) + bias) <= 0):
weight = weight + eta * labelMat[i] * dataMat[i].T
bias = bias + eta * labelMat[i]
print("weight, bias: ", end="")
print(weight, end=" ")
print(bias)
flag = True
break
else:
flag = False
return weight, bias
完整代碼可以前往我的github查看,還有可視化過程。
https://github.com/yangliu0/MachineLearning/tree/master/Perceptron
感知機算法的對偶形式
假設\(w_0,b_0\)均初始化為0,對誤分類點通過
逐步修改\(w,b\),設修改n次,則\(w,b\)關於\((w_i,y_i)\)的增量分為是\(\alpha_i y_ix_i\)和\(\alpha_i y_i\),這里的\(\alpha_i=n_i \eta\),其中\(n_i\)表示第i個點誤分類的次數,這樣最后學習到的\(w,b\)可以分別表示為
實例點更新的次數越多,意味着它距離分離超平面越近,也就越難正確分類。
訓練過程:輸出\(\alpha,b\),其中\(\alpha = (\alpha_1, \alpha_2,...,\alpha_N)^T\)
(1)\(\alpha\leftarrow0, b\leftarrow0\)
(2)在訓練集中選取數據\((x_i, y_i)\)
(3)如果\(y_{i}\left( \sum ^{n}_{j=1}\alpha _{j}y_{j}x_{j}\cdot x_{i}+b\right)\leq0\),則
(4)轉到(2),直到沒有錯誤。
最后通過\(w=\sum ^{N}_{i=1}\alpha _{i}y_{i}x_{i}\)計算出\(w\),使用上述過程求出的\(b\),即計算出模型參數。
以下就是上述感知機對偶形式的python訓練代碼:
def trainModel(dataMat, labelMat, alpha, b, eta):
flag = True
while flag:
for i in range(m):
if (labelMat[i, 0] * (np.sum((alpha * labelMat * np.dot(dataMat, dataMat[i].T).reshape((m, 1)))) + b)) <= 0:
alpha[i] = alpha[i] + eta
b = b + eta * labelMat[i]
flag = True
break
else:
flag = False
w = np.dot(dataMat.T, alpha * labelMat)
return w, b
以下就是結果可視化圖,可以看出,訓練的感知機算法對線性可分的點進行了很好的划分。
感知機算法的原始形式和對偶形式分別對應了支持向量機(SVM)的兩種相應形式,是它們的基礎。
上述兩種形式的感知機算法完整實現可以在我的github查看,使用python實現。
https://github.com/yangliu0/MachineLearning/tree/master/Perceptron
參考文獻
[1]統計學習方法.李航