感知机原理介绍与python实现

1. 引言

    感知机是1957年由Rosenblatt提出的一个线性分类模型,对应与输入空间(特征空间)中将实例分为正负两类的分离超平面,属于判别模型中的一种,也是神经网络和支持向量机的基础。原始论文的地址如下:

    下面将具体介绍一下感知机模型的原理,并利用python来实现它。 

2. 感知机原理介绍

2.1 模型的定义

    假设输入空间(特征空间)为\mathcal { X } \subseteq \mathbf { R } ^ { n },输出空间为\mathcal { Y } = \{ + 1 , - 1 \}x,y分别对应一个实例的特征向量和标签,则感知机的计算公式如下:

                                                        f ( x ) = \operatorname { sign } ( w \cdot x + b )    

 其中,w,b分别为感知机模型的权重和偏置,sign为符号函数,其表达式如下:

                                                        \operatorname { sign } ( x ) = \left\{ \begin{array} { l l } { + 1 , } & { x \geqslant 0 } \\ { - 1 , } & { x < 0 } \end{array} \right.

    感知机有如下的几何解释:线性方程

                                                        w \cdot x + b = 0 

对应于特征空间\mathbf { R } ^ { n }中的一个超平面\mathbf { S },其中,w,b分别对应超平面的法向量和截距,这个超平面刚好将特征空间分为正负类两部分,如图1所示,因此,感知机其实就是一个分离超平面。

图1 感知机模型

2.2  模型的损失函数

    感知机的损失函数采用的是误分类点到超平面S的总距离,我们知道,对于输入空间\mathbf { R } ^ { n }中任一点x _ { 0 }到超平面S的距离为:

                                                         \frac { 1 } { \| w \| } \left| w \cdot x _ { 0 } + b \right|

 其中,\| w \|wL_2范数。对于误分类的数据\left( x _ { i } , y _ { i } \right)来说,有:

                                                         - y _ { i } \left( w \cdot x _ { i } + b \right) > 0

因此,误分类点x _ { i }到超平面S的距离为:

                                                         - \frac { 1 } { \| w \| } y _ { i } \left( w \cdot x _ { i } + b \right)

不考虑\frac { 1 } { \| w \| },就可以得到感知机模型的损失函数。

    给定训练数据集T = \left\{ \left( x _ { 1 } , y _ { 1 } \right) , \left( x _ { 2 } , y _ { 2 } \right) , \cdots , \left( x _ { N } , y _ { N } \right) \right\},其中,x _ { i } \in \mathcal { X } = \mathbf { R } ^ { n }y _ { i } \in \mathcal { Y } = \{ + 1 , - 1 \}i = 1,2 , \cdots , N,则感知机的损失函数为:

                                                        L ( w , b ) = - \sum _ { x _ { i } \in M } y _ { i } \left( w \cdot x _ { i } + b \right)

其中,M为误分类点的集合。因此,当存在误分类点时,损失函数是非负的,当不存在误分类点时,则损失函数为0。

2.感知机的python实现

    python中sklearn已经集成了感知机模型,因此,本文直接调用python中的sklearn来实现感知机模型,数据集选用的是经典的iris鸢尾花数据集,由于iris鸢尾花数据集有三种类别,因此,只选取其中两类作为训练集。代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron


def load_data():
    """
    加载iris模型,只选择其中两类作为训练集
    :return: 
    """
    iris = load_iris()
    iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
    iris_df['label'] = iris.target
    iris_df = iris_df[(iris_df['label'] != 2)]
    iris_df['label'][(iris_df['label'] == 0)] = -1
    return iris_df


def plot_perceptron(data, model):
    """
    绘制感知机模型
    :param data: 训练数据. [dataframe]
    :param model: 训练好的模型. [model]
    :return: 
    """
    plt.plot(data.iloc[:, 0][(data['label'] == -1)], data.iloc[:, 1][(data['label'] == -1)], 'bo', color='blue',
             label='0')
    plt.plot(data.iloc[:, 0][(data['label'] == 1)], data.iloc[:, 1][(data['label'] == 1)], 'bo', color='orange',
             label='1')
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend()

    x_ponits = np.arange(4, 8)
    y_ = -(model.coef_[0][0] * x_ponits + model.intercept_) / model.coef_[0][1]
    plt.plot(x_ponits, y_)
    plt.show()


def main():
    iris_df = load_data()
    clf = Perceptron(fit_intercept=False, max_iter=1000, shuffle=False)
    clf.fit(iris_df.iloc[:, [0, 1]], iris_df.iloc[:, -1])
    plot_perceptron(iris_df, clf)


if __name__ == '__main__':
    main()

    最终获得的感知机模型对iris数据集的划分如图2所示,发现最终感知机只对一个样本出现了误判。

图2 感知机模型对iris数据集的划分

3.模型总结 

    通过前文的介绍可以发现,感知机模型虽然结构简单,收敛速度快,但是其应用场景只适合于线性可分的场景,并且每次计算由于对超平面不做条件限制,因此,得到的模型参数可能会不一致,毕竟可以将一个线性可分数据集进行分割的平面可能存在无穷多个。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值