python机器学习——感知器
最近在看机器学习相关的书籍,顺便把每天阅读的部分写出来和大家分享,共同学习探讨一起进步!作为机器学习的第一篇博客,我准备从感知器开始,之后会慢慢更新其他内容。
在实现感知器算法前,我们需要先了解一下神经元(neuron)的工作原理,神经元有很多树突和一个轴突,树突(Dendrites)可以从其他神经元接收信息并将其带到细胞体(Cell nucleus),轴突(Axon)可以从细胞体发送信息到其他神经元。树突传递过来的信息在细胞体中进行计算处理后,如果结果超过某个阈值,轴突会传递信号到其他的神经元。人们通过认识神经元的工作过程,创造出了感知器学习算法。

感知器是Frank Rosenblatt在1975年就职于康奈尔实验室时所发明的一种人工神经网络,它被视为一种最简单形式的前馈神经网络,是一种二元线性分类器,不足在于不能处理线性不可分问题。
下图为三种不同情况,左图中的两类可以使用一条直线(即线性函数)分开,即线性可分;中间和右边由于不能使用线性函数分开,则为线性不可分。

我们直接来看一个实例,假设我们现在需要对花进行分类,数据集中有两种花朵,分别将其记为1和-1,我们需要根据数据集含有的花的一些特征来进行分类,这里仅使用两种花的特征,即萼片长度和花瓣长度,将这两个特征用向量表示为:
\[
x = \begin{bmatrix}x_1\\x_2\end{bmatrix}
\]
x也叫做输入向量,我们再定义一个相应的权重向量w:
\[
w = \begin{bmatrix}w_1\\w_2\end{bmatrix}
\]
将x和w线性组合后得到z:
\[
z = w_1x_1+w_2x_2
\]
我们假设,如果样本的激活值z大于等于事先设置好的阈值b,我们就说此样本属于类别1,否则属于类别-1,公式表示如下:
\[
\phi(z) = \begin{cases}1,\quad z\ge b \\\\-1,\quad otherwise\end{cases}
\]
可以看出这个想法和神经元的工作原理很相似。为了方便,我们将阈值b移到等式的左边并额外定义一个权重参数来代替-b,更新z为以下等式:
\[
z = w_0x_0+w_1x_1+w_2x_2
\]
那么上式中的z大于等于0的情况也就等价于之前当z大于等于阈值b的情况,可以得到:
\[
\phi(z) = \begin{cases}1,\quad z\ge0 \\\\-1,\quad otherwise\end{cases}
\]
上面的函数也叫做激活函数,我们通过激活函数将z压缩到了一个二元输出(1,-1),也就是:

我们可以看出权重向量w决定着分类是否准确,那么我们如何选择合适的权重向量w呢?我们不能一个一个给w赋值,这样工作量太大且没有效率,其实感知器可以通过数据集中的样本自动调整w,随着训练的进行,w的变化趋于平稳,分类的准确率也会大大提高。
我们更新权重向量w的公式为:
\[
w_j = w_j + \Delta w_j
\]
\[
\Delta w_j = \eta(y^i-\hat{y^i})x^i_j
\]
\[
\eta-学习率\\w_j-w向量的第j个特征\\y^i-第i个样本的真实类别\\\hat{y^i}-第i个样本的预测类别\\x_j^i-第i个样本的第j个特征
\]
其中学习率介于0.0和1.0之间,用于控制w更新的程度,权重向量w中的每一个参数都是同步更新的,即只有在w的每个参数的更新大小都计算出来后才会改变w的值,我们使用数据集中的大量训练样本x来更新w,来逐渐提高分类准确率。
感知器算法只有类别线性可分且学习率较小的情况下才能保证收敛,感知器接收训练样本x,将x与w线性结合得到z,再将z传递给激活函数,产生一个分类结果作为对样本x的预测类别,之后按照更新规则来更新w,等收敛后感知器也就训练完成了。
接下来我们开始实现感知器算法并使用Iris数据集训练:
import pandas as pd
读取数据集
df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None)
df.tail()
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| 145 | 6.7 | 3.0 | 5.2 | 2.3 | Iris-virginica |
| 146 | 6.3 | 2.5 | 5.0 | 1.9 | Iris-virginica |
| 147 | 6.5 | 3.0 | 5.2 | 2.0 | Iris-virginica |
| 148 | 6.2 | 3.4 | 5.4 | 2.3 | Iris-virginica |
| 149 | 5.9 | 3.0 | 5.1 | 1.8 | Iris-virginica |
由上表可以看到每个输入向量x都包含4个特征(0、1、2、3)和1个正确的类别(4)
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
取出前100个训练样本的类别向量,若其类别输入‘Iris-setosa’,则将其设置为-1,否则设置为1
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)
取出前100个训练样本的前两个特征向量
X = df.iloc[0:100, [0, 2]].values
画出这100个训练样本的类别分布图
plt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')
plt.scatter(X[50:100, 0], X[50:100, 1], color='blue', marker='x', label='versicolor')
plt.xlabel('petal length')
plt.ylabel('sepal length')
plt.legend(loc='upper left')
plt.show()

