感知机的对偶形式 @ Python

感知机的对偶形式 @ Python

  • 在感知机的原始形式当中, 我们会发现有的点成为误分类点的次数不止一次,每次计算的过程没有任何变化, 对于点 (xi,yi) 来说, 到目前为止作为误分类点的次数为 ni , 对于 w 的影响是niηxiyi,, 如果一直都是真确的分类点的话, ni=0 , 对于 w 的影响就为0, 所以可以推导出
    • w=i=1Nniηxiyi
    • b=i=1Nniηyi
    • 假设当前的权重为 wk ,偏置项为 bk , 若 (x5,y5) 是未分类点的话, 那么 wk=i=1Nniηxiyi 中的 n5=n5+1 , 我们将 αi=niη , 我们只需要使得 α5=α5+η
      同理, 可以求得 bk=bk+ηyi
    • yi(j=1Nαjyjxjxi+b)0 时, (xi,yi) 属于误分类点
      • αi=αi+η
      • b=b+ηyi
    • 显然每次判断是否为误分类点的时候我们都需要 ixj , 这些东西要重复使用,所以事先计算内积得到Gram矩阵, 然后直接使用矩阵, 可以提高算法的速度
    • 代码实现
    • # _*_ coding:utf-8 _*_
      import numpy as np
      import matplotlib.pyplot as plt
      
      
      class Perceptron:
          def __init__(self, x, y=1):
              self.x = x
              self.y = y
              self.alpha = np.zeros((self.x.shape[0], 1))
              self.b = 0.0  # 偏置项
              self.a = 1  # 改变此处可以得到不同的平面
      
              # 创建gram矩阵
              self.m = np.zeros((self.x.shape[0], self.x.shape[0]))
              for i in range(x.shape[0]):
                  for j in range(x.shape[0]):
                      self.m[i][j] = np.dot(x[i:], x[j:].T)[0][0]
      
          def train(self):
              length = self.x.shape[0]
              while True:
                  count = 0  # 记录误分类点的数目
                  for i in range(length):
                      # 对矩阵进行运算
                      y = np.dot(self.m[i], self.a * self.alpha * self.y) + self.b
                      # 如果是误分类点, 0 恰好在平面上
                      if y * self.y[i] <= 0:
                          self.alpha[i] = self.alpha[i] + 1
                          self.b = self.b + self.a * self.y[i]
                          count += 1
                  if count == 0:
                      return np.sum(self.x * self.alpha * self.y, axis=0), self.b
      
      
      class ShowPicture:
          def __init__(self, x, y, w, b):
              self.b = b
              self.w = w
              plt.figure(1)
              plt.title('what the fuck', size=14)
              plt.xlabel('x-axis', size=14)
              plt.ylabel('y-axis', size=14)
      
              xData = np.linspace(0, 5, 100)  # 创建等差数组
              yData = self.expression(xData)
              plt.plot(xData, yData, color='r', label='y1 data')
      
              # 绘制散点图
              for i in range(x.shape[0]):
                  if y[i] < 0:
                      plt.scatter(x[i][0], x[i][1], marker='x', s=50)
                  else:
                      plt.scatter(x[i][0], x[i][1], s=50)
              plt.savefig('2d.png', dpi=75)
      
          def expression(self, x):
              y = (-self.b - self.w[0] * x) / self.w[1]
              return y
      
          def show(self):
              plt.show()
      
      
      xArray = np.array([[3, 3], [4, 3], [1, 1]])
      yArray = np.array([[1], [1], [-1]])
      # [[3 3]
      # [4 3]
      # [1 1]]
      p = Perceptron(x=xArray, y=yArray)
      w, b = p.train()
      print w, b
      s = ShowPicture(x=xArray, y=yArray, w=w, b=b)
      s.show()
      

      这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值