统计学习方法第2章 感知机 Python实现

最近开始复习李航的统计学习方法啦,所以通过博客的形式系统整理所学并督促自己,重心主要放在算法的Python实现上,基础知识的介绍可能相对简洁一点,第一次发,以后在内容和格式上都会慢慢改进.

2.1 感知机原理

2.1.1 感知机的模型定义

感知机是二类分类的线性分类模型,参考书上的定义即可,简洁明了,其输入为实例的特征向量,输出为实例的类别,取+1和-1二值. 感知机属于判别模型,其学习旨在求出将训练数据进行线性划分的分离超平面.
在这里插入图片描述

2.1.2 感知机的学习策略

感知机的学习策略需要一个假设前提,即训练数据集是线性可分的,数据集的线性可分性可以简单归纳为:存在某个形如 w ⋅ x + b = 0 w·x+b=0 wx+b=0的超平面 S S S,能够将数据集的正实例点和负实例点完全正确地划分到超平面的两侧.

所谓确定一个学习策略,即定义(经验)损失函数并将损失函数极小化,感知机所采用的损失函数是误分类点到超平面 S S S的总距离. 制定学习策略的步骤如下:
(1) 写出输入空间Rn中任意点 x i x_i xi到超平面 S S S的距离 1 ∥ w ∥ ∣ w ⋅ x 0 + b ∣ \frac{1}{\parallel w \parallel} \mid w·x_0+b \mid w1wx0+b这里 ∥ w ∥ \parallel w \parallel w w w w L 2 L_2 L2范数.
(2) 对于误分类的数据 ( x i , y i ) (x_i,y_i) (xi,yi),则有 − y i ( w ⋅ x i + b ) > 0 -y_i(w·x_i+b)>0 yi(wxi+b)>0成立,因此误分类点 x i x_i xi到超平面 S S S的距离是 − 1 ∥ w ∥ y i ( w ⋅ x i + b ) -\frac{1}{\parallel w \parallel} y_i(w·x_i+b) w1yi(wxi+b)不考虑 1 ∥ w ∥ \frac{1}{\parallel w \parallel} w1,就得到感知机学习的损失函数.
(3) 给定训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T=\{ (x_1,y_1),(x_2,y_2),...,(x_N,y_N) \} T={(x1,y1),(x2,y2),...,(xN,yN)}感知机学习的经验风险函数为 L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) L(w,b)=-\displaystyle\sum_{x_i \in M}y_i(w·x_i+b) L(w,b)=xiMyi(wxi+b)其中 M M M为误分类点的集合.

2.1.3 感知机学习算法

感知机的学习算法包含了原始形式和对偶形式两种,分别定义如下:在这里插入图片描述在这里插入图片描述

2.2 感知机Python实现

本章的习题描述极为简单,那么我就使用Python实现本章对应感知机原始形式与对偶形式的两个例题:例2.1、例2.2. 废话不多说,直接贴代码会更加简洁直观.

2.2.1 原始形式Python代码

# -*- coding: utf-8 -*-
# 感知机的原始形式
 
import numpy as np
import matplotlib.pyplot as plt
 
class Perceptron(object):
    def __init__(self,eta=1,iter=50):
        # eta:学习率;itea:最大迭代次数
        self.eta = eta
        self.iter = iter
 
    # 根据现有权值和偏置预测分类
    def predict(self,xi,w,b):
        target = np.dot(w,xi)+b
        return target
 
    # 迭代修正权值和偏置
    def interation(self,vector,label):
        """
        input:
        param vector: 训练数据向量
        param label: 训练数据的原始划分类别
        return:
        weight and bias: 学习到的权值与偏置
        """
 
        data_shape = vector.shape
        print("data_shape",data_shape)
        # 初始化权值为零向量
        self.weight = np.zeros(data_shape[1])
        # 初始偏置
        self.bias = 0
        # 记录每一轮迭代还没有误分类数据
        errors_point = 0
        # True表示还需要继续迭代
        check_inter = True
        n = 0
        print("迭代次数:%d , 初始权值:%s , 初始偏置:%s" % (n,str(self.weight), str(self.bias)))
        while check_inter and n<self.iter:
            n +=1
            errors_point = 0
            for xi,yi in zip(vector,label):
                xi_prediction = self.predict(xi,self.weight,self.bias)
                # 感知机中的判断数据有没有被误分类的公式
                if yi*xi_prediction <= 0:
                    # 修正权值和偏置
                    self.weight = self.weight+self.eta*xi*yi
                    self.bias = self.bias+self.eta*yi
                    errors_point +=1
                    print("迭代次数:%d , 误分类点:%s , 权值:%s , 偏置:%s" % (n,str(xi),str(self.weight),str(self.bias)))
                    break
            if errors_point:
                # 如果还存在误分类点,则继续迭代
                check_inter = True
            else:
                # 如果不存误分类点,则停止迭代
                check_inter = False
        print("权值:%s , 偏置:%s" % (str(self.weight),str(self.bias)))
        return self.weight,self.bias
        
    def plot_graph(self,vector,label,weight,bias):
        plt.figure()
        for i in range(len(vector)):
            if label[i] == 1:
                plt.plot(vector[i][0],vector[i][1],'ro')
            else:
                plt.plot(vector[i][0],vector[i][1],'bo')
                
        line_x = [0,10]
        line_y = [0,0]
        for j in range(len(line_x)):
            line_y[j] = (-weight[0]*line_x[j]-bias)/weight[1]
        plt.plot(line_x,line_y)
        plt.savefig("picture.jpg")
        

