简答的说由输入空间(特征空间)到输出空间的以下函数:
\[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