统计学习方法之感知机1.感知机模型2.学习策略3.学习算法4.源代码

时间:2022-05-08
本文章向大家介绍统计学习方法之感知机1.感知机模型2.学习策略3.学习算法4.源代码,主要内容包括1.感知机模型、2.学习策略、3.学习算法、4.源代码、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

1.感知机模型

  • 在机器学习中,感知机(perceptron)是二分类的线性分类模型,属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。感知机的学习算法具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。感知机由Rosenblatt于1957年提出的,是神经网络和支持向量机的基础。
  • 假设输入空间(特征向量)为X⊆Rn,输出空间为Y={-1, +1}。输入x∈X表示实例的特征向量,对应于输入空间的点;输出y∈Y表示示例的类别。由输入空间到输出空间的函数为

称为感知机。其中,参数w叫做权值向量weight,b称为偏置bias。w⋅x表示w和x的点积

sign为符号函数,即

  • 在二分类问题中,f(x)的值(+1或-1)用于分类x为正样本(+1)还是负样本(-1)。感知机是一种线性分类模型,属于判别模型。我们需要做的就是找到一个最佳的满足w⋅x+b=0的w和b值,即分离超平面(separating hyperplane)。如下图,一个线性可分的感知机模型

中间的直线即w⋅x+b=0这条直线。

2.学习策略

  • 感知机学习算法本身是误分类驱动的,因此我们采用随机梯度下降法。首先,任选一个超平面w0和b0,然后使用梯度下降法不断地极小化目标函数

3.学习算法

感知机学习算法={原始形式和对偶形式}

3.1原始形式

  • 输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N,学习速率为η) 输出:w, b;感知机模型f(x)=sign(w·x+b) (1) 初始化w0,b0,权值可以初始化为0或一个很小的随机数 (2) 在训练数据集中选取(x_i, y_i) (3) 如果yi(w xi+b)≤0 w = w + ηy_ix_i b = b + ηy_i (4) 转至(2),直至训练集中没有误分类点

4.源代码

  • 问题描述
  • data.csv
1,1,-1
0,1,-1
3,3,1
4,3,1
2,0.5,-1
3,2,1
4,4,1
1,2,-1
  • percetron.py
"""
# -*- coding: utf-8 -*-
"""
Created on Fri Dec  8 14:24:10 2017

@author: jasonhaven
"""
import numpy as np
import matplotlib.pyplot as plt


def sign(x,w,b):
    '''
    x:特征向量
    y:标记
    w:权值向量
    b:偏置
    功能:计算 y=w*x+b
    '''
    y=np.dot(x,w)+b#返回只有一个元素的ndarray
    return int(y)


def train(X,Y,w,b,yita):
    '''
    X:n维特征向量
    y:n维标记向量
    w:权值向量初始
    b:偏置初始
    yita:学习率
    功能:训练模型,计算优化模型参数(感知机算法的原始形式)
    '''
    flag = False #损失函数是否最小
    while not flag:
        count_error=0
        for i,xi in enumerate(X):
            yi=Y[i]
            signy=sign(xi,w,b)
            if signy*yi<=0:
                w+=(yita*yi*xi).reshape(w.shape)
                b+=yita*yi
                count_error+=1
        if count_error==0:
            flag=True
    return w,b
    

def draw(train_datas,sign_of_train_datas,w,b):
    plt.figure('percetron')
    #设置横坐标
    x=np.linspace(0,6,100)
    #w[0]*x[0]+w[1]*x[1]+b=0
    #计算函数值
    y=-(w[0]*x+b)/w[1]
    #绘制函数
    plt.plot(x,y,color='r')
    #绘制数据集
    for i in range(len(train_datas)):
        if(sign_of_train_datas[i]==1):
            plt.scatter(train_datas[i][0],train_datas[i][1],s=100)
        else:
            plt.scatter(train_datas[i][0],train_datas[i][1],marker='x',s=100)
    plt.title('percetron')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    
    
def read_from_csv():
    file='./data.csv'
    content=np.loadtxt(file,delimiter=',')
    train_datas=[]
    sign_of_train_datas=[]
    for line in content:
        train_datas.append(line[0:2])
        sign_of_train_datas.append(line[-1:])
    return train_datas,sign_of_train_datas


if __name__=='__main__':
    #数据集
    #train_datas=[[3,3],[4,3],[1,1],[2,3],[4,5],[1,2]]
    #ign_of_train_datas=[1,1,-1,1,1,-1]
    
    train_datas,sign_of_train_datas=read_from_csv()
    
    #构造输入实例
    X=np.array(train_datas)
    Y=np.array(sign_of_train_datas)
    #设置初始w0,b0
    w0=np.zeros((X.shape[1],1))
    b0=0
    #设置学习率
    yita=1
    #训练模型
    w,b=train(X,Y,w0,b0,yita)
    print(w,b)
    draw(train_datas,sign_of_train_datas,w,b)
  • 运行结果