PLA感知机及其实现

基础知识:

1、感知机学习的模型

感知机是根据输入实例的特征向量x对其进行二分分类的线性分类模型:

f(x) = sign(w.x + b)

感知机模型对应于输入空间中的超平面w.x + b = 0,也即感知机学习的目的就是:找到一个能够完美划分不同类别的实例点的超平面;

2、感知机学习的策略

感知机的学习策略就是极小化损失函数:

         

损失函数对应于误分类点到分离超平面的总距离,换句话说,分离超平面被误分类点所吸引,不断向其靠近,最终完成划分任务;

3、感知机学习的算法

首先任意选取一个超平面,然后使用梯度下降法不断极小化目标函数(也就是我们上面的损失函数),直到最终完成划分。

在梯度下降法的过程中,我们每一次都要随机选取一个误分类点,使其梯度下降

具体过程如下:

 

(1)是任意选取一个分离超平面;(2)是随机选取一个误分类点,这里使用代码实现的时候我们就直接遍历加if判断即可;(3)就是对误分类点使用梯度下降法,减小其梯度;(4)即为不断重复前三步,最终完成划分。

4、算法的收敛性

当训练数据集线性可分时,感知机学习算法是收敛的,感知机算法在训练数据集上的误分类次数满足不等式:

k <= (R/y)^2

也就是说不管我们尝试多少次,总能找到一种完美划分的方法,且最终的结果也并不是唯一的,不同的出事分离超平面,不同的误分类点选取顺序,都有可能对结果产生影响,所以我们有无穷多个解。

 

代码实现:

# 训练集:

#     vector(第一项是截距项)        label
#     ------------------------------------------
#     [1, 1, 4]                     1          
#     [1, 2, 3]                     1
#     [1, -2, 3]                    1
#     [1, -2, 2]                    0
#     [1, 0, 1]                     0
#     [1, 1, 2]                     0

# 测试集:

#     vector(第一项是截距项)        label
#     ------------------------------------------
#     [1, 1, 1]                     ?
#     [1, 2, 0]                     ? 
#     [1, 2, 4]                     ? 
#     [1, 1, 3]                     ?   

from numpy import *
import matplotlib.pyplot as plt
import operator
import time

# 数据集
def createTrainDataSet():
    trainDataMat = [[1,  1, 4], 
                    [1,  2, 3], 
                    [1, -2, 3], 
                    [1, -2, 2], 
                    [1,  0, 1], 
                    [1,  1, 2]]
    trainClassLable = [1, 1, 1, -1, -1,  -1] # 分类标签,也即权重向量 w
    return trainDataMat, trainClassLable

# 测试集
def createTestDataSet():
    testDataMat = [[1, 1, 1], 
                   [1, 2, 0], 
                   [1, 2, 4], 
                   [1, 1, 3]]
    return testDataMat


# 核心代码PLA感知机算法
def pla(dataMatIn, classLabels):
    # mat函数将数组转化为矩阵,transpose函数将矩阵进行转置
    dataMatrix = mat(dataMatIn) 
    labelMat   = mat(classLabels).transpose()
    m, n = shape(dataMatrix) # 获取矩阵的行、列数 
    weights = ones((n, 1))   # 设置初始权重为 [1 1 1]
    while True:
        Done = True
        for i in range(m):
            if (dot(dataMatrix[i], weights) * labelMat[i] > 0): # dot函数计算矩阵的内积,此时计算yi(w*xi + b) <= 0 是否成立
                continue
            # 如果该点误分类,则梯度下降            
            else:
                Done = False
                weights += (labelMat[i] * dataMatrix[i]).transpose()
        if Done:
            break
    return weights

# 打印感知机划分图像
def plotBestFit(weights):
    dataMat, labelMat = createTrainDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0]
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i]) == 1:
            xcord1.append(dataArr[i, 1])
            ycord1.append(dataArr[i, 2])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)

    # 画出训练数据集中的点
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')

    # 画出分界线,也即分离超平面
    x = arange(-3.0, 3.0, 0.1)
    y = (-weights[0] - weights[1] * x) / weights[2]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2')
    plt.show()

# 判断测试数据集中的向量在分离超平面的哪一边,大于零说明在上面,返回标签1;小于零说明在下面,返回标签-1
def classifyVector(inX, weights):
    if float(dot(inX, weights)) > 0:
        return 1
    else:
        return -1

# 对测试数据集中的向量进行预测分类
def Predict(dataSet, weights):
    predict = []
    for vector in dataSet:
        predict.append(classifyVector(vector, weights))
    return predict

def main():
    trainDataSet, trainShares = createTrainDataSet()
    testDataSet = createTestDataSet()
    
    # 输出最终的分离超平面
    Final_weights = pla(trainDataSet, trainShares)
    print("Final_weights = \n", Final_weights)
    plotBestFit(Final_weights)
    
    # 输出对测试数据集的预测结果
    predictShares = Predict(testDataSet, Final_weights)
    print("predictResult: \n", predictShares)

if __name__ == '__main__':
    start = time.clock()
    main()
    end = time.clock()
    print('finish all in %s' % str(end - start))

输出结果如下:

     

     

可以看到分离超平面实现了对训练数据集中向量的完美划分,且对测试集中数据点的预测也是准确的,算法用时0.37s还可以,我们的PLA感知机算法就实现了。

 

转载于:https://www.cnblogs.com/RiTianBigBrother/p/5846589.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值