感知机算法(二) pocket_PLA


转载自 博客

1.pocket_PLA

上篇讲述了感知机算法(一)
PLA算法只能解决线性可分的问题。对于数据本身不是线性可分的情况,又该如何解决呢?下面,我们就将对PLA进行优化,以解决更一般的线性不可分问题。
首先,我们来看一下线性不可分的例子:
在这里插入图片描述因为数据线性不可分,所以PLA算法会陷入无限循环,这时候需要对PLA进行优化。优化后的PCA的基本做法很简单,就是如果迭代更新后分类错误样本比前一次少,则更新权重系数 w ;没有减少则保持当前权重系数 w 不变。也就是说,可以把条件放松,即不苛求每个点都分类正确,而是容忍有错误点,取错误点的个数最少时的权重系数 w 。通常在有限的迭代次数里,都能保证得到最佳的分类线。

这种算法也被称为「口袋PLA」Pocket PLA。怎么理解呢?就好像我们在搜寻最佳分类直线的时候,随机选择错误点修正,修正后的直线放在口袋里,暂时作为最佳分类线。然后如果还有错误点,继续随机选择某个错误点修正,修正后的直线与口袋里的分类线比较,把分类错误点较少的分类线放入口袋。一直到迭代次数结束,这时候放在口袋里的一定是最佳分类线,虽然可能还有错误点存在,但已经是最少的了。

2.算法实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
if __name__=='__main__':
    data=pd.read_csv('./MachineLearningInAction-master/Perceptron Linear Algorithm/data/data2.csv',header=None)
    x=data.iloc[:,:2].values
    y=data.iloc[:,2].values
    
    #显示原始数据
    plt.scatter(x[:50,0],x[:50,1],color='blue',marker='o',label='positive')
    plt.scatter(x[50:,0],x[50:,1],color='red',marker='+',label='negative')
    plt.xlabel('feature1')
    plt.ylabel('feature2')
    plt.title('original data')
    plt.legend(loc='upper left')
    plt.show()
    
    #归一化    
    u=np.mean(x,axis=0)
    v=np.std(x,axis=0)
    X=(x-u)/v
   
    #增加一列,加上偏置
    X=np.hstack((X,np.ones((X.shape[0],1))))
    #随机初始化
    w=np.random.randn(3,1) 
    
    x1=-2
    y1=(-w[2]-w[1]*x1)/w[1]
    x2=2
    y2=(-w[2]-w[1]*x2)/w[1]
     
    plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive')
    plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative')
    plt.plot((x1,y1),(x2,y2),color='pink')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.legend(loc = 'upper left')
    plt.title('Normalization data')
    plt.show()
    
    num_best=100
    for i in range(1000):
         y_pre1=np.dot(X,w)
         y_pre2=np.ones_like(y)
         y_pre2[np.where(y_pre1<0)[0]]=-1
         
         num_fault=len(np.where(y_pre2!=y)[0])
         if num_fault==0:
             break
         
         if i==0:
             w_best=w
             num_best=num_fault
         else:
             if num_fault<num_best:# 新的权重对应的直线对点分类错误更少,则更新权重
                 w_best=w
                 num_best=num_fault
                 print('第%2d次循环,更新,分类错误的点个数:%2d' % (i, num_fault))
                 x1 = -2
                 y1 = -1 / w_best[1] * (w_best[2] * 1 + w_best[0] * x1)
                 # 直线第二个坐标(x2,y2)
                 x2 = 2
                 y2 = -1 / w_best[1] * (w_best[2] * 1 + w_best[0] * x2)
                 # 作图
                 plt.scatter(X[:50, 0], X[:50, 1], color='blue', marker='o', label='Positive')
                 plt.scatter(X[50:, 0], X[50:, 1], color='red', marker='x', label='Negative')
                 plt.plot([x1,x2], [y1,y2],'r')
                 plt.xlabel('Feature 1')
                 plt.ylabel('Feature 2')
                 plt.legend(loc = 'upper left')
                 plt.show()
                 time.sleep(2)
                 
         r=np.random.choice(num_fault)#每次随机选择错误分类的点
         t=np.where(y_pre2!=y)[0][r]
         w+=y[t]*X[t,:].reshape((3,1))
         

3.优点分析

1.wt是随机的,可能算了很多次都没有找出一个更好的。

2.假设数据一开始就是线性可分,那么这个算法找出来的未必是最好解,且时间花费也可能比较大。

4.运行过程图

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
可以看到,经过一定次数的循环,可以找到较好的分类直线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值