感知机原理解析及代码实现

感知机原理解析与代码实现

一、感知机通俗直观理解

神经元与感知机

在这里插入图片描述

图1 神经元工作原理

​ 如图1所示,我们的大脑是一个生物学上的复杂的神经网络,它的最小的单元我们可以称其为神经元。 其工作方式为首先接收到信号,将这些信号通过树突组织的处理,将会产生微弱的生物电,进而产生刺激,随后树突组织将这些刺激送到细胞中的细胞核,细胞核对这些刺激做综合处理,当刺激达到了一定阈值后,他就会被激活。因此对应产生一个刺激的输出,并通过轴突进行进一步的传递。

​ 抽象来讲,神经细胞就是一个具备二进制输出的逻辑门,树突接收多个输入信号,如果累加的信号超过了某一个阈值,经过细胞体的整合就会产生与一个输出信号,进行通过轴突进行传递。感知机就是基于这样的神经元的抽象逻辑所提出的。
在这里插入图片描述

图2 感知机的基本结构

​ 如图2所示,感知机与神经元的工作方式类似,首先接收样本 x x x的输入,随后将其与权值 w w w进行加权计算得到净输入。接着净输入被传递到激活函数,生成值为+1或者-1的二值输出,并以其作为样本的预测类标。在学习阶段则将这个输出用于更新权重。

感知机的通俗解释

​ 感知机是一个用于二类分类的线性分类模型,是SVM(支持向量机)和神经网络的重要基础。那么我们可以利用感知机做些什么呢?

​ 通俗讲,在数据集线性可分的基础上,将数据集中每个样本抽象为一个二维坐标 ( x , y ) (x,y) (x,y),即每一个样本的数据和标签。感知机就是可以将所有样本点完美分成两类的一条直线。只要可以将坐标平面上的点完美分开,这就是一个好的感知机模型,所有可能这样的模型并不是唯一的。

​ 如何做到呢?问题被抽象为,将每一个错分类的点和该直线的距离求出并进行求和,当这个值最小或者最好为零的话,就求得了这条直线。

二、数学角度

感知机定义

​ 由输入到输出会得到一个映射,这样的映射函数 f ( x ) f(x) f(x)就是感知机的定义
f ( x ) = s i g n ( w ⋅ x + b ) (1) f(x)=sign(w\cdot x+b) \tag{1} f(x)=sign(wx+b)(1)
​ 其中, w w w为权重或者权重向量, b b b为偏置量,sign为如下所示的阶跃函数
s i g n ( x ) = { + 1 , x > = 0 − 1 , x < = 0 (2) sign(x)=\begin{cases} +1,x >=0\\ -1,x <=0 \end{cases} \tag{2} sign(x)={+1,x>=01,x<=0(2)
​ 从几何角度来讲,对于线性方程 w ⋅ x + b = 0 w\cdot x + b = 0 wx+b=0,就是那条得到的最优的直线,只是经过阶跃函数之后才能完成分类的工作。该方程也称为 n n n维特征空间的超平面 S S S,其中 w w w S S S的法向量, b b b S S S的截距,这个超平面将特征空间划分为两部分,位于两部分的点分别被称为真负类, S S S也被称为分离超平面。

感知机学习策略

​ 感知机的目标是学习一个将训练集正负样本完全分开的分离超平面,即需要确定参数 w , b w,b w,b的值,那么需要确定一个学习策略,即确定损失函数并且将损失函数最小化。

​ 由上一节的通俗解释可得,损失函数可定义为误分类点到超平面 S S S的距离总和。
− 1 ∣ ∣ w ∣ ∣ ∑ x i ∈ M y i ( w ⋅ x i + b ) (3) -\frac{1}{||w||} \sum_ {x_i\in M} y_i(w \cdot x_i+b) \tag{3} w1xiMyi(wxi+b)(3)
​ 这个式子就没啥好解释的了,就是距离公式求和,其中距离公式用的是几何距离。

​ 那么,如果不考虑 1 ∣ ∣ w ∣ ∣ \frac{1}{||w||} w1,那么可以得到感知机的损失函数
L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) (4) L(w,b) = - \sum_ {x_i\in M} y_i(w \cdot x_i+b) \tag{4} L(w,b)=xiMyi(wxi+b)(4)
​ 其中, M M M为所有误分类点的集合。那么我们的主要工作就是最小化这个损失函数即可。

感知机学习算法

​ 主要是通过采用梯度下降算法,不断极小化目标函数(4),具体操作步骤为:

(1)选取初值 w 0 , b 0 w_0,b_0 w0,b0,通常来说都是0

(2)在训练集中选取数据 ( x i , y i ) (x_i,y_i) xi,yi

(3)如果有式子 y i ( w ⋅ x + b ) < = 0 y_i(w \cdot x+b) <= 0 yi(wx+b)<=0,那么就将对权重和偏置进行更新
w ← w + η y i x i b ← b + η y i (5) w \gets w+\eta y_ix_i \\ b \gets b+\eta y_i \tag{5} ww+ηyixibb+ηyi(5)
(4)转至2,直到训练集中不存在误分类点为止

​ 在式(5)中, η \eta η为学习率,是一个可以自己进行设置数值的超参数

一种解释:当一个实例样本被误分类,即位于超平面的错误一侧时,则调整w,b的值,使分离超平面向该误分类点的一侧移动,以减少该误分类点与超平面间的距离,直至超平面越过该误分类点被其正确进行分类。

三、代码实现

import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.colors import ListedColormap
class Perceptron(object):
    def __init__(self,lr, n_iter):
        self.lr = lr
        self.n_iter = n_iter

    def train(self,X,y):
        #这个向量包含了两重信息,第一w_[0]代表了偏置项b,w_[1:]代表了权重向量
        self.w_ = np.zeros(1+X.shape[1])
        self.errors_ = []

        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X,y):
                #这里的target - self.predict(xi)对应公式(5)中的yi,
                update = self.lr * (target - self.predict(xi))
                self.w_[1:] += update * xi
                self.w_[0] += update
                errors += int(update != 0.0)
            self.errors_.append(errors)
        return self

    #这个函数完成了感知机定义里面的w·x+b这个操作
    def net_input(self, X):
        return np.dot(X, self.w_[1:])+self.w_[0]
    #按照学习算法的第三步,对式子判断其是否小于0
    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)

