机器学习 | 剖析感知器算法 & Python实现
前言:本系列博客参考于 《机器学习算法导论》和《Python机器学习》
如有侵权,敬请谅解。本书尽量用总结性的语言重述本书内容,避免侵权。
上一篇已经初步介绍了机器学习相关知识,简短介绍了机器学习的分类等等,本篇介绍其中监督学习中的分类领域下的感知器算法。
\]
本篇将循序渐进的实现一个感知器,并且通过训练使其具备对鸢尾花数据集中数据进行分类的能力。
早期的机器学习
在详细讨论感知器和相关算法之前,先大体了解一下早期机器学习的起源。 为了理解大脑的工作原理以涉及人工智能系统,沃伦*麦卡洛克 和 沃尔特*皮茨 在 \(1943\) 年 神经元是大脑中相互连接的神经细胞,这些细胞可以处理和传递化学和电信号。
麦卡洛克-皮茨 将神经细胞描述为一个具备二进制输出的逻辑门。
树突接收多个输入信号,如果累加的信号超过某一阈(yu)值,经细胞体的整合就会生成一个输出信号,并通过轴突进行传递。
正是基于以上 \(MCP\) 模型,感知器学习法则被提出来。
感知器
Description
$MCP$ 模型出现几年后,弗兰克*罗森布拉特提出了第一个感知器学习法则。
在此感知器规则中,罗森布拉特提出了一个自学习算法,此算法可以自动
在监督学习与分类中,类似算法可用于预测样本所属的类别。
更严谨的讲,我们可以把这个问题看作一个二值分类,为了简单起见,把两类分别记为 $1$(正类别)和 $-1$(父类别)。
定义一个激活函数(activation function),
它以特定的输入值x与相应的权值向量w的线性组合作为输入。
转化成公式长这个样子:
\phi(z)=w_{1} * x_{1}+w_{2} * x_{2}+\ldots+w_{m} * x_{m}=\sum_{m=0}^{m} w_{j} x_{j}=w^{T} x \\
w=\left\{\begin{array}{c}
w_{1} \\
w_{2} \\
\cdots \\
w_{m}
\end{array}\right\}, x=\left\{\begin{array}{c}
x_{1} \\
x_{2} \\
\cdots \\
x_{m}
\end{array}\right\}
\end{array}
\]
此时,对于一个特定样本 \(x_i\) 的激活,如果其值大于预设的阈值 \(a\),我们将其划为 \(1\) 类,否则为 \(-1\) 类。在感知器算法中,激活函数(如下公式)
\]
\(\phi(z)\) 是一个简单的分段函数
1, & \text { 若 } \mathrm{z}>=\mathrm{a} \\
-1, & \text { 其他 }
\end{array}\right.
\]
\(MCP\) 神经元和罗森布拉特阈值感知器的理念就是,
通过模拟的方式还原大脑中单个神经元的工作方式:他是否被激活。
总结的来说,罗森布拉特感知器最初的规则非常简单,可总结如下几步:
- 将权重初始化为 \(0\) 或者是一个极小的随机数
- 迭代所有训练样本,执行以下操作:
- 根据以上公式,计算输出值
- 更新权重
这里的输出值是指通过前面定义的单位阶跃函数预测得出的类标,而每次对权重向量中每一权重 \(w\) 的更新方式为:
\]
对于用于更新权重的值可以通过感知器学习规则计算获得:
\]
其中 \(η\) 是学习速率(一个介于 \(0.0\) 到 \(1.0\) 之间的常数)
\(y^{(i)}\) 是第 \(i\) 个样本的真实类标(即真实值)
\(\hat{y}^{(i)}\) 是第 \(i\) 个样本的预测类标(预测值)。需要注意的是,权重向量中的所有权重值是同时更新的,这意味着在所有的权重 \(\Delta w_{j}\) 更新前,我们无法重新计算 \(\hat{y}^{(i)}\)
具体的,对于一个二维数据集,可通过下世进行更新:
\Delta w_{0}=\eta\left(y^{(i)}-\text { output }^{(i)}\right) \\
\Delta w_{1}=\eta\left(y^{(i)}-\text { output }^{(i)}\right) x_{1}^{(i)} \\
\Delta w_{2}=\eta\left(y^{(i)}-\text { output }^{(i)}\right) x_{2}^{(i)}\\
...
\end{array}
\]
\]
接下来介绍感知器的内核(推导过程),体验一下感知器规则的简洁之美(TQL
对于如下式所示的两种场景,若感知器对类标的预测正确,权重可不做更新:
\[\begin{array}{l}
\Delta w_{j}=\eta\left(-1^{(i)}-(-1)^{(i)}\right) x_{j}^{(i)}=0 \\
\Delta w_{j}=\eta\left(1^{(i)}-1^{(i)}\right) x_{j}^{(i)}=0
\end{array}
\]在类标预测错误的情况下,权重的值会分别趋向于正类别或者负类别的方向:
\[\begin{array}{l}
\Delta w_{j}=\eta\left(-1^{(i)}-1^{(i)}\right) x_{j}^{(i)}=-2 \eta x_{j}^{(i)} \\
\Delta w_{j}=\eta\left(1^{(i)}-(-1)^{(i)}\right) x_{j}^{(i)}=2 \eta x_{j}^{(i)}
\end{array}
\]
解释:假定 \(x_{j}^{(i)}=0.5\) 且模型将此样本错误的分类到了 \(-1\) 类别内。在此情况下,我们应将相应的权值增 \(1\) ,以保证下次遇到此样本时使得激活函数:\(x_{j}^{(i)}=w_{j}^{(i)}\)
能将其更多的判定为正类别,这也相当于增大其值大于单位阶跃函数阈值的概率,以使得样本被判定为 \(+1\) 类:\(\Delta w_{j}^{(i)}=\left(1^{(i)}-(-1)^{(i)}\right) * 0.5^{(i)}=2 * 0.5=1\)
权重的更新与 \(x_{j}^{(i)}=0.5\) 成比例。例如另外一个样本 \(x_{j}^{(i)}=2\)
被错误的分类到 \(-1\) 类别中,我们应更大幅度的移动决策边界,以保证下次遇到此样本时能正确分类。
\]
注意:感知器收敛的前提是两个类别必须是线性可分的,且学习速率足够小。
如果两个类别无法通过一个线性决策边界进行划分,可以为模型在训练数据集上的学习迭代次数设置一个最大值,或者设置一个允许错误分类样本数量的阈值,否则,感知器训练算法将永远不停的更新权值
下图是感知器流程图,很权威的一张图。
上图说明了感知器如何接收样本 \(x\) 的输入,并将其与权值 \(w\) 进行加权以计算净输入(net_input),进而净输入被传递到激活函数(在此为单位阶跃函数),然后生成值为 \(+1\) 或者 \(-1\) 的二值输出,并以其作为样本的预测类标。在学习阶段,此输出用来计算预测的误差并更新权重。
Python实现
上述已经深入讲解感知器的规则,下面我们用代码实现它。
我们封装一个感知器类,对外提供训练和预测接口。
具体细节可见注释。
import numpy as np
class Perceptron(object):
"""
Perceptron:感知器
感知器收敛的前提是:两个类别必须是线性可分的,且学习速率必须足够小,否则感知器算法会永远不停的更新权值
"""
def __init__(self, eta=0.01, n_iter=10):
"""
初始化感知器对象
:param eta: float 学习速率
:param n_iter: int 在训练集进行迭代的次数
"""
self.eta = eta
self.n_iter = n_iter
def net_input(self, xi):
"""
计算净输入
:param xi: list[np.array] 一维数组数据集
:return: 计算向量的点积
向量点积的概念:
{1,2,3} * {4,5,6} = 1*4+2*5+3*6 = 32
description:
sum(i*j for i, j in zip(x, self.w_[1:])) python计算点积
"""
print(xi, end=" ")
print(self.w_[:], end=" ")
x_dot = np.dot(xi, self.w_[1:]) + self.w_[0]
print("的点积是:%d" % x_dot, end=" ")
return x_dot
""" 计算类标 """
def predict(self, xi):
"""
预测方法
:param xi: list[np.array] 一维数组数据集
:return:
"""
target_pred = np.where(self.net_input(xi) >= 0.0, 1, -1)
print("预测值:%d" % target_pred, end="; ")
return target_pred
def fit(self, x, y):
"""
学习、训练方法
:param x: list[np.array] 一维数组数据集
:param y: 被训练的数据集的实际结果
:return:
权值,初始化为一个零向量R的(m+1)次方,m代表数据集中纬度(特征)的数量
x.shape[1] = (100,2) 一百行2列:表示数据集中的列数即特征数
np.zeros(count) 将指定数量count初始化成元素均为0的数组 self.w_ = [ 0. 0. 0.]
"""
"""
按照python开发惯例,对于那些并非在初始化对象时创建但是又被对象中其他方法调用的属性,可以在后面添加一个下划线.
将权值初始化为一个零向量,x.shape[1] 是特征的维度数量,如鸢尾花数据 (150, 5) self.w_ = [0,0,0,0,0,0]
w_[0]是初始权重值0 w_[1:] 每次更新的权重值
"""
self.w_ = np.zeros(1 + x.shape[1])
print(self.w_)
# 收集每轮迭代过程中错误分类样本的数量,以便后续对感知器在训练中表现的好坏做出判定
self.errors_ = []
for _ in range(self.n_iter):
errors = 0
"""
迭代所有样本,并根据感知器规则来更新权重
"""
for x_element, target in zip(x, y):
""" 如果预测值(self.predict(x_element))和实际值(target)一致,则update为0 """
update = self.eta * (target - self.predict(x_element))
print("真实值:%d" % target)
self.w_[1:] += update * x_element
self.w_[0] += update
errors += int(update != 0.0)
self.errors_.append(errors)
return self
另外附上 《机器学习算法导论》书中的简易代码版本
import numpy as np
class Perceptron:
def fit(self, X, y):
# 学习、训练方法
m, n = X.shape
w = np.zeros((n, 1))
b = 0
done = False
while not done:
done = True
for i in range(m):
x = X[i].reshape(1, -1)
if y[i] * (x.dot(w) + b) <= 0:
w = w + y[i] * x.T
b = b + y[i]
done = False
self.w = w
self.b = b
def predict(self, X):
# 预测方法
return np.sign(X.dot(self.w) + self.b)
机器学习 | 剖析感知器算法 & Python实现的更多相关文章
- 感知器算法--python实现
写在前面: 参考: 1 <统计学习方法>第二章感知机[感知机的概念.误分类的判断] http://pan.baidu.com/s/1hrTscza 2 点到面的距离 3 梯度 ...
- 机器学习之感知器算法原理和Python实现
(1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学 ...
- Stanford大学机器学习公开课(三):局部加权回归、最小二乘的概率解释、逻辑回归、感知器算法
(一)局部加权回归 通常情况下的线性拟合不能很好地预测所有的值,因为它容易导致欠拟合(under fitting).如下图的左图.而多项式拟合能拟合所有数据,但是在预测新样本的时候又会变得很糟糕,因为 ...
- [置顶] 局部加权回归、最小二乘的概率解释、逻辑斯蒂回归、感知器算法——斯坦福ML公开课笔记3
转载请注明:http://blog.csdn.net/xinzhangyanxiang/article/details/9113681 最近在看Ng的机器学习公开课,Ng的讲法循循善诱,感觉提高了不少 ...
- 感知器及其Python实现
感知器是由美国计算机科学家罗森布拉特(F.Roseblatt)于1957年提出的.感知器可谓是最早的人工神经网络.单层感知器是一个具有一层神经元.采用阈值激活函数的前向网络.通过对网络权值的训练,可以 ...
- Perceptron Algorithm 感知器算法及其实现
Rosenblatt于1958年发布的感知器算法,算是机器学习鼻祖级别的算法.其算法着眼于最简单的情况,即使用单个神经元.单层网络进行监督学习(目标结果已知),并且输入数据线性可分.我们可以用该算法来 ...
- 第三集 欠拟合与过拟合的概念、局部加权回归、logistic回归、感知器算法
课程大纲 欠拟合的概念(非正式):数据中某些非常明显的模式没有成功的被拟合出来.如图所示,更适合这组数据的应该是而不是一条直线. 过拟合的概念(非正式):算法拟合出的结果仅仅反映了所给的特定数据的特质 ...
- 【2008nmj】Logistic回归二元分类感知器算法.docx
给你一堆样本数据(xi,yi),并标上标签[0,1],让你建立模型(分类感知器二元),对于新给的测试数据进行分类. 要将两种数据分开,这是一个分类问题,建立数学模型,(x,y,z),z指示[0,1], ...
- 机器学习之感知器和线性回归、逻辑回归以及SVM的相互对比
线性回归是回归模型 感知器.逻辑回归以及SVM是分类模型 线性回归:f(x)=wx+b 感知器:f(x)=sign(wx+b)其中sign是个符号函数,若wx+b>=0取+1,若wx+b< ...
- 感知器算法PLA
for batch&supervised binary classfication,g≈f <=> Eout(g)≥0 achieved through Eout(g)≈Ein(g ...
随机推荐
- 4. Shell 循环语句
重点: 条件测试. read. Shell 环境配置. case. for. find. xargs. gzip,bzip2,xz. tar. sed. 1)循环 1.1)循环执行介绍 将某代码段重复 ...
- 从0到1,手把手带你开发截图工具ScreenCap------001实现基本的截图功能
ScreenCap---Version:001 说明 从0到1,手把手带你开发windows端的截屏软件ScreenCap 当前版本:ScreenCap---001 支持全屏截图 支持鼠标拖动截图区域 ...
- Spring Cloud Seata系列:基于AT模式实现分布式事务
目录 前提 Seata的AT模型 流程梳理 一阶段: 二阶段-回滚 二阶段-提交 脏写问题 写隔离 读隔离 优缺点 AT与XA的区别 实现AT模式 https://seata.io/zh-cn/doc ...
- SpringBoot发送虚拟请求~
1.创建一个测试用的TestController @RestController public class TestController { @GetMapping("/test" ...
- ElasticSearch给索引起"别名"和其重要性
创建别名: https://www.elastic.co/guide/en/elasticsearch/reference/6.8/indices-aliases.html 我们有时候并不能确保索引库 ...
- 数字孪生结合GIS能够为城市灾害预防工作提供什么帮助?
数字孪生技术结合GIS(地理信息系统)在城市灾害预防工作中发挥着重要的作用,为城市的安全和可持续发展提供了关键帮助.数字孪生是一种将现实世界与数字虚拟世界相结合的技术,可以帮助城市规划者和管理者更好地 ...
- 【Python】【OpenCV】轮廓检测
Code: 1 import cv2 2 import numpy as np 3 4 img = np.zeros((200, 200), dtype=np.uint8) 5 img[50:150, ...
- Javascript Ajax总结——其他跨域技术之Web Sockets
Web Sockets的目标是在一个单独的持久连接上提供全双工.双向通信.在Javascript中创建了Web Sockets之后,会有一个HTTP请求发送到浏览器以发起连接.在取得服务器响应后,建立 ...
- 云MSP技本功|基于OGG 实现Oracle到Kafka增量数据实时同步
简介: 在大数据时代,存在大量基于数据的业务.数据需要在不同的系统之间流动.整合.通常,核心业务系统的数据存在OLTP数据库系统中,其它业务系统需要获取OLTP系统中的数据.传统的数仓通过批量数据同步 ...
- [P2416 泡芙] 题解报告
题目链接:P2416 泡芙 简化题意 给定一个无向图 \(G\),每条边有边权 \(0 / 1\),现给定 \(m\) 组询问,每次询问形如 \(s, t\),问是否可以从 \(s\) 走到 \(t\ ...