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常规方法实现数组的全排列
Mar 17 Python
微信跳一跳自动运行python脚本
Jan 08 Python
Python爬虫信息输入及页面的切换方法
May 11 Python
Pandas过滤dataframe中包含特定字符串的数据方法
Nov 07 Python
在Pandas中给多层索引降级的方法
Nov 16 Python
Django 日志配置按日期滚动的方法
Jan 31 Python
Python读取实时数据流示例
Dec 02 Python
pytorch实现mnist数据集的图像可视化及保存
Jan 14 Python
keras 特征图可视化实例(中间层)
Jan 24 Python
Python selenium模块实现定位过程解析
Jul 09 Python
pyx文件 生成pyd 文件用于 cython调用的实现
Mar 04 Python
Python中的套接字编程是什么?
Jun 21 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中的 == 运算符进行字符串比较
2006/11/26 PHP
PHP实现MySQL更新记录的代码
2008/06/07 PHP
ThinkPHP中limit()使用方法详解
2016/04/19 PHP
详解thinkphp中的volist标签
2018/01/15 PHP
PHP实现QQ登录的开原理和实现过程
2018/02/04 PHP
Javascript与flash交互通信基础教程
2008/08/07 Javascript
jQuery ui 1.7更新小结
2009/08/15 Javascript
超级酷和最实用的jQuery实例收集(20个)
2010/04/21 Javascript
阻止子元素继承父元素事件具体思路及实现
2013/05/02 Javascript
jQuery插件Elastislide实现响应式的焦点图无缝滚动切换特效
2015/04/12 Javascript
jQuery聚合函数实例
2015/05/21 Javascript
javascript组合使用构造函数模式和原型模式实例
2015/06/04 Javascript
jQuery简单实现仿京东商城的左侧菜单效果代码
2015/09/09 Javascript
详解js中call与apply关键字的作用
2016/11/21 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
2017/08/02 Javascript
AngularJS集合数据遍历显示的实例
2017/12/27 Javascript
vue2.0 + element UI 中 el-table 数据导出Excel的方法
2018/03/02 Javascript
详解基于Node.js的HTTP/2 Server实践
2018/05/31 Javascript
ajax跨域访问遇到的问题及解决方案
2019/05/23 Javascript
[01:15]PWL S2开团时刻第二期——他们杀 我就白给
2020/11/25 DOTA
[43:26]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第二场 11.20
2020/11/23 DOTA
利用Python获取赶集网招聘信息前篇
2016/04/18 Python
用 Python 连接 MySQL 的几种方式详解
2018/04/04 Python
Python matplotlib修改默认字体的操作
2020/03/05 Python
Pycharm插件(Grep Console)自定义规则输出颜色日志的方法
2020/05/27 Python
Python flask路由间传递变量实例详解
2020/06/03 Python
详解Python 循环嵌套
2020/07/09 Python
使用HTML和CSS3绘制基本卡通图案的示例分享
2015/11/06 HTML / CSS
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
艺术家策划的室内设计:Curious Egg
2019/03/06 全球购物
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
中层竞聘演讲稿
2014/01/09 职场文书
2014年教师业务学习材料
2014/05/12 职场文书
优秀的应届生自荐信
2014/05/23 职场文书
先进工作者推荐材料
2014/12/23 职场文书
Java数据结构之链表相关知识总结
2021/06/18 Java/Android