perceptron implementation and evaluation ( 感知机python实现及评估)

note:

  • 一次只训练一个数据 (Online Learning)
    • Online Learning: 能够根据线上反馈数据,实时快速地进行模型调整,使得模型及时反映线上的变化,提高线上预测的准确率
    • 对应的是batch learning: 是一种离线的学习方法,一次性将batch大小的批量数据输入到学习算法中。
  • 只有当数据被错误分类时,才会对该数据进行学习 (Error-driven learning)
  • 对数据集训练循环多次,直到收敛(收敛指没有数据再被错误分类,weight 值 和 bias 值都不会再发生变化)
  • 每个训练循环(iteration)前,都要打乱数据的顺序(shuffle)
  • 线性可分(linearly separable),如果数据集里的数据可以被一条直线(hyperplane)正确的分成两类,我们就说这个数据集是线性可分的。否则,数据集线性不可分(nonlinearly separable)
  • 分类线(hyperplane)其实并不是唯一的
  • 最终训练出的weight 受最后一个数据的影响特别大,所以会采用一个升级版算法“averaged preception algorithm),它将训练过程中的weight和bias求平均值,作为最终的weight。 或者 (每个iteration都收敛的情况下)平均每个iteration的算出的weight和bias,当然每个iteration学习之前,都要重新打乱(shuffle)数据。

伪代码(pseudo code)

在这里插入图片描述

  • a : activation
  • y: 标签值(label), 1 或 -1
  • 当 y * a <= 0 时,说明,预测值与标签值相背,分类错误,此时需要对该数据进行学习
    学习时,更新weight 和 bias
  • 对数据集训练循环多次,直到收敛(收敛指没有数据再被错误分类,weight 值 和 bias 值都不会再发生变化)
  • learn:
    在这里插入图片描述
    在这里插入图片描述

Hyperplane

不是weight 向量那条线分类,是w1x1 + w2 * x2 + … + wnxn 这条线作为hyperplane分类,weight 向量和hyperplane 是垂直的。
在这里插入图片描述


code

代码是我coursework的代码,我还没来得及标准化这个代码
但是可以看出大概意思,我有空再整理啦
有小伙伴要我数据集和coursework题目的,可以留言给我

from google.colab import files
import io
import numpy as np
import pandas as pd


class Preprocess(object):

  #extract data base on class labels and pre-process data
  def filtAndShuf(self, allData, filterclass):   
    #delet the data with the last class label       
    delClassIndex = np.where(allData[:,4]==filterclass[-1])   
    data = np.delete(allData, delClassIndex, axis=0)   

    #Replaces the class name of the string in the first column of the parameters with the numeric 1
    data[data==filterclass[0]] = 1     

    #Replaces the class name of the string in the rest column(s) of the parameters with the numeric -1
    data[:,4][data[:,4]!=1] = -1    

    #shuffle the data, let them order randomly 
    np.random.shuffle(data)  

    #split the data into two: the feature data and the label data  
    x,y = np.split(data,[4],axis=1)

    #inset a column to x with value equal to 1 corresponding to the bias column as the w0
    x=np.insert(x, 0, values=np.ones(x.shape[0]), axis=1)
    y = y[:,0]      
    return(x,y)


class Perceptron(object): 

  def updateWeight(self, x, y, w, λ, eta):  
    incorCount = 0           
    for i in range(x.shape[0]):     

      #calculate the action value
      a = np.dot(w, x[i,:]) 

      #detect if the instance is incorrectly classified
      if a*y[i] <= 0:         

        #update the weight, eta is learning rate,  the λ is the regularisation coefficient
        w = w + eta * y[i] * x[i,:] - eta * λ * w   

        #count the number of misclassified instance
        incorCount += 1  

    #calculate the accuracy     
    accuracy = 1- incorCount / x.shape[0]          
    return(w, incorCount, accuracy) 



if __name__ == '__main__':

################################################################################
###                         parameters preparation                           ###
################################################################################

  preprocess = Preprocess()
  perceptron = Perceptron()

  #import data
  uploaded = files.upload()
  trainData = pd.read_csv(io.BytesIO(uploaded['train.data']),header=None)
  testData = pd.read_csv(io.BytesIO(uploaded['test.data']),header=None)

  trainData = np.array(trainData)
  testData = np.array(testData)

  #names for the three classifiers, which can makes print convenient
  classifierName = np.array([['1-vs-2', '1-vs-3', '2-vs-3'], 
                             ['1-vs-rest','2-vs-rest','3-vs-rest']])
  
  #indicate how to process the three binary classfiers, the last class(column) will be deleted
  #the first two columns will be labeled as 1 and -1 respectively
  binaryClass = np.array([['class-1','class-2','class-3'],                            
                          ['class-1','class-3','class-2'],
                          ['class-2','class-3','class-1']])
  
  #indicate how to process the three multi-classifiers, the last class(column) will be deleted
  #the first class(column) will be labeled as 1, the  middle two classes(columns) will be labeled as -1
  multiClass = np.array([['class-1', 'class-2', 'class-3', 'None'],                                 ['class-2', 'class-1', 'class-3', 'None'],
                         ['class-3', 'class-1', 'class-2', 'None']])
  
  dataName = np.array(['trainData', 'testData'])
  data = np.array([trainData, testData])

