python实现感知器算法(批处理)


Posted in Python onJanuary 18, 2019

本文实例为大家分享了Python感知器算法实现的具体代码,供大家参考,具体内容如下

先创建感知器类:用于二分类

# -*- coding: utf-8 -*-
 
import numpy as np
 
 
class Perceptron(object):
  """
  感知器:用于二分类
  参照改写 https://blog.csdn.net/simple_the_best/article/details/54619495
  
  属性:
  w0:偏差
  w:权向量
  learning_rate:学习率
  threshold:准则阈值
  """
  
  def __init__(self,learning_rate=0.01,threshold=0.001):
    self.learning_rate=learning_rate
    self.threshold=threshold
    
  def train(self,x,y):
    """训练
    参数:
    x:样本,维度为n*m(样本有m个特征,x输入就是m维),样本数量为n
    y:类标,维度为n*1,取值1和-1(正样本和负样本)
    
    返回:
    self:object
    """
    self.w0=0.0
    self.w=np.full(x.shape[1],0.0)
    
    k=0
    while(True):
      k+=1
      dJw0=0.0
      dJw=np.zeros(x.shape[1])
      err=0.0
      for i in range(0,x.shape[0]):
        if not (y[i]==1 or y[i]==-1):
          print("类标只能为1或-1!请核对!")
          break
        update=self.learning_rate*0.5*(y[i]-self.predict(x[i]))
        dJw0+=update
        dJw+=update*x[i]
        err+=np.abs(0.5*(y[i]-self.predict(x[i])))
      self.w0 += dJw0
      self.w += dJw
      if np.abs(np.sum(self.learning_rate*dJw))<self.threshold or k>500:
        print("迭代次数:",k," 错分样本数:",err)
        break
    return self
    
    
  def predict(self,x):
    """预测类别
    参数:
    x:样本,1*m维,1个样本,m维特征
    
    返回:
    yhat:预测的类标号,1或者-1,1代表正样本,-1代表负样本
    """
    if np.matmul(self.w,x.T)+self.w0>0:
      yhat=1
    else:
      yhat=-1
    return yhat 
  
  def predict_value(self,x):
    """预测值
    参数:
    x:样本,1*m维,1个样本,m维特征
    
    返回:
    y:预测值
    """
    y=np.matmul(self.w,x.T)+self.w0
    return y

然后为Iris数据集创建一个Iris类,用于产生5折验证所需要的数据,并且能产生不同样本数量的数据集。