# 将bunch格式的数据集转化为pandas的dataframe
def sklearn_to_df(datasets):
    df = pd.DataFrame(datasets.data, columns=datasets.feature_names)
    df['target'] = pd.Series(datasets.target)
    return df

iris = load_iris()
df_iris = sklearn_to_df(iris)
y = df_iris.iloc[0:100,4].values
y = np.where(y == 0,-1,1)
X = df_iris.iloc[0:100,[0,2]].values

#鸢尾花数据集的可视化
# plt.scatter(X[:50,0],X[:50,1],
#             color='r',marker='o',label='setosa')
# plt.scatter(X[50:100,0],X[50:100,1],
#             color='b',marker='x',label='versicolor')
# plt.xlabel('petal length')
# plt.ylabel('sepal length')
# plt.legend(loc='upper left')
# plt.show()

# 利用鸢尾花数据集来训练感知机
pn = Perceptron(lr=0.01,n_iter=10)
pn.train(X, y)
# plt.plot(range(1,len(pn.errors_)+1),pn.errors_,marker='o')
# plt.xlabel('Epoch')
# plt.ylabel('Number of miscalssifications')
# plt.show()

#画出决策边界
def plot_decision_regions(X, y, classifier, resolution=0.02):
    markers = ('s','x','o','^','v')
    colors = ('red','blue','lightgreen','gray','cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    x1_min, x1_max = X[:,0].min() - 1, X[:,0].max() + 1
    x2_min, x2_max = X[:,1].min() - 1, X[:,1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))

    z = classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T)
    z = z.reshape(xx1.shape)

    plt.contourf(xx1,xx2,z,alpha=0.4,cmap=cmap)
    plt.xlim(xx1.min(),xx1.max())
    plt.ylim(xx2.min(),xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x = X[y == cl,0], y = X[y == cl,1],
                    alpha=0.8, c=cmap(idx),
                    marker=markers[idx],label=cl)

plot_decision_regions(X, y, classifier=pn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc = 'upper left')
plt.show()

​ 以上代码的运行结果我以可视化的形式表示了出来,其中核心部分就是Perceptron这个类,完整的解释了感知机的数学实现方式。运行结果图如下所示:

在这里插入图片描述

图3 运行结果

参考文献

[1] 李航. 统计学习方法[M]. 北京: 清华大学出版社, 2012
[2] Sebastian Raschka.Python Machine Learning

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值