1.感知机模型原理
感知机模型是用于二分类的线性分类模型,输入为实例的特征向量,输出为实例的类别,取+1和-1值,即:
f(x) = sign(w · x +b)
其中x∈ R n,y∈{-1,+1}。
感知机模型为一个线性分类模型,当w · x +b==0时,对应于特征空间 R n中的一个超平面S,w为超平面的法向量,b为超平面的截距。而正是通过超平面S将特征空间Rn中的x分开的。
R2特征空间中的超平面S如下所示:
2.感知机学习策略
通过上述介绍,对于线性可分的数据集,我们需要求的就是超平面S,即求出w和b。而为了求出超平面S,我们需要定义损失函数以及对其进行最小化。
损失函数选取误分类点到超平面的总距离,首先任意一点到超平面S的距离为
上述为点到平面的几何间隔,||w||为w的L2范式,选取几何间隔的原因是为了距离能够不随w和b变化,因此除以||w||。
而这里不考虑||w||的原因是感知机模型为误分类驱动,当分类完全正确时,此时||w||不论为多少,上述结果均为0。因此可以不用考虑||w||。
3.感知机学习算法
1)原始形态
主要采用梯度下降法进行优化目标函数,我们的目标函数为:
然后需要选择分类错误的点(y((w·x)+b)<=0),然后利用上述点对目标函数进行梯度下降,同时我们采用随机梯度下降(即每次选取一个点):
感知机模型的学习算法原始形式可总结为:
2)对偶形态
感知机的原始形态和对偶形态与SVM的原始形态和对偶形态相对应:
4.代码实现
利用mnist 数据集,仅实现了原始形态:
import numpy as np
import datetime
'''
实验结果
time_cost 131
currencies: 0.8141
'''
def load_data(fileName):#加载数据
print("start read data")
fr = open(fileName,'r')
dataX=[];dataY=[]
for line in fr.readlines():
lineArr=[]
curline = line.strip().split(',')
if curline[0]>= '5' :#标签数据生成
dataY.append(1)
else:
dataY.append(-1)
dataX.append([int(num)/255 for num in curline[1:]])#特征 int(num)/255——进行min-max标准化
#print(dataX)
return dataX,dataY
def perceptron(dataX,dataY,t,iter=50):
w=[0.0]*len(dataX[0]);b=0.0# w和b初始化为0
w = np.mat(w)
round = 0#记录迭代次数
while(1):
flag = 0#标记是否完全分类正确
time = 0#记录每次迭代出错的用于训练的数目
round+=1
for i in range(len(dataY)):
x = np.mat(dataX[i])
if dataY[i]*(w*x.T+b)<=0:#y(w*x+b)<=0 出错 用于训练
w = w + t*dataY[i]*x
b = b + t*dataY[i]
flag = 1
time+= 1
print("第%d轮第%d次" % (round, time))
if flag == 0 or round==iter:#直到所有均分类正确即可结束循环或者得到迭代上限结束运算
break
return w,b
def perceptron1(dataX,dataY,t,iter=50):#另一种更加规范的实现方式 参考了https://github.com/Dod-o/Statistical-Learning-Method_Code
dataMat = np.mat(dataX)
labelMat = np.mat(dataY).T
m,n = np.shape(dataMat)
w = np.zeros((1,np.shape(dataMat)[1]))
b=0
for i in range(iter):
for j in range(m):
x = dataMat[j]
y = labelMat[j]
if y*(w*x.T+b)<=0:
w = w + t * y*x
b = b + t * y
print("Round%d:%d training" % (i, iter))
return w,b
if(__name__ == '__main__'):
trainX,trainY = load_data("./mnist_train/mnist_train.csv")
start = datetime.datetime.now()
w,b = perceptron1(trainX,trainY,0.0001,50)#进行训练
end = datetime.datetime.now()
print("time_cost",(end-start).seconds)
testX,testY = load_data("./mnist_test/mnist_test.csv")#进行测试
cur = 0
for i in range(len(testX)):
x = np.mat(testX[i])
res = -1 if (w*x.T+b)<0 else 1
if(res==testY[i]):
cur+=1
print("currencies:",float(cur/len(testX)))
5.总结
似乎还是参考的比较多一些。。。,但可能在写的过程中又是一次总结复习吧,希望能够更加用心一些。
6.参考文献
1.《统计学习方法》
2.https://www.pkudodo.com/2018/11/18/1-4/