# -*- coding: utf-8 -*-
"""
Author:CommissarMa
2018年5月23日 16点52分
"""
import numpy as np
import scipy.io as sio
 
 
class Iris(object):
  """Iris数据集
  参数:
  data:根据size裁剪出来的iris数据集
  size:每种类型的样本数量
  way:one against the rest || one against one
  
  注意:
  此处规定5折交叉验证(5-cv),所以每种类型样本的数量要是5的倍数
  多分类方式:one against the rest
  """
  
  def __init__(self,size=50,way="one against the rest"):
    """
    size:每种类型的样本数量
    """
    data=sio.loadmat("C:\\Users\\CommissarMa\\Desktop\\模式识别\\课件ppt\\PR实验内容\\iris_data.mat")
    iris_data=data['iris_data']#iris_data:原数据集,shape:150*4,1-50个样本为第一类,51-100个样本为第二类,101-150个样本为第三类
    self.size=size
    self.way=way
    self.data=np.zeros((size*3,4))
    for r in range(0,size*3):
      self.data[r]=iris_data[int(r/size)*50+r%size]
    
  
  def generate_train_data(self,index_fold,index_class,neg_class=None):
    """
    index_fold:5折验证的第几折,范围:0,1,2,3,4
    index_class:第几类作为正类,类别号:负类样本为-1,正类样本为1
    """
    if self.way=="one against the rest":
      fold_size=int(self.size/5)#将每类样本分成5份
      train_data=np.zeros((fold_size*4*3,4))
      label_data=np.full((fold_size*4*3),-1)
      for r in range(0,fold_size*4*3):
        n_class=int(r/(fold_size*4))#第几类
        n_fold=int((r%(fold_size*4))/fold_size)#第几折
        n=(r%(fold_size*4))%fold_size#第几个
        if n_fold<index_fold:
          train_data[r]=self.data[n_class*self.size+n_fold*fold_size+n]
        else:
          train_data[r]=self.data[n_class*self.size+(n_fold+1)*fold_size+n]
        
      label_data[fold_size*4*index_class:fold_size*4*(index_class+1)]=1
    elif self.way=="one against one":
      if neg_class==None:
        print("one against one模式下需要提供负类的序号!")
        return
      else:
        fold_size=int(self.size/5)#将每类样本分成5份
        train_data=np.zeros((fold_size*4*2,4))
        label_data=np.full((fold_size*4*2),-1)
        for r in range(0,fold_size*4*2):
          n_class=int(r/(fold_size*4))#第几类
          n_fold=int((r%(fold_size*4))/fold_size)#第几折
          n=(r%(fold_size*4))%fold_size#第几个
          if n_class==0:#放正类样本
            if n_fold<index_fold:
              train_data[r]=self.data[index_class*self.size+n_fold*fold_size+n]
            else:
              train_data[r]=self.data[index_class*self.size+(n_fold+1)*fold_size+n]
          if n_class==1:#放负类样本
            if n_fold<index_fold:
              train_data[r]=self.data[neg_class*self.size+n_fold*fold_size+n]
            else:
              train_data[r]=self.data[neg_class*self.size+(n_fold+1)*fold_size+n]
        label_data[0:fold_size*4]=1
    else:
      print("多分类方式错误!只能为one against one 或 one against the rest!")
      return
    
    return train_data,label_data
        
    
    
  def generate_test_data(self,index_fold):
    """生成测试数据
    index_fold:5折验证的第几折,范围:0,1,2,3,4
    
    返回值:
    test_data:对应于第index_fold折的测试数据
    label_data:类别号为0,1,2
    """
    fold_size=int(self.size/5)#将每类样本分成5份
    test_data=np.zeros((fold_size*3,4))
    label_data=np.zeros(fold_size*3)
    for r in range(0,fold_size*3):
      test_data[r]=self.data[int(int(r/fold_size)*self.size)+int(index_fold*fold_size)+r%fold_size]
    label_data[0:fold_size]=0
    label_data[fold_size:fold_size*2]=1
    label_data[fold_size*2:fold_size*3]=2
    
    return test_data,label_data

然后我们进行训练测试,先使用one against the rest策略:

# -*- coding: utf-8 -*-
 
from perceptron import Perceptron
from iris_data import Iris
import numpy as np
 
if __name__=="__main__":
   iris=Iris(size=50,way="one against the rest")
   
   correct_all=0
   for n_fold in range(0,5):
     p=[Perceptron(),Perceptron(),Perceptron()]
     for c in range(0,3):
       x,y=iris.generate_train_data(index_fold=n_fold,index_class=c)
       p[c].train(x,y)
     #训练完毕,开始测试
     correct=0
     x_test,y_test=iris.generate_test_data(index_fold=n_fold)
     num=len(x_test)
     for i in range(0,num):
       maxvalue=max(p[0].predict_value(x_test[i]),p[1].predict_value(x_test[i]),
          p[2].predict_value(x_test[i]))
       if maxvalue==p[int(y_test[i])].predict_value(x_test[i]):
         correct+=1
     print("错分数量:",num-correct,"错误率:",(num-correct)/num)
     correct_all+=correct
   print("平均错误率:",(num*5-correct_all)/(num*5))

然后使用one against one 策略去训练测试:

# -*- coding: utf-8 -*-
 
from perceptron import Perceptron
from iris_data import Iris
import numpy as np
 
