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基于queue和threading实现多线程下载实例
Oct 08 Python
Python转换HTML到Text纯文本的方法
Jan 15 Python
利用Python的Twisted框架实现webshell密码扫描器的教程
Apr 16 Python
python类和继承用法实例
Jul 07 Python
win与linux系统中python requests 安装
Dec 04 Python
python类的继承实例详解
Mar 30 Python
Python3爬楼梯算法示例
Mar 04 Python
Python函数和模块的使用总结
May 20 Python
django多文件上传,form提交,多对多外键保存的实例
Aug 06 Python
使用Python实现画一个中国地图
Nov 23 Python
tensorflow pb to tflite 精度下降详解
May 25 Python
Django集成富文本编辑器summernote的实现步骤
May 31 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仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
兼容ie6浏览器的php下载文件代码分享
2014/07/14 PHP
Laravel框架中实现使用阿里云ACE缓存服务
2015/02/10 PHP
laravel学习教程之存取器
2016/07/30 PHP
PHP实现通过strace定位故障原因的方法
2018/04/29 PHP
JS写的数字拼图小游戏代码[学习参考]
2008/10/29 Javascript
lyhucSelect基于Jquery的Select数据联动插件
2011/03/29 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
2013/05/08 Javascript
js控制web打印(局部打印)方法整理
2013/05/29 Javascript
jquery win 7透明弹出层效果的简单代码
2013/08/06 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
如何将php数组或者对象传递给javascript
2014/03/20 Javascript
JavaScript、jQuery与Ajax的关系
2016/01/24 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
2016/02/29 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
JavaScript实现的浏览器下载文件的方法
2017/08/09 Javascript
vue学习教程之带你一步步详细解析vue-cli
2017/12/26 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
vue组件之间通信方式实例总结【8种方式】
2019/02/22 Javascript
Python中处理字符串的相关的len()方法的使用简介
2015/05/19 Python
python遍历序列enumerate函数浅析
2017/10/17 Python
详解python使用Nginx和uWSGI来运行Python应用
2018/01/09 Python
python对离散变量的one-hot编码方法
2018/07/11 Python
对Python 窗体(tkinter)文本编辑器(Text)详解
2018/10/11 Python
python读取Excel表格文件的方法
2019/09/02 Python
150行Python代码实现带界面的数独游戏
2020/04/04 Python
解决Keras使用GPU资源耗尽的问题
2020/06/22 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
2020/11/11 Python
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
春节联欢晚会主持词范文
2014/03/24 职场文书
学生退学证明
2015/06/23 职场文书
导游词书写之黄山
2019/08/06 职场文书
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python
Python绘画好看的星空图
2022/03/17 Python