实现感知器
import numpy as np
class Perceptron(object):
"""Perceptron classifier.
Parameters
----------
eta:float
Learning rate(between 0.0 and 1.0
n_iter:int
Passes over the training dataset.
Attributes
----------
w_:1d-array
weights after fitting.
errors_:list
Number of miscalssifications in every epoch.
"""
def __init__(self, eta=0.01, n_iter=10):
self.eta = eta
self.n_iter = n_iter
def fit(self, X, y):
"""Fit training data.
:param X:{array-like}, shape=[n_samples, n_features]
Training vectors, where n_samples is the number of samples and
n_features is the number of features.
:param y: array-like, shape=[n_samples]
Target values.
:return:
self:object
"""
self.w_ = np.zeros(1 + X.shape[1]) # Add w_0
self.errors_ = []
for _ in range(self.n_iter):
errors = 0
for xi, target in zip(X, y):
update = self.eta * (target - self.predict(xi))
self.w_[1:] += update * xi
self.w_[0] += update
errors += int(update != 0.0)
self.errors_.append(errors)
return self
def net_input(self, X):
"""Calculate net input"""
return np.dot(X, self.w_[1:]) + self.w_[0]
def predict(self, X):
"""Return class label after unit step"""
return np.where(self.net_input(X) >= 0.0, 1, -1) #analoge ? :n in C++
ppn = Perceptron(eta = 0.1, n_iter = 10)
ppn.fit(X, y)
<__main__.Perceptron at 0x16680906978>
画出训练曲线
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker = 'o')
plt.xlabel('Epoches')
plt.ylabel('Number of misclassifications')
plt.show()

