感知机的对偶形式 @ 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()

感知机的对偶形式 @ Python_第1张图片

你可能感兴趣的:(统计学习方法)