记一下机器学习笔记 Rosenblatt感知机

原创 2016年05月31日 21:18:42

一入ML深似海啊…
这里主要是《神经网络与机器学习》(Neural Networks and Learning Machines,以下简称《神机》)的笔记,以及一些周志华的《机器学习》的内容,可能夹杂有自己的吐槽,以及自己用R语言随便撸的实现。
话说这个《神经网络与机器学习》还真是奇书,不知是作者风格还是翻译问题,一眼望去看不到几句人话(也许是水利狗看不懂),感觉我就是纯买来自虐的。
作为开始当然是最古老的机器学习算法之一,神经网络的板砖感知机,对应《神机》的第一章。

因为是Rosenblatt提出的模型所以就加上了他名字作为前缀。这是一个有监督学习,也就是不仅给出自变量还要给出结果值让机器自个拟合的模型,而且是一个二分类模型。再说清楚一点,这玩意只能分线性可分的样本,也就是对于二维的数据,它只能搞一条直线把样本分开,对于三维的数据,只能搞个平面把样本分开。
所以像居然连异或运算都不能弄之类的对它的吐槽历来不少。

感知机概念


感知机由一个线性组合器(说白了就是把一系列输入值加权求和)以及一个硬限幅器(说白了就是拿前面的求和取符号)组成。具体样子参考下图(来自《神机》):
这里写图片描述
我们将一组输入值记为x1,x2,...,xm,相应的权值记为w1,w2,w3...wm,另外还要有个偏置值b(相当于线性回归里边的截距)。把这些输入到感知机里边进行加权求和:

v=i=1mwixi+b

加权和v称为诱导局部域
然后对这个v取符号,也就是大于0取1,小于0取-1,就这样决定这组输入值归为哪类:
y=sign(v)

