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

模型

  • 感知机模型是属于二分类的线性判别模型,旨在找到一个线性超平面,能将正负实例划分开来。
    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 np
from sklearn.metrics import accuracy_score

class 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,b


def 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


你可能感兴趣的:(机器学习,统计学习方法)