感知器算法例题ppt_感知机模型(perceptron)算法详解及python实战

  • Post author:
  • Post category:python


关于感知器模型

感知器是一个简单的监督学习的机器学习算法,也是最早的神经网络结构。作为一个二分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别。数据:



是一个d维的特征向量,


是目标标签,

目标:利用上述给定的数据学习一个超平面


使其可以将数据集的正例点和负实例点划分到两侧。即:


算法详解

损失函数

为学习上述的超平面,选择误分类点的总数作为损失函数是一个很直观的选择,但是由于该损失函数对参数非连续可导,因此采用误分类点到超平面


的总距离作为损失函数。

对于错误分类的实例,当真实标签为


,错误的预测结果为


;真实标签为


时,错误的预测结果为


,因此,错误分类点


到超平面的距离可由如下表示:

由于感知机的目的在于使所有训练样本分类正确,


对于判断是否分类正确没有影响,因此相关损失函数中可略去该项。对于误分类实例集合M,可得如下损失函数:

求解

原始形式

感知器学习算法是误分类驱动的,可采用随机梯度下降算法对参数



进行优化。公式(2)的梯度为:

对于随机采样并错误分类的点


,其对



的更新贡献如下:

其中


是学习率,通过不断的采样可利用公式(5)和(6)对



进行不断更新直到全部分类正确。

对偶形式

考察公式(5)和(6),如果学习率


,则上式变为:

在训练过程中,如果


被采样了100次,而其中30次被错误分类,那么实例


对w和b带来的变化分别为:



。更一般地,对任意实例


,若其在训练过程中共有


次被分类错误,则其对



带来的变化分别为



。在学习率


下,上述变化可表示为



。那么,训练过程中如果



的初始值为0,则最终



学习得到的结果为:

感知器的模型最终可表示为:

从上式可以看到,在感知机的对偶形式下,实例仅以内积的形式出现 ,在计算前可以计算所有实例之间由内积构成的矩阵,即Gram矩阵(Gram matrix),以加快计算速度。

小贴士超平面及点到超平面的距离

超平面是在空间


中的一个子空间


。在三维空间中,超平面是一个二维平面,而在二维空间中超平面则为一条直线,此时,点到超平面的距离就变成了我们中学所熟悉的点到直线的距离——如果直线表达式为


,那么点


到该直线的距离为:

数据介绍

Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性(下表中的前四列)。可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。

代码

加载必要的包

import numpy as np

from sklearn.model_selection import train_test_split

from sklearn.datasets import load_iris

加载数据

iris = load_iris()

# 数据中前五个样例的属性向量

iris.data[:5]

array([[5.1, 3.5, 1.4, 0.2],

[4.9, 3. , 1.4, 0.2],

[4.7, 3.2, 1.3, 0.2],

[4.6, 3.1, 1.5, 0.2],

[5. , 3.6, 1.4, 0.2]])

# 对应的标签

iris.target[:5]

array([0, 0, 0, 0, 0])

X = iris.data[:100] #iris数据总共有三类,每类50个样本,我们只取前两类做二分类任务

y = iris.target[:100]

y = np.where(y == 1, 1, -1) #把原始标签由(0,1)调整为(-1,1)

划分数据

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4)

原始形式

def evaluation(X,y,w,b):

p = np.dot(X, w) + b

pred = np.where(p <= 0.0, -1, 1)

ture_num = (pred==y).sum()

total_num = X.shape[0]

acc = 1.0*ture_num / total_num

return acc

def PerceptronBase(X,y,eta,epoch):

w = np.zeros(X.shape[1])

b = 0

errors = []

for i in range(epoch):

error = 0

for xi, yi in zip(X, y):

p = np.dot(xi, w) + b

if p*yi<=0: #当预测错误的时候更新参数

deta_w = yi*xi*eta

deta_b = yi*eta

w += deta_w

b += deta_b

error += 1

errors.append(error)

acc = evaluation(X_test,y_test,w,b)

info = ‘ Epoch: [{0}] Train_Error: {erro_:d} Acc: {acc_:.4f}’.format(i,erro_=error,acc_=acc)

print(info)

return w,b

w,b = PerceptronBase(X_train,y_train,0.01,5)

Epoch: [0] Train_Error: 7 Acc: 1.0000

Epoch: [1] Train_Error: 0 Acc: 1.0000

Epoch: [2] Train_Error: 0 Acc: 1.0000

Epoch: [3] Train_Error: 0 Acc: 1.0000

Epoch: [4] Train_Error: 0 Acc: 1.0000

对偶形式

def PerceptronDual(X,y,eta,epoch):

n_samples, n_features = X.shape

alpha, b = [0] * n_samples, 0

w = np.zeros(n_features)

i = 0

for i in range(epoch):

error = 0

for j in range(n_samples):

p = np.dot(X[j], w) + b

if p*y[j]<=0:

alpha[j] += 1

error+=1

alpha_npy = np.array(alpha)[:,np.newaxis]

y_npy = y[:,np.newaxis]

w = (alpha_npy* X * y_npy).sum(0)*eta

b = (alpha_npy* y_npy).sum(0)*eta

acc = evaluation(X_test,y_test,w,b)

info = ‘ Epoch: [{0}] Train_Error: {erro_:d} Acc: {acc_:.4f}’.format(i,erro_=error,acc_=acc)

print(info)

return w,b

w,b = PerceptronDual(X_train,y_train,0.01,5)

Epoch: [0] Train_Error: 60 Acc: 0.5000

Epoch: [1] Train_Error: 30 Acc: 0.5000

Epoch: [2] Train_Error: 30 Acc: 0.5000

Epoch: [3] Train_Error: 30 Acc: 0.5000

Epoch: [4] Train_Error: 30 Acc: 0.5000

项目地址



版权声明:本文为weixin_32498069原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。