################################################################################
###                  Answers to  Question 3                                  ###
################################################################################
  print('\nQuestion 3, Binary classifier training') 
  
  finalWeight = np.zeros([3, 5], dtype=float)
  
  for k in range(3):  # 3 classifiers
    #initial the weights for each iteration
    weight=np.zeros((20,5),dtype=float)
  
    for i in range(20):  # 20 iteration

      #extract and pre-process the data for the binary classifier training
      x, y = preprocess.filtAndShuf(trainData, binaryClass[k,:])   

      #record the weight after each iteration training
      weight[i,:], incorCount, accuracy = perceptron.updateWeight(x, y, weight[i,:], 0, 1)

    #the final weights for the three 
    finalWeight[k,:] = np.sum(weight, axis=0) / weight.shape[0]  
    print(classifierName[0,k], 'weight =', np.around(finalWeight[k,[1,2,3,4]], decimals=2),\
          ' bias =', np.around(finalWeight[k,0], decimals=2)) 


################################################################################
###                  Answers to  Question 4                                  ###
################################################################################
  print('\nQuestion 4, Binary classification accuracy') 

  for k in range(3):  # 3 classifiers
    for i in range(2):  # 2 dataset
      x,y = preprocess.filtAndShuf(data[m], binaryClass[k,:]) 
      finalWeight[k,:], incorCount, accuracy = perceptron.updateWeight(x, y, finalWeight[k,:], 0, 0)
      print(dataName[i],':    incorrect number =', incorCount, '    accuracy =', round(accuracy,2))


################################################################################
###                  Answers to  Question5                                   ###
################################################################################
  print('\nQuestion 5, the most discriminative feature') 
  
  for i in range(1,5):
    weight=np.zeros(2,dtype=float)
    x,y = preprocess.filtAndShuf(trainData, binaryClass[1,:])
    weight, incorCount, accuracy = perceptron.updateWeight(x[:,[0,i]], y, weight, 0, 1)
    print('the feature ',i , 'is converged after', incorCount,'updates')


################################################################################
###                  Answers to  Question6                                   ###
################################################################################
  print('\n\nQuestion 6, multi-class classifier training and their accuracy') 

  finalWeight = np.zeros(5, dtype=float)
  for k in range(3):  # 3 classifier
    weight=np.zeros((20,5),dtype=float)
          
    for i in range(20):  # 20 iteration
      x, y = preprocess.filtAndShuf(trainData, multiClass[k,:])    
      weight[i,:], incorCount, accuracy = perceptron.updateWeight(x, y, weight[i,:], 0, 1)
    finalWeight = np.sum(weight, axis=0) / weight.shape[0]  
    print('\nmulti-class',classifierName[1,k], '\n   weight =', np.around(finalWeight[[1,2,3,4]], decimals=2),\
          ' bias =', np.around(finalWeight[0], decimals=2)) 

    for j in range(2):  # 2 dataset
      x,y = preprocess.filtAndShuf(data[j], multiClass[k,:])  
      finalWeight, incorCount, accuracy = perceptron.updateWeight(x, y, finalWeight, 0, 0)
      print('  ',dataName[j],':    incorrect number =', incorCount, '    accuracy =', round(accuracy,2))

  

################################################################################
###                  Answers to  Question7                                   ###
################################################################################
  print('\n\nQuestion 7, l2 regularisation')   
  λ = np.array([0.01, 0.1, 1.0, 10.0, 100.0])  # 5 regularisation coefficient
  eta = np.array([1, 1, 1, 0.1, 0.01])    #learning rate

  for k in range(3):  # 3 classifier
    print('\nmulti-class', classifierName[1,k])
    finalWeight = np.zeros(5, dtype=float)
       
    for j in range(5):  # 5 regularisation coefficient
      weight=np.zeros((20,5),dtype=float)

      for i in range(20):  # 20 iteration
        x, y = preprocess.filtAndShuf(trainData, multiClass[k,:])    # binaryClass[k,:] //  multiClass[k,:]
        weight[i,:], incorCount, accuracy = perceptron.updateWeight(x, y, weight[i,:], λ[j], eta[j])
      finalWeight = np.sum(weight, axis=0) / weight.shape[0]  
      print('\nλ =', λ[j],', weight =', np.around(finalWeight[[1,2,3,4]], decimals=2),\
            ' bias =', np.around(finalWeight[0], decimals=2)) 


      for m in range(2):  # 2 dataset
          x,y = preprocess.filtAndShuf(data[m], multiClass[k,:])  # binaryClass[k,:] //  multiClass[k,:]
          finalWeight, incorCount, accuracy = perceptron.updateWeight(x, y, finalWeight, 0, 0)
          print('           ',dataName[m],'accuracy:  incorrect number =',\
                incorCount, '  accuracy =', round(accuracy,2))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Enzo 想砸电脑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值