if __name__=="__main__":
   iris=Iris(size=10,way="one against one")
   
   correct_all=0
   for n_fold in range(0,5):
     #训练
     p01=Perceptron()#0类和1类比较的判别器
     p02=Perceptron()
     p12=Perceptron()
     x,y=iris.generate_train_data(index_fold=n_fold,index_class=0,neg_class=1)
     p01.train(x,y)
     x,y=iris.generate_train_data(index_fold=n_fold,index_class=0,neg_class=2)
     p02.train(x,y)
     x,y=iris.generate_train_data(index_fold=n_fold,index_class=1,neg_class=2)
     p12.train(x,y)
     #测试
     correct=0
     x_test,y_test=iris.generate_test_data(index_fold=n_fold)
     num=len(x_test)
     for i in range(0,num):
       vote0=0
       vote1=0
       vote2=0
       if p01.predict_value(x_test[i])>0:
         vote0+=1
       else:
         vote1+=1
       if p02.predict_value(x_test[i])>0:
         vote0+=1
       else:
         vote2+=1
       if p12.predict_value(x_test[i])>0:
         vote1+=1
       else:
         vote2+=1
       
       if vote0==max(vote0,vote1,vote2) and int(vote0)==int(y_test[i]):
         correct+=1
       elif vote1==max(vote0,vote1,vote2) and int(vote1)==int(y_test[i]):
         correct+=1
       elif vote2==max(vote0,vote1,vote2) and int(vote2)==int(y_test[i]):
         correct+=1
     print("错分数量:",num-correct,"错误率:",(num-correct)/num)
     correct_all+=correct
   print("平均错误率:",(num*5-correct_all)/(num*5))

实验结果如图所示:

python实现感知器算法(批处理)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python解析xml中dom元素的方法
Mar 12 Python
使用Python制作获取网站目录的图形化程序
May 04 Python
浅谈五大Python Web框架
Mar 20 Python
详解python中asyncio模块
Mar 03 Python
浅谈解除装饰器作用(python3新增)
Oct 15 Python
python自定义线程池控制线程数量的示例
Feb 22 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
May 05 Python
python 动态调用函数实例解析
Oct 21 Python
Python基于进程池实现多进程过程解析
Apr 30 Python
Python基于smtplib协议实现发送邮件
Jun 03 Python
详解Anaconda 的安装教程
Sep 23 Python
python 常见的反爬虫策略
Sep 27 Python
python实现多层感知器
Jan 18 #Python
python实现多层感知器MLP(基于双月数据集)
Jan 18 #Python
基于python实现KNN分类算法
Apr 23 #Python
python实现定时发送qq消息
Jan 18 #Python
如何在Django中设置定时任务的方法示例
Jan 18 #Python
Python设计模式之工厂方法模式实例详解
Jan 18 #Python
Python设计模式之原型模式实例详解
Jan 18 #Python
You might like
用PHP编写和读取XML的几种方式
2013/01/12 PHP
深入理解PHP内核(一)
2015/11/10 PHP
php微信开发自定义菜单
2016/08/27 PHP
PHP使用文件锁解决高并发问题示例
2018/03/29 PHP
jquery的ajax跨域请求原理和示例
2014/05/08 Javascript
Javascript 字符串模板的简单实现
2016/02/13 Javascript
jQuery中通过ajax的get()函数读取页面的方法
2016/02/29 Javascript
针对后台列表table拖拽比较实用的jquery拖动排序
2016/10/10 Javascript
js HTML5上传示例代码完整版
2016/10/10 Javascript
Ajax和Comet技术总结
2017/02/19 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
2017/02/27 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
[11:33]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第二场
2018/04/06 DOTA
[01:19:46]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
Python利用IPython提高开发效率
2016/08/10 Python
pyside+pyqt实现鼠标右键菜单功能
2020/12/08 Python
python socket 聊天室实例代码详解
2019/11/14 Python
Python 元组拆包示例(Tuple Unpacking)
2019/12/24 Python
pyqt5数据库使用详细教程(打包解决方案)
2020/03/25 Python
Python web如何在IIS发布应用过程解析
2020/05/27 Python
matlab、python中矩阵的互相导入导出方式
2020/06/01 Python
HTML5 Canvas入门学习教程
2016/03/17 HTML / CSS
银行实习生的自我评价
2014/01/13 职场文书
村官工作鉴定评语
2014/01/27 职场文书
日本语毕业生自荐信
2014/02/01 职场文书
代办委托书怎么写
2014/08/01 职场文书
关于读书的活动方案
2014/08/14 职场文书
交通事故死亡赔偿协议书
2014/12/03 职场文书
2014年外贸业务员工作总结
2014/12/11 职场文书
2015年煤矿工作总结
2015/04/28 职场文书
让生命充满爱观后感
2015/06/08 职场文书
2015年小学生国庆节演讲稿
2015/07/30 职场文书
2016年第32个教师节红领巾广播稿
2015/12/18 职场文书
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