主要思想
设 $\vec w$ 为权重项,$b$ 为偏置项,$\vec x$ 为特征值,$y$ 为标签
在线性可分 的情况下,拟合线性函数 $\vec w\cdot\vec x+b$,使得:
也就是:
误分类点
根据上文,很容易知道对于一个特征向量 $\vec x$ 如果误分类了,则会有:
借此可以很方便的找出误分类点。
损失函数
把误分类点到线性函数的距离作为误差,组成损失函数:
更新权重项与偏置项
采用梯度下降的方法进行更新。设 $L(\vec w,b) = lossFunc$ 我们要使 $L(\vec w,b)$ 的值尽量小,则可以求其梯度的负数 $-\nabla L$ 即为该函数下降最快的方向,但是注意,通过这个方法可能无法到达全局最优点,可能会到达局部最优点或鞍点 。不过这无所谓,对于感知机来说这就足够了。
其中 $\alpha$ 是学习率,要注意 $\vec xy$ 是一个向量。
模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import numpy as npX_train = np.array([[1 , 1 ], [1 , 0 ], [0 , 1 ], [0 , 0 ]]) Y_train = np.array([1 , 1 , 1 , -1 ]) class perceptron : def __init__ (self, X, Y, Alpha = 0.01 ): self.alpha = Alpha self.X_trn = np.array(X) self.Y_trn = np.array(Y) self.B = np.random.rand() self.W = np.random.rand(len (X[0 ])) def check (self, i ): Sum = np.dot(self.W, self.X_trn[i]) + self.B if (Sum * self.Y_trn[i] >= 0 ): return True else : return False def Loss_func (self, i ): self.W += self.alpha * self.X_trn[i] * self.Y_trn[i] self.B += self.alpha * self.Y_trn[i] def train (self ): Error = True while (Error): Error = False for i in range (len (self.X_trn)): if (self.check(i) == False ): self.Loss_func(i) Error = True print ("W: " , self.W, "\tB: " , self.B) per = perceptron(X_train, Y_train, 0.01 ) per.train()
以及调库实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import PerceptronMy_Data = datasets.load_iris() clf = Perceptron() x = My_Data['data' ] y = My_Data['target' ] train_x, test_x, train_y, test_y = train_test_split(x, y, test_size = 0.3 ) clf.fit(train_x, train_y) clf.predict(test_x) print (clf.score(test_x, test_y))