机器学习001-感知机-2020-4-6

感知机 perceptron :  二分类的线性分类模型,属于判别模型

基本概念:

数据集T:

T=  { (x1,y1),(x2,y2) , .....(xn,yn)}     yi ={ -1, +1 }  i ∈ (1,n)

线性可分数据集: (linearly separable date set)

存在某个超平面  w.x+b = 0,能够将数据集的正实例点和负实例点全部正确划分到超平面的两侧.

即:yi = +1 ,     w.xi +b > 0

        yi = -1 ,      w.xi +b < 0

 

sign为符号函数: 

h(x)=sign(w⋅x+b) 感知机函数

 

线性分类器的几何表示有:直线(二维)平面(3维)、超平面(高纬)

 

下图中间的直线即 w⋅x+b=0 

学习策略:求得一个能够将训练集正实例点和负实例点完全正确分开的超平面(separating hyperplane)

损失函数: 误分类总点数 -> 所有误分类点到超平面距离之和 (转换问题求解)

极小化损失函数:点到直线的距离(有代数形式和向量形式)

推导:

1:点到直线的距离

2:对误分类点

如果  w *  xi + b> 0 , yi  = -1 (将负实例点判断为正实例点)

       (w * xi + b) * yi < 0

如果  w *  xi + b< 0 , yi  = 1 (将正实例点判断为负实例点)

       (w * xi + b) * yi < 0

        距离是整数,所以对一个误分类点 d

 

3:  一个数可以不用考虑 

4:所有误分类距离相加

极小化目标函数:

梯度下降: 分别对 w, b 求偏导数

极小化过程不是一次使M中所有误分类点的梯度下降,而是一次随机的选取一个误分类点使其梯度下降。使用的规则为 θ:=θ−α∇θℓ(θ),其中α是步长,∇θℓ(θ)是梯度。

随机选取一个误分类点根据上面的规则,更新w,b

w:= w -η*yi*xi

b:=b-η*yi      

η是学习率 learingrate (0,1),这样,通过迭代可以期待损失函数L(w,b)不断减小,直至为0.

算法的收敛性证明:

感知机学习算法原始形式:

输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈{-1, +1},i=1,2...N,学习速率为η)

输出:w, b;感知机模型f(x)=sign(w·x+b)

(1) 初始化w0,b0,权值可以初始化为0或一个很小的随机数

(2) 在训练数据集中选取(x_i, y_i)

(3) 如果yi(w xi+b)≤0

           w = w + ηyixi

           b = b + ηyi

(4) 转至(2),直至训练集中没有误分类点

实例:

《统计学习方法》第二版李航  P40

正实例点:x1 =(3,3) x2=(4,3)

负实例点:x3=(1,1)

import numpy as npimport matplotlib.pyplot as plt#训练数据x = np.array([(3.0,3.0),(4.0,3),(1,1)]) #标签y = np.array([(1),(1),(-1)])#参数初始化w = np.array([0.0,0.0])b = np.array([0.0])learngrate = 1i = 0while True:    if y[i]*(w@x[i] +b )<= 0:   # 出现分类错误的点         w += learngrate*x[i]*y[i]  #参数更新           b += learngrate*y[i]        i=0    elif i<2:        i+=1    else :        break print("训练结果:w= ",w,"b=",b)#画图#训练数据点x1 = [3,4,1]x2 = [4,3,1]plt.plot(x1,x2,'ro')#超平面x_1 =np.linspace(1,5)   x_2 =-(w[0]*x_+b)/w[1]   #根据超平面公式 plt.plot(x_1,x_2)plt.grid(True)  # 显示网格plt.xlabel('x1')  plt.ylabel('x2')  # 为了和原理中表达方式一致,横纵坐标应该是x1,x2plt.show()

感知机的对偶形式:(运筹学 线性规划)

对偶,简单地说,就是换一个不同的角度去解答相似问题,但是问题的解是相通的。

感知机:对偶形式是从增量的角度去看到参数的更新的。即先把所有的增量求出来,最后的参数就是在原来的参数基础上加上总的增量。

简单理解:记录每个样本由于误分类而进行更新的次数x。(ai =x)

有可能样本点一次也没更新,离超平面较远的。 (ai = 0)

有可能样本点不停的更新,在超平面附近的点。(ai =x)

ai = ni*η     (η :学习速率为,ni:第i个样本被修改的次数)

最后的w ,b 可以表示为:(w每个样本点被误判的次数乘以 yixi的累加和)

感知机对偶形式算法:

注意:

1:    ai :=ai +η  =niη +η  =(ni+1)η    (该样本点,更新一次)

2: Gram 矩阵的作用:

xj.xi:     将训练集中各个样本内积计算出来,以矩阵形式存储

  G = [  xj* xi  ] n*n

可以降低算法复杂度,主要是对高维空间减少计算量。

 

 

 

感知机对偶算法实现: 

《统计学习方法》第二版李航  P45

正实例点:x1 =(3,3) x2=(4,3)

负实例点:x3=(1,1)

