目錄算法
感知機模型dom
感知機是二分類的線性分類模型,輸入爲實例的特徵向量,輸出爲實例的類別(取+1和-1)。感知機對應於輸入空間中將實例劃分爲兩類的分離超平面。感知機旨在求出該超平面,爲求得超平面導入了基於誤分類的損失函數,利用梯度降低法對損失函數進行最優化(最優化)。感知機的學習算法具備簡單而易於實現的優勢,分爲原始形式 和 對偶形式。感知機預測是用學習獲得的感知機模型對新的實例進行預測的,所以屬於判別模型。感知機是一種線性分類模型,只適應於線性可分的數據,對於線性不可分的數據模型訓練是不會收斂的。函數
定義(感知機): 假設輸入空間(特徵向量)是 $\chi\subseteq{R^n}$,輸出空間爲$Y=\{+1,-1\}$,輸入$x\subseteq\chi$表示實例的特徵向量,對應於輸入空間的點;輸出 $y\subseteq{Y}$表示實例的類別,則由輸入空間到輸出空間的表達形式爲:學習
$$f(x)=sign(w*x+b)$$測試
稱爲感知機,其中$w$叫做權值,$b$叫做偏置。$sign$是符號函數,即:優化
$$sign(x)= \begin{cases} -1& {x<0}\\ 1& {x\geq 0} \end{cases}$$spa
感知機的幾何解釋:code
線性方程$w \cdot x + b = 0$對應特徵空間$R^n$中的一個超平面$S$,其中$w$是超平面的法向量,$b$是超平面的截距,這個超平面將特徵空間劃分爲兩個部分,位於兩部分的點(特徵向量)分別被分爲正、負兩類,所以,超平面$S$稱爲分離超平面。orm
數據集的線性可分性:blog
給定一個數據集$T={(x_1, y_1), (x_2, y_2),…,(x_N, y_N)}$,其中$x_i \in R^n$,$y_i \in \lbrace+1, -1 \rbrace$,$i=1,2,3,\dots,N$,若存在超平面$S$:$w \cdot x + b = 0$將數據集的正實例點和負實例點徹底正確地劃分到$S$的兩側,則稱數據集$T$爲線性可分數據集。
損失函數
假設訓練數據線性可分,爲了找到這個平面須要肯定一個學習策略,即定義(經驗)損失函數並將損失函數極小化,
爲此,咱們首先計算任意一點$x_0$到超平面$S$的距離:
$$d=\frac{|w \cdot x_0 + b |}{||w||}$$
這裏,$||w||$是$w$的$L_2$範數。
其次,對於誤分類數據來講,
$$ y_i(w \cdot x_0 + b )>0$$
損失函數是全部誤分類點的集合:
$$L(w, b) = -\sum_{x_i \in M}y_i(w \cdot x_i + b)$$
感知機的優化方法
感知機學習算法是對如下最優化問題的算法。給定一個數據集:
$$T = \{(x_1, y_1), (x_2, y_2), ..., (x_N, y_N)\}$$
使其爲如下損失函數 極小化 問題的解:
$$L(w, b) = -\sum_{x_i \in M}y_i(w \cdot x_i + b)$$
感知機學習算法是誤分類驅動的,具體採用隨機梯度降低法(stochastic gradient descent)。首先任意選取一個超平面$w_0$,$b_0$,而後用梯度降低法不斷地極小化目標函數.感知機模型選擇的是採用隨機梯度降低,這意味着咱們每次僅僅須要使用一個誤分類的點來更新梯度.
$$\nabla_wL(w, b) = -\sum_{x_i \in M}y_ix_i $$
$$\nabla_bL(w, b) = -\sum_{x_i \in M}y_i$$
原始形式
輸入:訓練數據集$T = \{(x_1, y_1), (x_2, y_2), ..., (x_N, y_N)\}$
其中,$x_i \in \chi = R^{\ n}, \ y_i \in \gamma = \{+1, -1\}, \ i = 1, 2, ..., N$,學習率$\eta(0 < \eta \leq 1)$
輸出:$w$,$b$,感知機模型$f(x)=sign(w*x+b)$
1.選出初值$w_0$,$b_0$
2.在訓練集中選取數據$(x_i,y_i)$
3.若是$y_i(w\cdot x_i + b) \leq0$
$$w \leftarrow w + \eta y_ix_i \\ b \leftarrow b + \eta y_i$$
4.轉至 (2),直到訓練集中沒有誤分類點。
感知機模型的對偶形式
對偶形式的想法是,將$w$ 和$b$ 表示爲實例 $x_i$ 和標記 $y_i$的線性組合的形式,經過求解其係數而求得 $w$ 和$b$ 。不失通常性,可假設原始形式中初始值 $w_0$均$b_0$爲 0。對誤分類點$(x_i,y_i)$ 經過
$$w \leftarrow w + \eta y_ix_i \\ b \leftarrow b + \eta y_i$$
逐步修改w 和$b$,設修改$n$ 次,則 關於 $(x_i,y_i)$ 的增量分別是 $\alpha_iy_ix_i 和 $\alpha_iy_i$和$\alpha_iy_ix_i $和 $\alpha_iy_i$,這裏 $\alpha_i = n_i\eta$。最後獲得的$w$ 和$b$, 能夠分別表示爲
$$w = \sum_{i = 1}^N\alpha_iy_ix_i \\ b = \sum_{i = 1}^N\alpha_iy_i$$
這裏,$\alpha_i \geq 0, i = 1, 2, ..., N$
訓練過程
輸入:訓練數據集$T = \{(x_1, y_1), (x_2, y_2), ..., (x_N, y_N)\}$
其中,$x_i \in \chi = R^{\ n}, \ y_i \in \gamma = \{+1, -1\}, \ i = 1, 2, ..., N$,學習率$\eta(0 < \eta \leq 1)$
輸出:$w$,$b$,感知機模型$f(x) = sign(\sum_{j = 1}^N\alpha_jy_jx_j \cdot x + b)$,其中$\alpha = (\alpha_1, \alpha_2, ..., \alpha_N)^T$
1. $\alpha \leftarrow 0, b \leftarrow 0$
2.在訓練集中選取數據$(x_i,y_i)$
3.若是$y_i(\sum_{j = 1}^N\alpha_jy_jx_j \cdot x_i + b) \leq 0$,
$$\alpha_j \leftarrow \alpha_j + \eta \\b\leftarrow b + \eta y_i$$
4.轉至 2,直到訓練集中沒有誤分類點。
對偶形式中,能夠預處理訓練集中實例間的內積並以矩陣存儲,該矩陣即 Gram 矩陣(Gram matrix)
$$G = [x_i \cdot x_j]_{N \times N}$$
感知機算法實現
from sklearn.datasets import make_classification from sklearn.linear_model import Perceptron from sklearn.model_selection import train_test_split from matplotlib import pyplot as plt import numpy as np #利用算法進行建立數據集 def creatdata(): x,y = make_classification(n_samples=1000, n_features=2,n_redundant=0,n_informative=1,n_clusters_per_class=1) ''' #n_samples:生成樣本的數量 #n_features=2:生成樣本的特徵數,特徵數=n_informative() + n_redundant + n_repeated #n_informative:多信息特徵的個數 #n_redundant:冗餘信息,informative特徵的隨機線性組合 #n_clusters_per_class :某一個類別是由幾個cluster構成的 make_calssification默認生成二分類的樣本,上面的代碼中,x表明生成的樣本空間(特徵空間) y表明了生成的樣本類別,使用1和0分別表示正例和反例 y=[0 0 0 1 0 1 1 1... 1 0 0 1 1 0] ''' return x,y if __name__ == '__main__': x,y=creatdata() #將生成的樣本分爲訓練數據和測試數據,並將其中的正例和反例分開 x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0) #正例和反例 positive_x1=[x[i,0]for i in range(len(y)) if y[i]==1] positive_x2=[x[i,1]for i in range(len(y)) if y[i]==1] negetive_x1=[x[i,0]for i in range(len(y)) if y[i]==0] negetive_x2=[x[i,1]for i in range(len(y)) if y[i]==0] #定義感知機 clf=Perceptron(fit_intercept=True,n_iter=50,shuffle=False) # 使用訓練數據進行訓練 clf.fit(x_train,y_train) #獲得訓練結果,權重矩陣 weights=clf.coef_ #獲得截距 bias=clf.intercept_ #到此時,咱們已經獲得了訓練出的感知機模型參數,下面用測試數據對其進行驗證 acc=clf.score(x_test,y_test)#Returns the mean accuracy on the given test data and labels. print('平均精確度爲:%.2f'%(acc*100.0)) #最後,咱們將結果用圖像顯示出來,直觀的看一下感知機的結果 #畫出正例和反例的散點圖 plt.scatter(positive_x1,positive_x2,c='red') plt.scatter(negetive_x1,negetive_x2,c='blue') #畫出超平面(在本例中便是一條直線) line_x=np.arange(-4,4) line_y=line_x*(-weights[0][0]/weights[0][1])-bias plt.plot(line_x,line_y) plt.show()