感知机学习的目标就是求得一个可以将训练数据集中正负实例彻底分开的分类超平面python
感知机原始形式dom
from __future__ import division import random import numpy as np import matplotlib.pyplot as plt def sign(v): if v>=0: return 1 else: return -1 def train(train_num,train_datas,lr): w=[0,0] b=0 for i in range(train_num): x=random.choice(train_datas) x1,x2,y=x if(y*sign((w[0]*x1+w[1]*x2+b))<=0): w[0]+=lr*y*x1 w[1]+=lr*y*x2 b+=lr*y return w,b def plot_points(train_datas,w,b): plt.figure() x1 = np.linspace(0, 8, 100) x2 = (-b-w[0]*x1)/w[1] plt.plot(x1, x2, color='r', label='y1 data') datas_len=len(train_datas) for i in range(datas_len): if(train_datas[i][-1]==1): plt.scatter(train_datas[i][0],train_datas[i][1],s=50) else: plt.scatter(train_datas[i][0],train_datas[i][1],marker='x',s=50) plt.show() if __name__=='__main__': train_data1 = [[1, 3, 1], [2, 2, 1], [3, 8, 1], [2, 6, 1]] # 正样本 train_data2 = [[2, 1, -1], [4, 1, -1], [6, 2, -1], [7, 3, -1]] # 负样本 train_datas = train_data1 + train_data2 # 样本集 w,b=train(train_num=50,train_datas=train_datas,lr=0.01) plot_points(train_datas,w,b)
感知机对偶形式学习
通俗理解“原问题难以求解或者求解的消耗较高,于是转为求解它的对偶问题”。优化
此处,对偶问题主要解决的是将感知机的对偶形式中对w,b的学习变成了对α,b的学习,原始形式中,w在每一轮迭代错分时都须要更新,而采用对偶形式时,对于某一点(xi,yi)发生错分时,咱们只须要更新其对应的αi便可,便可一次计算出w. spa
另外,xj⋅xi仅之内积的形式出现,所以咱们能够先计算出x的gram矩阵存储起来,这样正式训练时只须要查表就能够获得xj⋅xi的值,这样作能够方便程序的优化,提升运算的速度。 .net
至关于不断更新xj⋅xi以前的系数,而不用每次像原始形式那样去计算向量积。code
from __future__ import division import random import numpy as np import matplotlib.pyplot as plt def sign(v): if v>=0: return 1 else: return -1 def train(train_num,train_datas,lr): w=0.0 b=0 datas_len = len(train_datas) alpha = [0 for i in range(datas_len)] train_array = np.array(train_datas) gram = np.matmul(train_array[:,0:-1] , train_array[:,0:-1].T) for idx in range(train_num): tmp=0 i = random.randint(0,datas_len-1) yi=train_array[i,-1] for j in range(datas_len): tmp+=alpha[j]*train_array[j,-1]*gram[i,j] tmp+=b if(yi*tmp<=0): alpha[i]=alpha[i]+lr b=b+lr*yi for i in range(datas_len): w+=alpha[i]*train_array[i,0:-1]*train_array[i,-1] return w,b,alpha,gram def plot_points(train_datas,w,b): plt.figure() x1 = np.linspace(0, 8, 100) x2 = (-b-w[0]*x1)/(w[1]+1e-10) plt.plot(x1, x2, color='r', label='y1 data') datas_len=len(train_datas) for i in range(datas_len): if(train_datas[i][-1]==1): plt.scatter(train_datas[i][0],train_datas[i][1],s=50) else: plt.scatter(train_datas[i][0],train_datas[i][1],marker='x',s=50) plt.show() if __name__=='__main__': train_data1 = [[1, 3, 1], [2, 2, 1], [3, 8, 1], [2, 6, 1]] # 正样本 train_data2 = [[2, 1, -1], [4, 1, -1], [6, 2, -1], [7, 3, -1]] # 负样本 train_datas = train_data1 + train_data2 # 样本集 w,b,alpha,gram=train(train_num=500,train_datas=train_datas,lr=0.01) plot_points(train_datas,w,b)
参考:http://blog.csdn.net/winter_evening/article/details/70196040blog