分类算法有两种类型:感知器和适应性线性神经元

神经元的数学表示

w=[w1w2...wm],x=[x1x2...xm]w=\begin{bmatrix} w_1 \\ w_2 \\ ... \\ w_m \\ \end{bmatrix} , x=\begin{bmatrix} x_1 \\ x_2 \\ ... \\ x_m\\ \end{bmatrix}w=⎣⎢⎢⎡​w1​w2​...wm​​⎦⎥⎥⎤​,x=⎣⎢⎢⎡​x1​x2​...xm​​⎦⎥⎥⎤​
z=w1x1+w2x2+⋅⋅⋅+wmxmz=w_1x_1 + w_2x_2 + ···+w_mx_mz=w1​x1​+w2​x2​+⋅⋅⋅+wm​xm​
其中w为权重,x为训练样本

感知机的训练步骤

  1. 把权重向量初始化为0,或把每个分向量初始化为[0,1]间任意小数
  2. 把训练样本输入感知机,得到分类结果(-1或1)
  3. 根据分类结果更新权重向量

激活函数

为了计算方便我们添加w0x0w_0x_0w0​x0​, 其中w0=−θ,x0=1w_0=-\theta,x_0=1w0​=−θ,x0​=1 则
z=w0x0+w1x1+...+wmxm=wTx,ϕ(z)={1if z>0−1,otherwisez=w_0x_0 + w_1x_1+...+w_mx_m = w^Tx , \phi(z)=\begin{cases} 1 & \text {if z>0} \\ -1, & \text{otherwise} \end{cases} z=w0​x0​+w1​x1​+...+wm​xm​=wTx,ϕ(z)={1−1,​if z>0otherwise​
这样,当z>0z>0z>0时,ϕ(z)=1\phi(z)=1ϕ(z)=1,当z<0z<0z<0时,ϕ(z)=−1\phi(z)=-1ϕ(z)=−1.

权重的更新算法

  • w(j)=w(j)+Δw(j)w(j)=w(j)+\Delta w(j)w(j)=w(j)+Δw(j)
  • Δw(j)=η∗(y−y′)∗x(j)\Delta w(j)=\eta*(y-y')*x(j)Δw(j)=η∗(y−y′)∗x(j) : y表示x(j)的正确分类,y’表示感知机算出来的分类,x(j)表示训练样本。可以看出来如果感知器的分类结果y′y'y′与正确分类yyy相同时,那么可以得到Δw(j)=0\Delta w(j)=0Δw(j)=0,也就可以得到w(j)=0w(j)=0w(j)=0,也就是说如果感知器可以正确对数据样本进行正确分类,那么对权重w(j)w(j)w(j)就不需要进行调整;只有感知器得到了错误的分类结果之后,出需要调整权重向量w(j)w(j)w(j)。
  • η\etaη 表示学习率是[0,1]之间的一个小数,一般有使用者自己设置。通过反复运行模型,人为根据经验调整学习率η\etaη,使得模型训练结果越来越好。
  • w(0)=0,Δw(0)=η∗(y−y′)w(0)=0, \Delta w(0)=\eta*(y-y')w(0)=0,Δw(0)=η∗(y−y′)阈值的更新

举例说明如何更新权重

假设

  1. 权重向量初始化为:w=[0,0,0]w=[0,0, 0]w=[0,0,0]
  2. 训练样本的值:x=[1,2,3]x=[1,2,3]x=[1,2,3]
  3. 学习率:η=0.3\eta=0.3η=0.3
  4. 这个样本的正确分类y=1
  5. 感知器算出来的分类是y’=-1

调整权重向量Δw(0)=0.3∗(1−(−1))∗x(0)=0.3∗2∗1=0.6\Delta w(0)=0.3*(1-(-1))*x(0)=0.3*2*1=0.6Δw(0)=0.3∗(1−(−1))∗x(0)=0.3∗2∗1=0.6,w(0)=w(0)+Δw(0)=0.6w(0) = w(0)+\Delta w(0)=0.6w(0)=w(0)+Δw(0)=0.6,则权重的第一个分量更新为0.6,即w=[0.6,0,0]w=[0.6,0,0]w=[0.6,0,0]

同理,Δw(1)=0.3∗(1−(−1))∗x(1)=0.3∗2∗2=1.2\Delta w(1)=0.3*(1-(-1))*x(1)=0.3*2*2=1.2Δw(1)=0.3∗(1−(−1))∗x(1)=0.3∗2∗2=1.2,则更新权重的第二个分量为w(1)=w(1)+Δw(1)=1.2w(1)=w(1)+\Delta w(1)=1.2w(1)=w(1)+Δw(1)=1.2

同理,Δw(2)=0.3∗(1−(−1)∗x(2))=0.3∗2∗3=1.8\Delta w(2)=0.3*(1-(-1)*x(2))=0.3*2*3=1.8Δw(2)=0.3∗(1−(−1)∗x(2))=0.3∗2∗3=1.8,则更新权重的第三个分量为w(2)=w(2)+Δw(2)=1.8w(2)=w(2)+\Delta w(2)=1.8w(2)=w(2)+Δw(2)=1.8

最终可以得到更新后的权重向量为w=[0.6,1.2,1.8]w=[0.6, 1.2, 1.8]w=[0.6,1.2,1.8]

这样就可以再次将新的训练样本输入到模型中,根据分类结果走相同的步骤继续改进权重向量。

感知器算法的适用范围


必须要满足上图中第一个图中的情况,也就是预测的数据可以现行分割,感知器的训练目标就是要找出这条线。而后面两个情况,是无法进行线性可分的,不适用于感知器算法进行分类。

代码实现

定义感知器类

import numpy as npclass Perceptron(object):"""eta: 学习率n_iter: 权重向量的训练次数w_: 神经分叉权重向量errors_: 用于记录神经元判断出错次数"""def __init__(self, eta = 0.01, n_iter = 10):self.eta = etaself.n_iter = n_iterpassdef fit(self, X, y):"""输入训练数据,培训神经元,X表示输入样本, y对应样本的正确分类X: shape[n_samples, n_features]n_samples:表示有多少个训练样本数量n_features: 表示有多少个属性例如:X: [[1,2,3], [4,5,6]] => n_samples=2;n_features=3y: [1, -1]表示第一个向量的分类是1, 第二个向量的分类是-1""""""首先初始化权重为0加一是因为激活函数w0,也就是阈值,这样就只用判断输出结果是否大于0就可以了"""self.w_ = np.zero(1 + X.shape[1])self.errors_ = []"""只要出现错误分类,那么反复训练这个样本,次数是n_iter"""for _ in range(self.n_iter): errors = 0"""X:[[1,2,3], [4,5,6]]y:[1, -1]zip(X, y) => [[1,2,3,1], [4,5,6-1]]"""for xi, target in zip(X,y):"""update = η * (y-y')"""update = self.eta * (target - self.predict(xi))"""xi 是一个向量, 例如[1,2,3], target表示1update 是一个常量update*xi 等价于 [Δw(1) = X[1]*update, Δw(2) = X[2]*update, Δw(3) = X[3]*update]"""# w_[1:]表示w忽略第0个元素,从第一个元素开始往后self.w_[1:] += update * xiself.w_[0] += update * 1errors += int(update != 0.0)self.errors_.append(errors)passpassdef net_input(self, X):"""z = W0*1 + W1*X1 + W2*X2+ ...+ Wn*Xn"""return np.dot(X, self.w_[1:]) + self.w_[0]def predict(self, X):"""如果self.net_input(X) >= 0.0返回1, 否则返回-1"""return np.where(self.net_input(X) >= 0.0 , 1, -1)

目前虽然有了感知器的分类算法,但是还没有运行起来,下面将如何使用这个感知器分类算法,然后将训练样本输入到模型中,最后进行预测数据。

介绍训练数据

有了基本模型后,要做的就是要把大量的数据,输入至模型中,让模型通过对大量数据的观察,总结出数据中隐含的某种规律,根据数据特点不断调节模型中神经元权重数值,当神经元的权重数值调节到合适的范围之内后,就可以利用训练后的模型对新的数据进行预测分类。
首先需要先介绍训练数据的数据结构。训练数据内容如下:

使用pandas工具,来读取数据,可以很容易的进行抽取数据。
首先安装pandas:pip install pandas -i https://pypi.douban.com/simple

import pandas as pdfile="./iris.csv"
df = pd.read_csv(file, header=None)
print(df.head())

结果输出如下:

可视化展示这个数据,使用matplotlib工具进行展示。

import matplotlib.pyplot as plt
import numpy as np
from test3 import df# 将df中0到100行的数据的第四列赋值给y向量
y = df.loc[0:100, 4].values
# 将Iris-setosa转为-1,其余转为1
y = np.where(y == 'Iris-setosa', -1, 1)
# print(y)
# 将df0到100行的数据的第0列和第2列抽取出来,赋值给x向量
X = df.iloc[0:100, [0, 2]].values
# print(X)
# 将X向量的钱50条数据的第0列作为x轴,第1列作为y轴坐标,画在二维坐标轴,画出来的点是红色的'o',
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('花瓣长度')
plt.ylabel('花径长度')
plt.legend(loc='upper left')
# 下面两行解决乱码问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = Falseplt.show()


可以看出来这两类数据可以线性分割开。

一步一步调试

初始化eta=0.1, w=[0 0 0]5.1,1.4,target=-1, self.net_input(x)=W0*1+W1*5.1+W2*1.4=0,self.predict(xi)=1,update=eta*(target-self.predict(xi))=0.1*(-2)=-0.2,errors=1,W=[1*(-0.2)5.1*(-0.2)1.4*(-0.2)]=[-0.2 -1.02 -0.28]
4.9,1.4,target=-1, self.net_input(x)=W0*1+W1*4.9+W2*1.4=-0.2*1+(-1.02)*4.9+(-0.28)*1.4=-0.3918432<0,self.predict(xi)=-1,update=eta*(target-self.predict(xi))=0.1*0=0,errors=1,W=[-0.2+1*0-1.02+4.9*0-0.28+1.4*0]=[-0.2 -1.02 -0.28]
4.7,1.3,target=-1, self.net_input(x)=W0*1+W1*4.7+W2*1.3=-0.2+(-4.794)+(-0.364)<0,self.predict(xi)=-1,update=0,errors=1,W=[-0.2 -1.02 -0.28]
5.4,1.7,target=-1,self.net_input(x)<0,self.predict(xi)=-1,update=0,errors=1,W=[-0.2 -1.02 -0.28]
7,4.7,target=1,self.net_input(x)<0,self.predict(xi)=-1,update=0.2,errors=2,W=[(-0.2)+(0.2*1) (-1.02)+(0.2*7) (-0.28)+(0.2*4.7)]=[0 0.38 0.66]
  1. 首先得到样本数据和分类标签target
  2. 然后计算预测标签的值predict
  3. 更新权重W=eta*(target-predict), 将上一次的权重W进行累加w(j)+Δw(j)
  4. 以此类推

机器学习系列(一)感知器分类算法相关推荐

  1. 神经网络与机器学习 笔记—Rosenblatt感知器收敛算法C++实现

    Rosenblatt感知器收敛算法C++实现 算法概述 自己用C++实现了下,测试的例子和模式用的都是双月分类模型,关于双月分类相关看之前的那个笔记: https://blog.csdn.net/u0 ...

  2. 分类系列之感知器学习算法PLA 和 口袋算法Pocket Algorithm

    我们有一堆数据,默认他们是线性可分的.  定义f为这个数据分割线的最优解,但是我们不知道他的值.  我们仅有一个函数集H,这个函数一般是无穷大的.我们的目的就是从H中找出一条线g来尽可能的接近f.但是 ...

  3. 机器学习算法系列(一)- 感知器学习算法(PLA)

    阅读本文需要的背景知识点:数学基础知识.一丢丢编程知识 一.引言   前面一节我们了解了机器学习算法系列(〇)- 基础知识,接下来正式开始机器学习算法的学习,首先我们从最简单的一个算法--感知器学习算 ...

  4. ML之NB:基于news新闻文本数据集利用纯统计法、kNN、朴素贝叶斯(高斯/多元伯努利/多项式)、线性判别分析LDA、感知器等算法实现文本分类预测

    ML之NB:基于news新闻文本数据集利用纯统计法.kNN.朴素贝叶斯(高斯/多元伯努利/多项式).线性判别分析LDA.感知器等算法实现文本分类预测 目录 基于news新闻文本数据集利用纯统计法.kN ...

  5. 使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负

    使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负 1. 数据集 百度网盘链接,提取码:q79p 数据集文件格式为CSV.数据集包含了大约5万场英雄联盟钻石排位赛前15分钟的数据集合,总 ...

  6. 【Python-ML】感知器学习算法(perceptron)

    1.数学模型   2.权值训练 3.Python代码 感知器收敛的前提是两个类别必须是线性可分的,且学习速率足够小.如果两个类别无法通过一个线性决策边界进行划分,要为模型在训练集上的学习迭代次数设置一 ...

  7. 机器学习实战-57: 人工神经网络分类算法(Artificial Neural Network)

    机器学习实战-57: 人工神经网络分类算法 深度学习原理与实践(开源图书)-总目录,建议收藏,告别碎片阅读! 人工神经网络(Artificial Neural Network)分类算法属于监督学习算法 ...

  8. 基于机器学习和TFIDF的情感分类算法,详解自然语言处理

    摘要:这篇文章将详细讲解自然语言处理过程,基于机器学习和TFIDF的情感分类算法,并进行了各种分类算法(SVM.RF.LR.Boosting)对比 本文分享自华为云社区<[Python人工智能] ...

  9. 机器学习中常见的六种分类算法(附Python源码+数据集)

    今天和大家学习一下机器学习中常见的六种分类算法,如K近邻.决策树.朴素贝叶斯.逻辑回归.支持向量机.随机森林 除了介绍这六种不同分类算法外,还附上对应的Python代码案例,并分析各自的优缺点. 01 ...

最新文章

  1. 充电桩服务器协议,充电桩与云服务器通信协议
  2. server长时间运行query,Ajax刷新被block
  3. 浅析Java的“克隆”方法[zt]
  4. [剑指offer]面试题第[43]题[Leetcode][第233题][JAVA][1~n整数中1出现的次数][找规律][递归]
  5. html弹出保存文件对话框_初步了解CAD的模板文件
  6. 分享一个 pycharm 专业版的永久使用方法
  7. 【转】一个程序员分享8年的开发经验
  8. 实验室检测专用计算机的维护保养,计算机实验室维护与管理.doc
  9. html左斜杠转义字符,html的右斜杠转义符号是什么呢
  10. 熵权法stata程序
  11. siteserver/sscms 首页新闻排版及代码(二)
  12. AMD CPU 运行 Android Studio 原生模拟器的几点注意事项
  13. 手机游戏无障碍设计——猜地鼠之Android篇
  14. 四、Scala从入门到精通一一循环控制
  15. Java基础语法(三)——运算符
  16. java志愿者活动招募申请报名系统springbootboot
  17. 如何编写自己的头文件
  18. 9、共享变量(Broadcast Variable和Accumulator)
  19. python学习爬虫之删除无用字符以及空白替换等()
  20. iOS app可视化开发(一)使用Xcode创建app

热门文章

  1. SQL Server 表变量和临时表的区别
  2. oracle 11gr2 bbed 安装,oracle11gR2 安装bbed工具
  3. windows系统如何查看端口被占用、杀进程
  4. Git强制覆盖还原本地救火命令
  5. linux由哪些部分组成,linux内核处于什么位置?,为你介绍一些Linux操作系统的基础知识(一)...
  6. java通过jxl处理execl空行_jxl操作Excel导入数据库之空行的处理
  7. 移动端、微信小程序页面布局参考
  8. PHP中empty,is_null,isset的区别
  9. php推荐码生成,最新最全PHP生成制作验证码代码详解(推荐),验证码详解_PHP教程...
  10. 前端预览word文件_[装机必备] QuickLook —— 敲击空格即可快速预览文件