机器学习初探之感知机
监督学习
我么们知道机器学习就是让机器跟人类一样去学习东西。我们人类是怎样去学习呢?简单的说,就是有老师传授我们知识,带着我们学习(比如说带领我们认识世界上的各种动物,如、熊猫、老虎、猫咪和小狗)。然后呢,通过不断的学习和总结,我们形成了自己的知识架构(即对这些动物能够进行很好的判别),当我们去动物园参观动物时能够知道这些动物的名字。
如下图所示:
其实机器学习和人类的学习方式一样。只不过在这里我们需要设计一个机器学习的算法,通过对这个算法输入大量的学习资料可以生成一个模型,当输入新的任务时,这个模型可以做出判别,输出结果。
如下图所示:
以上就是机器学习的一个大概流程和思路。 不说废话,下面来介绍机器学习的感知机内容。------参考李航老师著的《统计学习方法》这本书。
一、感知机简介
今天来学习下机器学习的敲门砖——感知机模型。感知机是在1957年由Frank Rosenblatt提出的,它被成为机器学习领域最为基础的模型。虽然是最为基础的,但是它在机器学习的领域中,有着举足轻重的地位,它是SVM(支持向量机)和NN(神经网络)学习的基础,可以说它是最古老的分类方法之一了。
在机器学习中,感知机(perceptron)是二分类的线性分类模型属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。
其实感知机的思想很好理解,比如我们在一个屋子里有很多的男人和女人,感知机的模型就是尝试找到一条直线,能够把所有的男人和女人隔离开。放到三维或者更高维的空间,感知机的模型就是尝试找到一个超平面,能够把所有的二元类别隔离开。当然,如果我们找不到这么一条直线的话怎么办?找不到的话那就意味着类别线性不可分,也就意味着感知机模型不适合你的数据的分类。预先对数据可视化进行观看进而判断能不能使用感知机的二分类模型。
所以,使用感知机一个最大的前提,就是数据是线性可分的,这严重限制了感知机的使用场景。它的分类竞争对手在面对不可分的情况时,比如支持向量机可以通过核技巧来让数据在高维可分,神经网络可以通过优化**函数、增加隐藏层和支持多输出,来让数据可分。
二、感知机模型理论
假设输入空间(特征向量)为,输出空间为Y={-1, +1}。输入表示实例的特征向量,对应于输入空间的点;输出表示示例的类别。由输入空间到输出空间的函数为:
称为感知机。其中,参数w叫做权值向量,b称为偏置。w⋅x表示w和x的点积。
sign为符号函数,即
在二分类问题中,f(x)的值(+1或-1)用于分类x为正样本(+1)还是负样本(-1)。感知机是一种线性分类模型,属于判别模型。我们需要做的就是找到一个最佳的满足w⋅x+b=0的w和b值,即分离超平面(separating hyperplane)。如下图,一个线性可分的感知机模型
中间的这条直线为w⋅x+b=0
三、感知机的学习策略
如果训练集是可分的,感知机的学习目的是求得一个能将训练集正实例点和负实例点完全分开的分离超平面。为了找到这样一个平面(或超平面),即确定感知机模型参数w和b,我们需要一个学习策略,即定义损失函数并将损失函数极小化。
在这里感知机十分巧妙的选择里误分类点到超平面S的总距离作为损失函数,首先我们写出输入空间中任一点到超平面S的距离:
对与误分类的点来说,我们总可以得到
那么所有误分类点到超平面的距离为:
为了简化运算,不考虑,我们可以得到感知机的损失函数:
其中M为误分类点的集和。
可以看出,损失函数L(w,b)是非负的。如果没有误分类点,则损失函数的值为0,而且误分类点越少,误分类点距离超平面就越近,损失函数值就越小。同时,损失函数L(w,b)是连续可导函数。由此可以对损失函数进行梯度下降法,不断优化W和b值,从而得到最优解。
在这里我用的数据集是mnist的数字数据集,将>=5作为1,<5作为-1 此为标签。进行分类
import numpy as np
import time
# 首先载入数据
def loaddata(filename):
'''
输入:
filename为数据集的路径
输出:
list形式的标签和数据
'''
labelArr=[];dataArr=[]
fr=open(filename,'r') #读取数据
for line in fr.readlines():
lineArr=line.strip().split(',')
# 由于minst的数据集是0-9数字的标记,由于感知机模型为二分类的任务,
#所以将>=5作为1,<5作为-1 此为标签
if int(lineArr[0])<5:
labelArr.append(-1)
else:
labelArr.append(1)
dataArr.append([int(num)/255 for num in lineArr[1:]]) #对数据进行归一化了,嗯嗯 其实没什么用
return dataArr,labelArr
#训练模型
def percepton(dataArr,labelArr,iter=50):
'''
输入:
训练数据、训练标签和迭代次数
输出:
权重w和偏重b
'''
datamat=np.mat(dataArr) #60000*784
labelmat=np.mat(labelArr).T #需要确定矩阵的行列数#60000*1
m,n=np.shape(datamat)
#初始化权重w和偏置(bias) 都初始为零 h为学习率
w=np.zeros((1,np.shape(datamat)[1]))
b=0
h=0.001
for k in range(iter):
#遍历每一个数据,一共有m个数据
for i in range(m):
#获取当前样本的向量
xi=datamat[i]
yi=labelmat[i]
#判断是否是误差分类的样本 对于误分类的数据来说-y(wx+b)>0
#如果是误差分类的样本的话需要进行梯度下降算法更新w和b
if -yi*(w*xi.T+b)>=0:
w=w+h*yi*xi
b=b+h*yi
return w,b
#测试模型
def test_model(dataArr, labelArr, w, b):
'''
输入:
测试数据、测试标签、权重w和b
输出:
分类的正确率
'''
datamat=np.mat(dataArr)
labelmat=np.mat(labelArr).T
m,n=np.shape(datamat)
error_num=0
for i in range(m):
xi=datamat[i]
yi=labelmat[i]
result=-yi*(w*xi.T+b)
if result>=0:
error_num+=1
accurate=1-(error_num/m)
return accurate
#返回样本分类的正确率
if __name__=='__main__':
start=time.time()
traindata,trainlabel=loaddata('./Mnist/mnist_train.csv')
testdata,testlabel=loaddata('./Mnist/mnist_test.csv')
#训练获得的权重
w,b=percepton(traindata,trainlabel,iter=30)
#进行测试获得正确率
accurate=test_model(testdata,testlabel,w,b)
end=time.time()
print('accuracy is :',accurate)
print('time span:',end-start)
上一篇: php通过获取头信息判断图片类型的方法,_PHP教程
下一篇: cookie和session的关系