机器学习系列(一)感知器分类算法
分类算法有两种类型:感知器和适应性线性神经元
神经元的数学表示
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=⎣⎢⎢⎡w1w2...wm⎦⎥⎥⎤,x=⎣⎢⎢⎡x1x2...xm⎦⎥⎥⎤
z=w1x1+w2x2+⋅⋅⋅+wmxmz=w_1x_1 + w_2x_2 + ···+w_mx_mz=w1x1+w2x2+⋅⋅⋅+wmxm
其中w为权重,x为训练样本
感知机的训练步骤
- 把权重向量初始化为0,或把每个分向量初始化为[0,1]间任意小数
- 把训练样本输入感知机,得到分类结果(-1或1)
- 根据分类结果更新权重向量
激活函数
为了计算方便我们添加w0x0w_0x_0w0x0, 其中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=w0x0+w1x1+...+wmxm=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′)阈值的更新
举例说明如何更新权重
假设
- 权重向量初始化为:w=[0,0,0]w=[0,0, 0]w=[0,0,0]
- 训练样本的值:x=[1,2,3]x=[1,2,3]x=[1,2,3]
- 学习率:η=0.3\eta=0.3η=0.3
- 这个样本的正确分类y=1
- 感知器算出来的分类是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]
- 首先得到样本数据和分类标签target
- 然后计算预测标签的值predict
- 更新权重W=eta*(target-predict), 将上一次的权重W进行累加w(j)+Δw(j)
- 以此类推
机器学习系列(一)感知器分类算法相关推荐
- 神经网络与机器学习 笔记—Rosenblatt感知器收敛算法C++实现
Rosenblatt感知器收敛算法C++实现 算法概述 自己用C++实现了下,测试的例子和模式用的都是双月分类模型,关于双月分类相关看之前的那个笔记: https://blog.csdn.net/u0 ...
- 分类系列之感知器学习算法PLA 和 口袋算法Pocket Algorithm
我们有一堆数据,默认他们是线性可分的. 定义f为这个数据分割线的最优解,但是我们不知道他的值. 我们仅有一个函数集H,这个函数一般是无穷大的.我们的目的就是从H中找出一条线g来尽可能的接近f.但是 ...
- 机器学习算法系列(一)- 感知器学习算法(PLA)
阅读本文需要的背景知识点:数学基础知识.一丢丢编程知识 一.引言 前面一节我们了解了机器学习算法系列(〇)- 基础知识,接下来正式开始机器学习算法的学习,首先我们从最简单的一个算法--感知器学习算 ...
- ML之NB:基于news新闻文本数据集利用纯统计法、kNN、朴素贝叶斯(高斯/多元伯努利/多项式)、线性判别分析LDA、感知器等算法实现文本分类预测
ML之NB:基于news新闻文本数据集利用纯统计法.kNN.朴素贝叶斯(高斯/多元伯努利/多项式).线性判别分析LDA.感知器等算法实现文本分类预测 目录 基于news新闻文本数据集利用纯统计法.kN ...
- 使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负
使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负 1. 数据集 百度网盘链接,提取码:q79p 数据集文件格式为CSV.数据集包含了大约5万场英雄联盟钻石排位赛前15分钟的数据集合,总 ...
- 【Python-ML】感知器学习算法(perceptron)
1.数学模型 2.权值训练 3.Python代码 感知器收敛的前提是两个类别必须是线性可分的,且学习速率足够小.如果两个类别无法通过一个线性决策边界进行划分,要为模型在训练集上的学习迭代次数设置一 ...
- 机器学习实战-57: 人工神经网络分类算法(Artificial Neural Network)
机器学习实战-57: 人工神经网络分类算法 深度学习原理与实践(开源图书)-总目录,建议收藏,告别碎片阅读! 人工神经网络(Artificial Neural Network)分类算法属于监督学习算法 ...
- 基于机器学习和TFIDF的情感分类算法,详解自然语言处理
摘要:这篇文章将详细讲解自然语言处理过程,基于机器学习和TFIDF的情感分类算法,并进行了各种分类算法(SVM.RF.LR.Boosting)对比 本文分享自华为云社区<[Python人工智能] ...
- 机器学习中常见的六种分类算法(附Python源码+数据集)
今天和大家学习一下机器学习中常见的六种分类算法,如K近邻.决策树.朴素贝叶斯.逻辑回归.支持向量机.随机森林 除了介绍这六种不同分类算法外,还附上对应的Python代码案例,并分析各自的优缺点. 01 ...
最新文章
- 充电桩服务器协议,充电桩与云服务器通信协议
- server长时间运行query,Ajax刷新被block
- 浅析Java的“克隆”方法[zt]
- [剑指offer]面试题第[43]题[Leetcode][第233题][JAVA][1~n整数中1出现的次数][找规律][递归]
- html弹出保存文件对话框_初步了解CAD的模板文件
- 分享一个 pycharm 专业版的永久使用方法
- 【转】一个程序员分享8年的开发经验
- 实验室检测专用计算机的维护保养,计算机实验室维护与管理.doc
- html左斜杠转义字符,html的右斜杠转义符号是什么呢
- 熵权法stata程序
- siteserver/sscms 首页新闻排版及代码(二)
- AMD CPU 运行 Android Studio 原生模拟器的几点注意事项
- 手机游戏无障碍设计——猜地鼠之Android篇
- 四、Scala从入门到精通一一循环控制
- Java基础语法(三)——运算符
- java志愿者活动招募申请报名系统springbootboot
- 如何编写自己的头文件
- 9、共享变量(Broadcast Variable和Accumulator)
- python学习爬虫之删除无用字符以及空白替换等()
- iOS app可视化开发(一)使用Xcode创建app
热门文章
- SQL Server 表变量和临时表的区别
- oracle 11gr2 bbed 安装,oracle11gR2 安装bbed工具
- windows系统如何查看端口被占用、杀进程
- Git强制覆盖还原本地救火命令
- linux由哪些部分组成,linux内核处于什么位置?,为你介绍一些Linux操作系统的基础知识(一)...
- java通过jxl处理execl空行_jxl操作Excel导入数据库之空行的处理
- 移动端、微信小程序页面布局参考
- PHP中empty,is_null,isset的区别
- php推荐码生成,最新最全PHP生成制作验证码代码详解(推荐),验证码详解_PHP教程...
- 前端预览word文件_[装机必备] QuickLook —— 敲击空格即可快速预览文件