if __name__=="__main__":
    x1 = np.array([[3, 3], [4, 3], [1, 1]])
    x2 = np.array([1, 1, -1])
    perception = Perceptron()
    weight,bias = perception.interation(x1,x2)
    perception.plot_graph(x1,x2,weight,bias)

运行结果展示
在这里插入图片描述

2.2.2 对偶形式Python代码

# -*- coding: utf-8 -*-
# 感知机的对偶形式
 
import numpy as np
import matplotlib.pyplot as plt
 
class Perceptron_dual(object):
    def __init__(self,eta=1,iter=50):
        # eta:学习率;itea:最大迭代次数
        self.eta = eta
        self.iter = iter
 
    # 迭代修正权值和偏置
    def interation(self,vector,label):
        """
        input:
        param vector: 训练数据向量
        param label: 训练数据的原始划分类别
        return:
        alpha,weight and bias: 学习到的参数、权值与偏置
        """
 
        data_shape = vector.shape
        print("data_shape", data_shape)
        # 初始化权值参数为零向量
        self.alpha = np.zeros(data_shape[0])
        # 初始化权值为零向量
        self.weight = np.zeros(data_shape[1])
        # 初始偏置
        self.bias = 0
        # 计算Gram矩阵
        gram = np.matmul(vector,vector.T)
        # 记录每一轮迭代还没有误分类数据
        errors_point = 0
        # True表示还需要继续迭代
        check_inter = True
        n = 0
        print("迭代次数:%d , 初始参数:%s , 初始偏置:%s" % (n,str(self.alpha), str(self.bias)))
        while check_inter and n<self.iter:
            n +=1
            errors_point = 0
            for i in range(len(vector)):
                xi = vector[i]
                yi = label[i]
                tmp = 0
                for j in range(len(vector)):
                    tmp +=self.alpha[j]*label[j]*gram[i,j]
                tmp +=self.bias
                # 感知机中的判断数据有没有被误分类的公式
                if yi*tmp <= 0:
                    # 修正权值和偏置
                    self.alpha[i] = self.alpha[i]+self.eta
                    self.bias = self.bias+self.eta*yi
                    errors_point +=1
                    print("迭代次数:%d , 误分类点:%s , 参数:%s , 偏置:%s" % (n,str(xi),str(self.alpha),str(self.bias)))
                    break
            if errors_point:
                # 如果还存在误分类点,则继续迭代
                check_inter = True
            else:
                # 如果不存误分类点,则停止迭代
                check_inter = False
        for i in range(len(vector)):
            self.weight +=self.alpha[i]*vector[i]*label[i]
        print("权值:%s , 偏置:%s" % (str(self.weight),str(self.bias)))

        return self.alpha,self.weight,self.bias        
        
    def plot_graph(self,vector,label,weight,bias):
        plt.figure()
        for i in range(len(vector)):
            if label[i] == 1:
                plt.plot(vector[i][0],vector[i][1],'ro')
            else:
                plt.plot(vector[i][0],vector[i][1],'bo')
                
        line_x = [0,10]
        line_y = [0,0]
        for j in range(len(line_x)):
            line_y[j] = (-weight[0]*line_x[j]-bias)/weight[1]
        plt.plot(line_x,line_y)
        plt.savefig("picture.jpg")

if __name__=="__main__":
    x1 = np.array([[3, 3], [4, 3], [1, 1]])
    x2 = np.array([1, 1, -1])
    perception = Perceptron_dual()
    alpha,weight,bias = perception.interation(x1,x2)
    perception.plot_graph(x1,x2,weight,bias)

运行结果展示
在这里插入图片描述

最终的分类结果展示
在这里插入图片描述

在文章的最后,我想说明,代码中的感知机模块,不仅仅限于二维特征向量,不过画图函数可能无法实现更高维了.

参考博客:
https://blog.csdn.net/Big_Pai/article/details/88740612
https://blog.csdn.net/W_peijian/article/details/79098649
https://blog.csdn.net/winter_evening/article/details/70196040

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值