import numpy as npfrom matplotlib import pyplot as pltfrom matplotlib import animation#训练数据x = np.array([(3.0,3.0),(4.0,3),(1,1)]) #标签y = np.array([(1),(1),(-1)])#参数初始化alpha = np.zeros(len(x),np.float)b = np.array([0.0])learngrate = 1def Gram_matrix(x):    """    x: 训练数据    return: g [ndim][ndim]  ndim训练数据个数    """    ndim = len(x)    g = np.empty((ndim,ndim),np.float)    for i in range(ndim):        for j in range(ndim):            g[i][j] =x[i]@x[j]    return gg = Gram_matrix(x)history = []   # 保存每次训练的 w ,bi = 0 while True:  #     if y[i]*(alpha*y@g[i]+b)<=0:  #对应感知机算法(3)        alpha[i] = alpha[i] +learngrate  # 参数更新        b = b+ learngrate*y[i]        history.append([alpha*y@x,b])        i= 0     #对应(4)    elif i<len(x)-1:        i = i+1    else:        break print('最终的结果:alpha :',alpha)print(" w: ",alpha*y@x,'b:',b)# 训练过程可视化fig = plt.figure(figsize=(6, 6))ax = plt.gca()ax.grid()line, = ax.plot([], [], '-', lw=2)def init():    line.set_data([],[])    x1,x2,x1_,x2_ = [],[],[],[]    for i in range(len(x)):        if y[i]>0:            x1.append(x[i][0])            x2.append(x[i][1])        else :            x1_.append(x[i][0])            x2_.append(x[i][1])    plt.plot(x1, x2, 'bo', x1_, x2_, 'rx')    plt.axis([-1,6,-1,6])    return line ,def update(i):    global history ,ax ,line    w = history[i][0]    b = history[i][1]    x1 = -6    y1 = -(b+x1*w[0])/w[1]    x2 = 6    y2 =-(b+x2*w[0])/w[1]    line.set_data([x1,x2],[y1,y2])    return line,ani = animation.FuncAnimation(fig, update, range(len(history)), init_func=init, interval=200,                             repeat=False)ani.save('Perceptron_1.gif', writer='imagemagick', fps=100)plt.show()

人工制造数据集:

from numpy import *import  numpy as np import pandas as pdimport matplotlib.pyplot as plt from matplotlib.lines import Line2Ddef makeLinearSeparableDataSet(weights ,numLines):    """    weights 是一个列表,里面存储的是我们用来产生随机数据的那条直线的法向量。    numLines 是一个正整数,表示需要创建多少个数据点。    Return  a linear Separable data Set     Randomly generate numLines points  on both sides of the    hyperplane . weights * x = 0     Notice : weights and x are vecors         """    w = np.array(weights) # <class 'numpy.ndarray'>  一个数组 ,w法向量的垂线    numFeatures = len(weights) #len 求长度    dataSet = zeros((numLines,numFeatures+1)) #产生一个全0 矩阵 n*n    for i in range(numLines):        x = np.random.rand(1,numFeatures)*20 -10         innerProduct = np.sum(w*x)        if innerProduct <=0 :            dataSet[i]  = append(x,-1)        else :            dataSet[i] = append(x,1)        return dataSet# 人工制造数据集 100个data=makeLinearSeparableDataSet([5,3],100)print(data)x = data[:,0:2]y = data[:,-1]#参数初始化alpha = np.zeros(len(x),np.float)b = np.array([0.0])learngrate = 1def Gram_matrix(x):    """    x: 训练数据    return: g [ndim][ndim]  ndim训练数据个数    """    ndim = len(x)    g = np.empty((ndim,ndim),np.float)    for i in range(ndim):        for j in range(ndim):            g[i][j] =x[i]@x[j]    return gg = Gram_matrix(x)history = []   # 保存每次训练的 w ,bi = 0 while True:  #     if y[i]*(alpha*y@g[i]+b)<=0:  #对应感知机算法(3)        alpha[i] = alpha[i] +learngrate  # 参数更新        b = b+ learngrate*y[i]        history.append([alpha*y@x,b])        i= 0     #对应(4)    elif i<len(x)-1:        i = i+1    else:        break print('最终的结果:alpha :',alpha)print(" w: ",alpha*y@x,'b:',b)# 训练过程可视化fig = plt.figure(figsize=(6, 6))ax = plt.gca()ax.grid()line, = ax.plot([], [], '-', lw=2)def init():    line.set_data([],[])    x1,x2,x1_,x2_ = [],[],[],[]    for i in range(len(x)):        if y[i]>0:            x1.append(x[i][0])            x2.append(x[i][1])        else :            x1_.append(x[i][0])            x2_.append(x[i][1])    plt.plot(x1, x2, 'bo', x1_, x2_, 'rx')    plt.axis([-10,10,-10,10])    return line ,def update(i):    global history ,ax ,line    w = history[i][0]    b = history[i][1]    x1 = -6    y1 = -(b+x1*w[0])/w[1]    x2 = 6    y2 =-(b+x2*w[0])/w[1]    line.set_data([x1,x2],[y1,y2])    return line,ani = animation.FuncAnimation(fig, update, range(len(history)), init_func=init, interval=200,                             repeat=False)ani.save('P_1.gif', writer='imagemagick', fps=100)plt.show()

 

References:

[1]https://blog.csdn.net/Dream_angel_Z/article/details/48915561

[2] 统计学习方法, 李航 著

[3]    https://www.bilibili.com/video/BV1dJ411B7gh?from=search&seid=407699525287630939(浙江大学机器学习课程 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值