画出分界线
from matplotlib.colors import ListedColormap
def plot_decision_region(X, y, classifier, resolution=0.02):
# setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
# plot the decision surface
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 0].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())
#plot class samples
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_region(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

参考:
https://www.toutiao.com/a6669391886744027662/
https://zh.wikipedia.org/wiki/%E6%84%9F%E7%9F%A5%E5%99%A8
python机器学习——感知器的更多相关文章
- python之感知器-从零开始学深度学习
感知器-从零开始学深度学习 未来将是人工智能和大数据的时代,是各行各业使用人工智能在云上处理大数据的时代,深度学习将是新时代的一大利器,在此我将从零开始记录深度学习的学习历程. 我希望在学习过程中做到 ...
- Python实现感知器的逻辑电路(与门、与非门、或门、异或门)
在神经网络入门回顾(感知器.多层感知器)中整理了关于感知器和多层感知器的理论,这里实现关于与门.与非门.或门.异或门的代码,以便对感知器有更好的感觉. 此外,我们使用 pytest 框架进行测试. p ...
- 《Python 机器学习》笔记(二)
机器学习分类算法 本章将介绍最早以算法方式描述的分类机器学习算法:感知器(perceptron)和自适应线性神经元. 人造神经元--早期机器学习概览 MP神经元 生物神经元和MP神经元模型的对应关系如 ...
- Python机器学习2.2
使用Python实现感知器学习算法 在<Python机器学习>中的2.2节中,创建了罗森布拉特感知器的类,通过fit方法初始化权重self.w_,再fit方法循环迭代样本,更新权重,使用p ...
- 机器学习之感知器算法原理和Python实现
(1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学 ...
- 机器学习:Python实现单层Rosenblatt感知器
如果对Rosenblatt感知器不了解,可以先查看下相关定义,然后对照下面的代码来理解. 代码中详细解释了各步骤的含义,有些涉及到了数学公式的解释. 这篇文章是以理解Rosenblatt感知器的原理为 ...
- 感知器做二分类的原理及python实现
本文目录: 1. 感知器 2. 感知器的训练法则 3. 梯度下降和delta法则 4. python实现 1. 感知器[1] 人工神经网络以感知器(perceptron)为基础.感知器以一个实数值向量 ...
- 机器学习 —— 基础整理(六)线性判别函数:感知器、松弛算法、Ho-Kashyap算法
这篇总结继续复习分类问题.本文简单整理了以下内容: (一)线性判别函数与广义线性判别函数 (二)感知器 (三)松弛算法 (四)Ho-Kashyap算法 闲话:本篇是本系列[机器学习基础整理]在time ...
- 感知器算法--python实现
写在前面: 参考: 1 <统计学习方法>第二章感知机[感知机的概念.误分类的判断] http://pan.baidu.com/s/1hrTscza 2 点到面的距离 3 梯度 ...
随机推荐
- 大头儿子和小头爸爸的战斗--java字符和字符串
故事背景 一座普普通通的小屋里,住着大头儿子.小头爸爸和围裙妈妈.在他们普普通通的生活中,总是响起充满欢乐的笑声.最温暖的家又成了他们每个人的爱的源泉. <大头儿子和小头爸爸>是孩子居首( ...
- LitePal的基本用法
快速配置 1. 引入Jar包或源码 首先我们需要将LitePal的jar包引入到项目当中,可以点击这里查看LitePal的最新版本,选择你需要的下载即可.下载好了jar包之后,把它复制到项目的li ...
- docker镜像制作必备技能
正文 使用过docker的都知道dockerfile,其用于定义制作镜像的流程,由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像.可参考往期文章学习:docker基础知识整理 ...
- Redis 介绍学习
1.Redis 简介 Redis 是一个支持数据结构更多的键值对数据库.它的值不仅可以是字符串等基本数据 类型,也可以是类对象,更可以是 Set.List.计数器等高级的数据结构. Memcached ...
- 面试常考各类排序算法总结.(c#)
前言 面试以及考试过程中必会出现一道排序算法面试题,为了加深对排序算法的理解,在此我对各种排序算法做个总结归纳. 1.冒泡排序算法(BubbleSort) 1.1 算法描述 (1)比较相邻的元素.如果 ...
- 用go语言爬取珍爱网 | 第三回
前两节我们获取到了城市的URL和城市名,今天我们来解析用户信息. 用go语言爬取珍爱网 | 第一回 用go语言爬取珍爱网 | 第二回 爬虫的算法: 我们要提取返回体中的城市列表,需要用到城市列表解析器 ...
- 从源码角度看JedisPoolConfig参数配置
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 你好,JedisPoolConfig Java中使用Jedis作为连接Redis的工具.在使用Jedis的也可以配置Jed ...
- drf框架中分页组件
drf框架中分页组件 普通分页(最常用) 自定制分页类 pagination.py from rest_framework.pagination import PageNumberPagination ...
- 【前端词典】4 个实用有趣的 JS 特性
前言 最近在学习的过程中发现了我之前未曾了解过的一些特性,发现有些很有趣并且在处理一些问题的时候可以给我一个新的思路. 这里我将这些特性介绍给大家. 4 个有趣的 JS 特性 利用 a 标签解析 UR ...
- css涂鸦这样玩
前言 上一次深扒CSS的时候,还说CSS和H5绘制复杂图形很麻烦,看了大神的操作后,感觉茅塞顿开了,哈哈. 就算可能我暂时没有用到的机会,学习一下开发者的设计思路也是受益匪浅呀. 嗯,今天要介绍的是一 ...