统计学习方法2、感知机模型原理与实现

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,即求出wb。而为了求出超平面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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值