感知机(python实现)
感知机(perceptron)是二分类的线性分类模型,输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。感知机的学习算法具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。感知机由Rosenblatt于1957年提出的,是神经网络和支持向量机的基础。
行文脉络
- 感知机模型
- 感知机学习策略
- 感知机学习算法
- 原始形式
- 对偶形式
4. Github地址
1. 感知机模型
定义
假设输入空间(特征向量)为X⊆Rn,输出空间为Y={-1, +1}。输入x∈X表示实例的特征向量,对应于输入空间的点;输出y∈Y表示示例的类别。由输入空间到输出空间的函数为
f(x)=sign(w·x + b) (1)
称为感知机。其中,参数w叫做权值向量,b称为偏置。w·x表示w和x的内积。sign为符号函数,即
(2)
几何解释
感知机模型是线性分类模型,感知机模型的假设空间是定义在特征空间中的所有线性分类模型,即函数集合{f|f(x)=w·x+b}。线性方程 w·x+b=0对应于特征空间Rn中的一个超平面S,其中w是超平面的法向量,b是超平面的截踞。这个超平面把特征空间划分为两部分。位于两侧的点分别为正负两类。超平面S称为分离超平面,如下图:
学习与预测
感知机学习即由训练数据集T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N)求得感知机模型(1),即求得参数w,b;感知机预测即根据得到的感知机模型(1),对新的输入实例给出对应的类型。
2. 感知机学习策略
假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据的正负实例点完全分开的分离超平面,即最终求得参数w、b。这需要一个学习策略,即定义(经验)损失函数并将损失函数最小化。
损失函数的一个自然的选择是误分类的点的总数。但是这样得到的损失函数不是参数w、b的连续可导函数,不宜优化。损失函数的另一个选择是误分类点到分里面的距离之和。
首先,对于任意一点xo到超平面的距离为
(3)
其次,对于误分类点(xi,yi)来说 -yi(w·xi+b)>0
这样,假设超平面S的总的误分类点集合为M,那么所有误分类点到S的距离之和为
(4)
不考虑1/||w||,就得到了感知机学习的损失函数。
经验风险函数
给定数据集T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N),感知机sign(w·x+b)学习的损失函数定义为
(5)
其中M为误分类点的集合,这个损失函数就是感知机学习的经验风险函数。
显然,损失函数L(w,b)是非负的。如果没有误分类点,那么L(w,b)为0,误分类点数越少,L(w,b)值越小。一个特定的损失函数:在误分类时是参数w,b的线性函数,在正确分类时,是0.因此,给定训练数据集T,损失函数L(w,b)是w,b的连续可导函数。
3. 感知机学习算法
最优化问题:给定数据集T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N),求参数w,b,使其成为损失函数的解(M为误分类的集合):
(6)
3.1 感知机学习的原始形式
感知机学习是误分类驱动的,具体采用随机梯度下降法。首先,任意选定w0、b0,然后用梯度下降法不断极小化目标函数(6),极小化的过程不知一次性的把M中的所有误分类点梯度下降,而是一次随机选取一个误分类点使其梯度下降。
假设误分类集合M是固定的,那么损失函数L(w,b)的梯度由(7)(8)给出
(7)
(8)
随机选取一个误分类点(xi,yi),对w,b进行更新:
(9)
(10)
式中η(0≤η≤1)是步长,在统计学是中成为学习速率。步长越大,梯度下降的速度越快,更能接近极小点。如果步长过大,有可能导致跨过极小点,导致函数发散;如果步长过小,有可能会耗很长时间才能达到极小点。
算法(感知机学习算法的原始形式)
输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-, +},i=,...N,学习速率为η)
输出:w, b;感知机模型f(x)=sign(w·x+b)
() 初始化w0,b0
() 在训练数据集中选取(xi, yi)
() 如果yi(w xi+b)≤
w = w + ηyixi
b = b + ηyi
() 转至()
直观解释:当一个实例点被误分类时,调整w,b,使分离超平面向该误分类点的一侧移动,以减少该误分类点与超平面的距离,直至超越该点被正确分类。
例1
对于训练数据集,其中正例点是x1=(3,3)T,x2=(4,3)T,负例点为x3=(1,1)T,用感知机学习算法的原始形式求感知机模型f(x)=w·x+b。这里w=(w(1),w(2))T,x=(x(1),x(2))T
解:构建最优化问题:
按照算法求解w, b。η=1
(1)取初值w0=0, b0=0
(2)对于(3,3):-(0+0)+0=0未被正确分类。更新w,b
w1=w0+1*y1·x1 = (0,0)T+1(3,3)T=(3,3)T
b1=b0+y1=1
得到线性模型w1x+b1 = 3x(1)+3x(2)+1
(3)返回(2)继续寻找yi(w·xi+b)≤0的点,更新w,b。直到对于所有的点yi(w·xi+b)>0,没有误分类点,损失函数达到最小。
分离超平面为x(1)+x(2)-3=0
感知机模型为 f(x)=sign(x(1)+x(2)-3)
在迭代过程中,出现w·xi+b=-2,此时,取任意一个点,都会是其小于0,不同的取值顺序会导致最终的结果不同,因此解并不是唯一的。为了得到唯一的超平面,需要对分离超平面增加约束条件,这就是支持向量机的想法。
实现代码
import os
import sys # An example in that book, the training set and parameters' sizes are fixed
training_set = [] w = []
b = 0
lens = 0
n = 0 # update parameters using stochastic gradient descent
def update(item):
global w, b, lens, n
for i in range(lens):
w[i] = w[i] + n * item[1] * item[0][i]
b = b + n * item[1]
print w, b # you can uncomment this line to check the process of stochastic gradient descent # calculate the functional distance between 'item' an the dicision surface
def cal(item):
global w, b
res = 0
for i in range(len(item[0])):
res += item[0][i] * w[i]
res += b
res *= item[1]
return res # check if the hyperplane can classify the examples correctly
def check():
flag = False
for item in training_set:
if cal(item) <= 0:
flag = True
update(item)
if not flag: #False
print "RESULT: w: " + str(w) + " b: "+ str(b)
tmp = ''
for keys in w:
tmp += str(keys) + ' '
tmp = tmp.strip()
modelFile.write(tmp + '\n')
modelFile.write(str(b) + '\n')
modelFile.write(str(lens) + '\n')
modelFile.write(str(n) + '\n')
modelFile.close()
os._exit(0)
flag = False if __name__=="__main__":
if len(sys.argv) != 4:
print "Usage: python perceptron.py n trainFile modelFile"
exit(0)
n = float(sys.argv[1])
trainFile = file(sys.argv[2])
modelFile= file(sys.argv[3], 'w')
lens = 0
for line in trainFile:
chunk = line.strip().split(' ')
lens = len(chunk) - 1
tmp_all = []
tmp = []
for i in range(1, lens+1):
tmp.append(int(chunk[i]))
tmp_all.append(tmp)
tmp_all.append(int(chunk[0]))
training_set.append(tmp_all)
trainFile.close()
for i in range(lens):
w.append(0) for i in range(1000):
check()
print "The training_set is not linear separable. "
3.2 感知机学习的对偶形式
对偶形式的基本想法是,将w,b表示成为实例xi和标记yi的线性组合的形式,通过求解其系数而得到w和b。不失一般性,将初始值w0,b0设为0.对误分类点(xi,yi)通过
w = w + ηyixi
b = b + ηyi
的转换逐步修该w,b,设修改了n次,则w,b关于(xi,yi)的增量分别为aiyixi和aiyi,这里ai=niη最终学习到的w,b可以表示为
实例点更新次数越多,意味着它距离分离超平面越近,也就越难正确分类。换句话说,这样的实例对学习结果影响很大。
算法(感知机学习算法的对偶形式)
输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N,学习速率为η)
输出:a,b;感知机模型f(x)=sign(w·x+b)
(1) 初始化w0,b0
(2) 在训练数据集中选取(xi, yi)
(3) 如果
ai = ai + η
b = b + ηyi
(4) 转至(2)
对偶形式中训练数据仅以内积的形式出现,为了方便可以预先把训练数据间内积计算出来并以矩阵的形式存储起来,这个矩阵就是所谓的Gram矩阵。
实现代码
import os
import sys # An example in that book, the training set and parameters' sizes are fixed
training_set = [] w = []
a = []
b = 0
lens = 0
n = 0
Gram = [] def calInnerProduct(i, j):
global lens
res = 0
for p in range(lens):
res += training_set[i][0][p] * training_set[j][0][p]
return res def AddVector(vec1, vec2):
for i in range(len(vec1)):
vec1[i] = vec1[i] + vec2[i]
return vec1 def NumProduct(num, vec):
for i in range(len(vec)):
vec[i] *= num
return vec def createGram():
global lens
for i in range(len(training_set)):
tmp = []
for j in range(0, len(training_set)):
tmp.append(calInnerProduct(i, j))
Gram.append(tmp) # update parameters using stochastic gradient descent
def update(k):
global a, b, n
a[k] += n
b = b + n * training_set[k][1]
print a, b # you can uncomment this line to check the process of stochastic gradient descent # calculate the functional distance between 'item' an the dicision surface
def cal(k):
global a, b
res = 0
for i in range(len(training_set)):
res += a[i] * int(training_set[i][1]) * Gram[i][k]
res += b
res *= training_set[k][1]
return res # check if the hyperplane can classify the examples correctly
def check():
global w, a
flag = False
for i in range(len(training_set)):
if cal(i) <= 0:
flag = True
update(i) if not flag: #False
for i in range(len(training_set)):
w = AddVector(w, NumProduct(a[i] * int(training_set[i][1]), training_set[i][0]))
print "RESULT: w: ", w, " b: ", b
tmp = ''
for keys in w:
tmp += str(keys) + ' '
tmp = tmp.strip()
modelFile.write(tmp + '\n')
modelFile.write(str(b) + '\n')
modelFile.write(str(lens) + '\n')
modelFile.write(str(n) + '\n')
modelFile.close()
os._exit(0)
flag = False if __name__=="__main__":
if len(sys.argv) != 4:
print "Usage: python perceptron_duality.py n trainFile modelFile"
exit(0)
n = float(sys.argv[1])
trainFile = file(sys.argv[2])
modelFile= file(sys.argv[3], 'w')
lens = 0
for line in trainFile:
chunk = line.strip().split(' ')
lens = len(chunk) - 1
tmp_all = []
tmp = []
for i in range(1, lens+1):
tmp.append(int(chunk[i]))
tmp_all.append(tmp)
tmp_all.append(int(chunk[0]))
training_set.append(tmp_all)
trainFile.close() createGram()
for i in range(len(training_set)):
a.append(0)
for i in range(lens):
w.append(0) for i in range(1000):
check()
print "The training_set is not linear separable. "
4. GitHub地址
https://github.com/jihite/Perceptron-python-
感知机(python实现)的更多相关文章
- 感知机-Python实现
如图3所示的训练数据集,其正实例点是(3,3),(3,4),负实例点是(1,1),试用感知机学习算法的原始形式求感知机模型,即求出w和b.这里, 图3 这里我们取初值,取.具体问题解释不写了,求解的方 ...
- 统计学习方法 | 感知机 | python实现
感知机是二类分类的线性分类模型,利用随机梯度下降法对基于误分类的损失函数进行极小化. 书中算法可以将所有样本和系数向量写成增广向量的形式,并将所有负样本乘以-1,统一形式,方便计算. (1)训练数据集 ...
- Python实现PLA(感知机)
Python实现PLA(感知机) 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) 计算过程 st=>start: 开始 e=>end o ...
- 利用Python实现一个感知机学习算法
本文主要参考英文教材Python Machine Learning第二章.pdf文档下载链接: https://pan.baidu.com/s/1nuS07Qp 密码: gcb9. 本文主要内容包括利 ...
- python 实现简单的感知机
最近在自学机器学习,记录下一些学习记录 如何用python实现一个简单的感知机 需要安装numpy库,即下面用到的np 简单的说就是 通过计算权重向量w和输入向量x的线性组合,判断该线性组合是否大于某 ...
- (数据科学学习手札34)多层感知机原理详解&Python与R实现
一.简介 机器学习分为很多个领域,其中的连接主义指的就是以神经元(neuron)为基本结构的各式各样的神经网络,规范的定义是:由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系 ...
- 使用Python来编写一个简单的感知机
来表示.第二个元素是表示期望输出的值. 这个数组定义例如以下: training_data = [ (array([0,0,1]), 0), (array([0,1,1]), 1), (arra ...
- python实现感知机线性分类模型
前言 感知器是分类的线性分类模型,其中输入为实例的特征向量,输出为实例的类别,取+1或-1的值作为正类或负类.感知器对应于输入空间中对输入特征进行分类的超平面,属于判别模型. 通过梯度下降使误分类的损 ...
- 统计学习方法与Python实现(一)——感知机
统计学习方法与Python实现(一)——感知机 iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 1.定义 假设输入的实例的特征空间为x属于Rn的n维特征向量, ...
随机推荐
- 在Action中以Struts2的方式输出JSON数据
参考地址;http://blog.csdn.net/itdada/article/details/21344985
- 关于django批量上传图片
本来想一张一张上传的,但是明显会对客户造成不必要的麻烦,所以如果前台一次性上传五张十张的话,那就简单的多. 但是后台我数据库对于图片存储的字段只有一个,不可能有多少张照片就要多少个字段来存储.也就是说 ...
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树
题目链接: http://codeforces.com/contest/703/problem/D D. Mishka and Interesting sum time limit per test ...
- HDU 5795 博弈
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5795 A Simple Nim Time Limit: 2000/1000 MS (Java/Oth ...
- 【BZOJ】【3166】【HEOI2013】Alo
可持久化Trie+set Orz zyf…… 搞区间中次大值不好搞,那么我们就反过来,找一个数,然后看它在哪些区间里是次大值…… (然而事实上我们并不用真的把这个区间具体是什么找见,只要知道它可以跟哪 ...
- 【BZOJ】【1030】【JSOI2007】文本生成器
AC自动机/DP Orz ZYF 玛雅快要省选了,赶紧复(xue)习(xi)一下AC自动机…… 其实在AC自动机上DP并没有当初想的那么复杂……就是把DP的转移关系换成了AC自动机上的边而已(不过这题 ...
- 【BZOJ】【2038】小Z的袜子
填个坑吧,学习了莫队算法.我也忘记是看的哪位大牛的博客&代码学习的了T_T,如果您发现了的话请私信我,我会注明学自您的代码. 另外感谢@PoPoQQQ大神 好,进入正文,莫队算法,也算是一种暴 ...
- 剑指offer--面试题23
//该题原本想用递归实现,但却用循环实现了... //关键用了个队列 #include <queue> void Print(BinaryTreeNode* pRoot, std::que ...
- hadoop,spark,linux上常用命令
记下常用命令,慢慢补充 1.hadoop 查看hdfs上的目录: hadoop fs -ls /给hdfs上目录授予权限: hadoop fs -chmod 777 /tmp/hive 在hdfs ...
- hdu 2999 Stone Game, Why are you always there? 博弈论
SG函数应用!! 代码如下: #include<cstdio> #include<cstring> #include<iostream> #include<c ...