y={+11xC1xC2.

可以用逼格更高的矩阵形式简洁表示:
y=sign(wTx+b)

xw就是把w1,w2,w3...wmx1,x2,...,xm写成一列阵,然后把前者转置为横阵再两矩阵相乘,也就是两者对应的每一项相乘再求和。
那么每组输入值x就各是一个样本。

又或者从几何角度理解:在m维空间上有这么一个超平面wTx+b=0x=[x1,x2,...,xm]T是这个空间上的一个点,这个点在超平面的一边归为一类,若在另一边归为另一类。

所以说样本必须线性可分的才可以被它分类。

感知机收敛定理


然后这玩意的学习方式是不断的误差修正,称为误差修正学习原则
当一个样本被正确分类的时候就没啥事,要是被错误分类了就根据样本的各个分量调整权值,就这样把整套样本丢进去跑几趟直到误差收敛为止。
现在干脆把偏置b弄进样本x里去,定义第n个输入样本:

x(n)=[+1,x1(n),x2(n),...,xm(n)]T

然后根据迭代步数n把权值向量这样定义:
w(n)=[w0(n),w1(n),w2(n),...,wm(n)]T

其中w0(n)即对应偏置b。这样输出可以简约的改成:
v(n)=i=1mwi(n)xi(n)=w(n)Tx(n)

经过学习之后的感知机应该有这么一套权值w

wTx>0wTx0xC1xC2.

所以感知机的权值修改策略是这样子的:
w(n+1)w(n)w(n+1)w(n)wTx>0xC1,wTx0xC2.
也就是正确分类样本x的时候不修改权值w
否则如果分类错了,就进行如下修改:
w(n+1)=w(n)η(n)x(n)w(n+1)=w(n)+η(n)x(n)wTx>0xC2,wTx0xC1.

也就是分类错误的时候就把权值向量w相应的加上或减去该次迭代的乘上一个系数η后的输入样本向量x
其中系数η称为学习率参数

将一批N个样本挨个输入到感知机中挨个调整权值的过程称为一次迭代,迭代的过程就是把这批样本不断输进去重复迭代多次。只要这些样本是线性可分的,那么经过若干次迭代之后最终必定能让感知机正确分类全部样本,也就是收敛。这就是感知机收敛定理。
证明详见《神机》第1.3节…

具体一点,将d(n)定义为量化的第n个样本应归的类,称为量化期望响应,即:

d(n)={+11xC1xC2.

那么权值向量w(n)的逐步修正可以这样表示:
w(n+1)=w(n)+η[d(n)y(n)]x(n)

d(n)y(n)为误差信号,学习率参数η是正常数,值大于0并小于等于1。在这里可以这样理解,上式右边的后半部分里,[d(n)y(n)]x(n)定义的是修正权值一个方向,而η定义的是朝着这个方向走的一步的大小。
所以学习率参数η的大小设定一直都是纠结的,太大了走起来不稳定,太小了又走得太慢…

R代码实现


我知道不用Python而是用R这么个非主流的语言一定会有很多人吐槽,毕竟R的可读性是硬伤…这里使用R的原因有二:一是借助R原生的向量和矩阵运算功能和其他各种统计函数实现起来可以简洁些,二是我实在是不熟悉Python…
《神机》上边演示各种算法时用的是一对非对称的面对面又有些错开的“双月牙”二维数据集,分布在上月牙的样本归为一个类,下月牙的归为另一个类,然后用各种算法分离这两个月牙。

首先生成双月数据集,先设定样本数量为2000,两个月牙距离为1,半径10,宽度6,样本坐标为月牙内随机生成:

library(ggplot2)# 先导入作图包

R = 10 #月牙半径
wid = 6 #月牙宽度
dis = 1 #月牙距离

N = 2000 #样本数量
i = 0
x1=c()
x2=c()
d=c() #

# 在月牙范围内随机生成点
while(i < N/2){
  xi = runif(1,-R-wid/2,R+wid/2); xj = runif(1,0,R+wid/2)
  r = sqrt(xi*xi+xj*xj)
  if(R+wid/2 >= r && R-wid/2 <= r){
    i=i+1
    x1[i]=xi; x2[i]=xj; d[i]=-1
  }
}#生成上半月牙
while(i < N){
  xi = runif(1,-wid/2,2*R+wid/2); xj = runif(1,-dis-R-wid,-dis)
  r = sqrt((xi-R)*(xi-R)+(xj+dis)*(xj+dis))
  if(R+wid/2 >= r && R-wid/2 <= r){
    i=i+1
    x1[i]=xi; x2[i]=xj; d[i]=1
  }
}#生成下半月牙

# 没什么特别的,就是拿来打乱数据顺序
rndodr = order(runif(N))
x1=x1[rndodr]
x2=x2[rndodr]
d=d[rndodr]

qplot(x1,x2,color=factor(d))#可视化

# 生成矩阵形式的数据集
dat = as.matrix(data.frame(x1,x2))

其中x1和x2分别是样本点的横纵坐标,d为样本点的归类。
可视化之后如下:
这里写图片描述

然后就是定义感知机和训练。根据《神机》分类误差用均方差表示。

# 感知机,输入为一个长度2的向量。
perceptron = function(x) sign(t(w) %*% c(x,+1))
# 之所以将偏置项+1放到最后面是因为R是从1开始索引的而不是0...

w=c(0,0,0) # 初始化权值
n=50 #迭代次数
eta = seq(1e-1,1e-5,length.out = n)#学习率参数eta设为从1E-1到1E-5的线性退火

MSE = c()#记录每次迭代后的均方差
# 训练
for(j in 1:n){

  for(i in 1:N){
    x = dat[i,]
    y = perceptron(x)
    w = w + eta[j] * (d[i] - y) * c(x,1)
  }# 丢入数据集中的每一个数据进行训练

  # 迭代完一次就对数据集进行分类然后计算均方差
  e = d - apply(dat,1,perceptron)
  mse = sqrt(sum(e*e)/n)
  MSE=append(MSE,mse)
}

训练完输出结果:

# 绘制均方差随迭代次数的变化曲线
qplot(x=c(1:n),y=MSE,geom = 'line')

# 绘制直观的样本划分情况
y = apply(dat,1,perceptron)
qplot(x1,x2,color=factor(y)) + geom_abline(intercept = -w[3]/w[2], slope = -w[1]/w[2])

# 统计误识别率
length(e[e!=0])/N

然后这是训练完的分类结果。
这里写图片描述
可见感知机很轻易的就把俩月牙完好得分开了。

这里写图片描述
再看均方根误差的变化曲线,可以看到第一轮迭代就已经收敛。


之后再试试俩月牙的距离为0的情况。这时俩月牙情况如下:
这里写图片描述

经过50轮迭代之后也顺利收敛,误识别率依然为0(因为随机生成点的关系不太可能有几个点同时在边界上)。
这里写图片描述

可以看到大概是在第20轮迭代之后收敛的。
这里写图片描述


再接下来就试试月牙间距离为-4的情况。这时候俩月牙已经不是线性可分了,看看感知机会如何整?
这里写图片描述

迭代完发现虽然不能做到但是感知机还是尽力地让俩月牙的点尽量分开了,于是成了这个样子。
这里写图片描述

均方根误差是酱紫抖动的。
这里写图片描述
再看看误识别率:

> length(e[e!=0])/N
[1] 0.0945

有9.45%的样本被错误分类了。


顺便附上月牙距离分别为0和-4时感知机训练过程的动图:
这里是距离为0的:
这里写图片描述

这里是距离为-4的:
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

感知机(perceptron)算法与MATLAB实现

参考:http://blog.csdn.net/xmu_jupiter/article/details/21884501感知机策略: 选取w和b,使得误分类点到分类超平面S的总距离最小,即min ...

感知机(Perceptron)

之前的线性回归的概率解释中,假设样本的概率密度函数的参数形式是已知的,然后需要基于样本,使用参数估计的方法来估计概率密度函数的参数值;这里的感知机算法和前一篇文章《LR回归》,都是直接假设判别函数的参...
  • daunxx
  • daunxx
  • 2016年07月04日 16:47
  • 2273

Rosenblatt感知机-神经网络与机器学习笔记1

一、Rosenblatt感知机小结感知机模型 输入向量:x(n)=[+1,x1(n),x2(n),...,xm(n)]Tx(n)=[+1,x_1(n),x_2(n),...,x_m(n)]^T ...

Rosenblatt感知机-神经网络与机器学习笔记1

一、Rosenblatt感知机小结感知机模型 输入向量:x(n)=[+1,x1(n),x2(n),...,xm(n)]Tx(n)=[+1,x_1(n),x_2(n),...,x_m(n)]^T ...
  • redboom
  • redboom
  • 2017年03月29日 21:07
  • 56

简单易学的机器学习算法——Rosenblatt感知机

一、感知机的概念

简单易学的机器学习算法——Rosenblatt感知机的对偶解法

一、Rosenblatt感知机回顾

神经网络与机器学习笔记——Rosenblatt感知器

Rosenblatt感知器 感知器是用于线性可分模式(模式分别位于超平面两边)分类的最简单的神经网络模型,基本上由一个具有可调突触权值和偏置的神经元组成。 Rosenblatt证明了当用来训练感知器的...
  • LXYTSOS
  • LXYTSOS
  • 2015年05月01日 10:22
  • 4544

机器学习笔记(2)——感知机

Perceptron(感知机)感知机是二分类的线性分类器,属于判别模型。由Rosenblatt在1957年提出,是神经网络和支持向量机(SVM)的基础。感知机本身相当于神经网络中的一个神经元,只能进行...

统计机器学习笔记(一)---感知机模型

公共绘图部分import numpy as np from matplotlib import pyplot as plt from matplotlib import animation from ...

机器学习之感知机学习笔记第一篇:求输入空间R中任意一点X0到超平面S的距离

我的学习资料是“统计学习方法”,作者是李航老师,这本书很著名,百度有很多关于它的PDF。 作为学习笔记,就说明我还是属于学习中,所以,这个分类中我暂时不打算讨论详细的算法,这个分类会讲到我在学习遇到...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记一下机器学习笔记 Rosenblatt感知机
举报原因:
原因补充:

(最多只允许输入30个字)