簡答的說由輸入空間(特徵空間)到輸出空間的以下函數:
\[f(x)=sign(w\cdot x+b)\]
稱爲感知機,其中,\(w\)和\(b\)表示的是感知機模型參數,\(w \in R^n\)叫作權值,\(b \in R\)叫作偏置(bias)
感知機是一種線性分類模型屬於判別模型。html
感知機的幾何解釋:線性方程:\[w \cdot x + b = 0\]對應於特徵空間\(R^n\)中的一個超平面S,這個超平面將特徵空間分爲兩個部分,位於兩部分的點(特徵向量)分別被分爲正負兩類,超平面S被稱爲分離超平面。算法
首先感知機的數據集是對線性可分的數據集的,所謂線性可分就是存在這麼一個超平面能夠把數據徹底正確的劃分到兩邊。
感知機學習的目標就是要得出\(w \quad b\),須要肯定一個(經驗)損失函數,並將損失函數最小化。對於這個損失函數咱們最容易想到的就是誤分類的總數,可是咱們也要注意到這個不可以是\(w \quad b\)的可導連續函數,因此咱們選擇點誤分類的點到超平面的距離做爲損失函數。最終獲得損失函數定義爲:
\[L(w,b)=-\sum_{x_i \in M}y_i(w \cdot x_i+b)\]函數
這裏咱們用的是隨機梯度降低法,思想是:首先隨機選擇一個分離超平面\(w_0,b_0\)而後用隨機梯度降低不斷最小化目標函數,最終獲得徹底正確的分類效果學習
1.選擇初始值\(w_0,b_0\)
2.在訓練集中選取數據\((x_i,y_i)\)
3.若是\(y_i(w \cdot x_i+b)\le 0\)
\[w \gets w+\eta y_i x_i\]\[b \gets b+ \eta y_i\]
4.跳轉至2,直至訓練集中沒有誤分類點spa
w = [0, 0] b = 0 def createDataSet(): """ create dataset for test """ return [[(3, 3), 1], [(4, 3), 1], [(1, 1), -1]] def update(item): """ update with stochastic gradient descent """ global w, b w[0] += item[1] * item[0][0] w[1] += item[1] * item[0][1] b += item[1] def cal(item): """ calculate the functional distance between 'item' an the dicision surface. output yi(w*xi+b). """ res = 0 for i in range(len(item[0])): res += item[0][i] * w[i] res += b res *= item[1] return res def check(): """ check if the hyperplane can classify the examples correctly """ flag = False for item in training_set: if cal(item) <= 0: flag = True update(item) if not flag: print "RESULT: w: " + str(w) + " b: " + str(b) return flag if __name__ == "__main__": training_set = createDataSet() while check(): pass
1.\(\alpha \gets 0,b \gets 0\)
2.在訓練集中選取數據\((x_i,y_i)\)
3.若是\(y_i(\sum_{j=1}^{N}\alpha_jy_ix_j\cdot x_i+b) \le 0\)
\[\alpha_i \gets \alpha_i+\eta\]\[b \gets b+\eta y_i\]
4.轉至2,直到沒有誤分類的數據code
這裏主要是有一個叫作gram矩陣的東西,由於咱們發現下面的計算過程當中都是之內積的形式存在的,因此說這部分的值能夠先算出來。\(G=[x_i*x_j]\)htm
import numpy as np def createDataSet(): """ create data set for test """ return np.array([[[3, 3], 1], [[4, 3], 1], [[1, 1], -1]]) def cal_gram(): """ calculate the Gram matrix """ g = np.empty((len(training_set), len(training_set)), np.int) for i in range(len(training_set)): for j in range(len(training_set)): g[i][j] = np.dot(training_set[i][0], training_set[j][0]) return g def update(i): """ update parameters using stochastic gradient descent """ global alpha, b alpha[i] += 1 b = b + y[i] def cal(i): """ cal """ global alpha, b, x, y res = np.dot(alpha * y, Gram[i]) res = (res + b) * y[i] return res def check(): """ check if the hyperplane can classify the examples correctly """ global alpha, b, x, y flag = False for i in range(len(training_set)): if cal(i) <= 0: flag = True update(i) if not flag: w = np.dot(alpha * y, x) print "RESULT: w: " + str(w) + " b: " + str(b) return False return True if __name__ == "__main__": training_set = createDataSet() alpha = np.zeros(len(training_set), np.float) b = 0.0 Gram = None y = np.array(training_set[:, 1]) x = np.empty((len(training_set), 2), np.float) for i in range(len(training_set)): x[i] = training_set[i][0] Gram = cal_gram() while check(): pass
本文連接
以上內容參考自《統計學習方法》blog