[python]感知机学习算法实现

来源:互联网 发布:网络新媒体的传播特征 编辑:程序博客网 时间:2024/05/15 01:06

模型

  • 感知机模型是属于二分类的线性判别模型,旨在找到一个线性超平面,能将正负实例划分开来。
    f(x)=sign(wx+b)

学习策略

  • 学习策略即定义(经验)损失函数并将损失函数最小化
  • 感知机的学习策略是基于误分类点到超平面的距离之和
  • 经验损失函数如下:
    L(w,b)=xiMyi(ωxi+b)

    其中M为误分类点的集合,

学习算法

  • 感知器算法是误分类驱动的,具体采用随机梯度下降法。首先,任意选取一个超平面w0,b0,然后利用梯度下降不断极小化目标函数,极小化过程中不是一次使M中所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降.损失函数的梯度L(ω,b)的梯度由
    wL(ω,b)=xiMyixibL(ω,b)=xiMyi

    给出
  • 随机选取一个误分类点(xi,yi),对w,b进行更新:
    ww+ηyixibb+ηyi

    公式中η(0<η1)是步长,在统计学中又称为学习率。通过迭代可以期待损失函数L(ω,b)不断减小,直到为0,综上所述,得到如下算法:
    算法2.1(感知器学习算法的原始形式)
    :T=(x1,y1),(x2,y2),,(xN,yN)xiχ=Rn,yiψ={1,+1}
    输出:w,b;感知机模型 f(x)=sign(wx+b)
    (1)任意选取w0,b0,例如可以设置为w0=0,b0=0
    (2)在训练数据集中选取数据(xi,yi)
    (3)计算yi(wixi+b)如果yi(wixi+b)0
    ww+ηyixibb+ηyi

    (4)转至(2),直至训练集中没有误分类点

特点

  • 感知机学习算法简单易于实现,在原始形式中,首先任意选取一个超平面,然后使用梯度下降算法不断极小化目标函数。在这个过程中一次随机选取一个误分类点使其梯度下降
  • 当训练数据集是线性可分时,感知机学习算法是收敛的,并且存在无穷多个解,而且误分类次数满足不等式:
    k(Rγ)2

    其中γ表示所有分类模型中能将数据集分开的超平面,而且||wi||=1,函数间隔的最小值,R=max1iN||x^i||

实现参考代码如下

# -*- coding: utf-8 -*-"""Created on Tue Apr 18 08:56:56 2017感知机算法实现@author: Administrator"""import numpy as npfrom sklearn.metrics import accuracy_scoreclass myPreception:    def __init__(self,X,y):        self.X=X        self.y=y    def dot(self,xi,w,b):        yPre =  np.dot(w,xi)+b        return int(yPre)    def prediction(self):        length = np.shape(self.X)[0]        a = 1        w=np.zeros([self.X.shape[1],1])        print np.shape(w)        b=0        flag =True        while flag:            count = 0            for i in xrange(length):            #print np.shape(self.X[i])                if self.y[i] ==0:                    self.y[i] = -1                tempY=self.dot(self.X[i,:],w.T,b)                #print tempY,self.X[i,:],self.y[i]                print tempY                if self.y[i]*tempY <= 0:                    tmp = a*self.y[i]*self.X[i]                    tmp = tmp.reshape(w.shape)                    w += tmp                    b += a*self.y[i]                    count+=1                    print w,b            if count ==0:                flag = False        return w,bdef loadDataSet(filename):    data = []     labels=[]      fr = open(filename,'r')    for line in fr:        lineArray = line.strip().split('\t')        data.append([float(lineArray[0]),float(lineArray[1])])        labels.append(float(lineArray[2]))    return np.array(data),np.array(labels)def predict(test_data,w,b):    labels=[]    result = 0    for x in test_data:        #print x,w,np.array(x)        result = np.dot(w.T,np.array(x))+b        print 'result=',result        if result > 0:            result = 1        else:            result = 0        labels.append(result)    return np.array(labels)if __name__ == '__main__':    data,labels=loadDataSet('testSet.txt')    #print labels[1]*data[1,:]    print data.shape    #np.reshape(labels,[np.shape(labels,1)])    #print np.shape(data)   # print data[1]    print np.shape(labels)    mp =myPreception(data,labels)    w,b=mp.prediction()    print w,b    label_pre = predict(data[0:100],w,b)    score = accuracy_score(labels[0:100],label_pre)    print score    x1=np.array([[7,2]])    pre_x1=predict(x1,w,b)    print pre_x1
0 0