统计学习方法之感知机 python代码实现

感知机是二分类线性模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1。

根据《统计学习方法》第2章,用python实现感知机。

import numpy as np
import matplotlib.pyplot as plt


class Perceptron:

    def __init__(self, dim):
        """ 初始化权重 w b 以及x特征的维度dim"""
        self.w = np.random.random((dim,))
        self.b = np.random.rand()
        self.dim = dim

    def f(self, x):
        """ w * x + b"""
        return np.dot(self.w, x.T) + self.b

    def gw(self, x, y):
        """ w梯度 """
        return x * y

    def gb(self,  y):
        """ b梯度"""
        return y

    def train_2(self, xs, ys, alpha=1, max_step=1000):
        """
        学习算法的对偶形式
        """

        n = len(xs)
        matrix = np.zeros((n,n),dtype=int)
        for i in range(n):
            for j in range(n):
                matrix[i][j] = np.dot(xs[i],xs[j])
        print("matrix:", matrix)
        a, b = [0]*n, 0
        step = 1
        error = float("inf")
        while error and step < max_step:
            print("step: {}, error: {}".format(step, error))
            error = 0
            for i,(x, y) in enumerate(zip(xs, ys)):
                sum_ = b
                for j in range(n):
                    sum_ += a[j]*ys[j]*matrix[j][i]
                if y*sum_ <= 0:
                    a[i] = a[i] + alpha
                    b += alpha * y
                    error += 1
            step += 1
        self.w = sum(a[i]*xs[i]*ys[i] for i in range(n))
        self.b = b
        if step >= max_step:
            print("max_step limit")
        else:
            print("successfully learn")
        print("w: {} b: {}".format(self.w, self.b))

    def train(self, xs, ys, alpha=0.1, max_step=1000):
        """
        学习算法
        :param xs: 输入样本特征
        :param ys: 样本分类
        :param alpha: 学习率
        :param max_step: 最大迭代伦次
        :return:
        """
        # 输入数据维度要等于指定维度(画图只能是二维)
        if xs.shape[1] != self.dim:
            raise ValueError("x sample must {} dim".format(self.dim))

        # 初始化图
        fig = self.figure_init(xs, ys)

        error = float("inf")
        step = 1
        while error and step < max_step:
            print("step: {}, error: {}".format(step, error))
            error = 0
            for x, y in zip(xs, ys):
                if self.f(x) * y <= 0:
                    self.w += alpha * self.gw(x, y)
                    self.b += alpha * self.gb(y)
                    self.figure_update(fig)  # 更新图
                    error += 1
            step += 1
        if step >= max_step:
            print("max_step limit")
        else:
            print("successfully learn")
        print("w: {} b: {}".format(self.w, self.b))

        # 关闭交互模式
        plt.ioff()

        # 图形显示
        plt.show()

    def figure_init(self, xs, ys):

        fig = plt.figure(figsize=(8, 6), dpi=80)
        ax = fig.add_subplot(1, 1, 1)
        # 设定标题等
        plt.title("Perceptron")
        plt.grid(True)

        # 设置X轴
        plt.xlabel("x(1)")
        plt.xlim(-10, 10)

        # 设置Y轴
        plt.ylabel("x(2)")
        plt.ylim(-10, 10)

        # 画点
        for x_, y_ in zip(xs, ys):
            if y_ == 1:
                ax.plot(x_[0], x_[1], "ro")
            else:
                ax.plot(x_[0], x_[1], "go")

        # 生成超平面 w1 * x1 + w2 * x2 + b = 0,随机取两个x1,计算x2连起来
        x1 = np.linspace(-10, 10, 2, endpoint=True)
        x2 = (- self.b - self.w[0] * x1) / self.w[1]

        # 画直线
        lines = ax.plot(x1, x2, "b-", linewidth=2.0, label="hyperplane")

        # 设置图例位置,loc可以为[upper, lower, left, right, center]
        ax.legend(loc="upper left", shadow=True)

        # 暂停
        plt.pause(0.5)

        ax.lines.remove(lines[0])
        # 打开交互模式
        plt.ion()

        return ax

    def figure_update(self, ax):
        """
        画图程序,每更新一次权重,调用一次
        """
        # 生成超平面 w1 * x1 + w2 * x2 + b = 0,随机取两个x1,计算x2连起来
        x1 = np.linspace(-10, 10, 2, endpoint=True)
        x2 = (- self.b - self.w[0]*x1)/self.w[1]

        # 更新直线
        lines = ax.plot(x1, x2, "b-", linewidth=2.0, label="hyperplane")
        # 暂停
        plt.pause(0.5)

        # 删掉直线
        ax.lines.remove(lines[0])


p = Perceptron(2)
x_data = np.array([[3, 3], [4, 3], [1, 1]])
y_data = np.array([1, 1, -1])
p.train(x_data, y_data)
# p.train_2(x_data, y_data)
其中,train函数是学习算法的原始形式,train_2是学习算法的对偶形式。其中error代表误分类的个数,简单的逻辑就是,当误分类的个数为0或者超出最大学习轮次则停止学习。
另外,figrue_init 和 figure_update函数则是在训练过程的图形展示。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【为什么要学习这门课程】深度学习框架如TensorFlow和Pytorch掩盖了深度学习底层实现方法,那能否能用Python代码从零实现学习深度学习原理呢?本课程就为大家提供了这个可能,有助于深刻理解深度学习原理。左手原理、右手代码,双管齐下!本课程详细讲解深度学习原理并进行Python代码实现深度学习网络。课程内容涵盖感知机、多层感知机、卷积神经网络、循环神经网络,并使用Python 3及Numpy、Matplotlib从零实现上述神经网络。本课程还讲述了神经网络的训练方法与实践技巧,且开展了代码实践演示。课程对于核心内容讲解深入细致,如基于计算图理解反向传播算法,并用数学公式推导反向传播算法;另外还讲述了卷积加速方法im2col。【课程收获】本课程力求使学员通过深度学习原理、算法公式及Python代码的对照学习,摆脱框架而掌握深度学习底层实现原理与方法。本课程将给学员分享深度学习Python实现代码。课程代码通过Jupyter Notebook演示,可在Windows、ubuntu等系统上运行,且不需GPU支持。【优惠说明】 课程正在优惠中!  备注:购课后可加入白勇老师课程学习交流QQ群:957519975【相关课程】学习本课程的前提是会使用Python语言以及Numpy和Matplotlib库。相关课程链接如下:《Python编程的术与道:Python语言入门》https://edu.csdn.net/course/detail/27845《玩转Numpy计算库》https://edu.csdn.net/lecturer/board/28656《玩转Matplotlib数据绘图库》https://edu.csdn.net/lecturer/board/28720【课程内容导图及特色】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值