机器学习之感知机---2022/04/15

0 参考资料

机器学习之感知机模型
《统计学习方法》笔记之感知机模型及代码实现
《统计学习方法》之感知机代码实现(原始形式和对偶形式)

1 算法流程

请添加图片描述
请添加图片描述

2 代码实现

'''
日期:2022.04.15
作者:城主
功能:代码实现感知机
'''

'''
算法 2.1 感知机学习算法的初始形式
输入:训练数据集T={(x1,y1),(x2,y2),...,(xn,yn),其中y只取正负1,学习率r}
输出:w,b; 感知机模型f(x)=sign(w.x+b)
(1) 选取初值w0,b0;
(2) 在训练集中选取数据(xi,yi);
(3) 如果yi(w.xi+b)<=0(说明错误判断的点)
    w<---w+r.yi.xi
    b<---b+r.yi
(4) 移至(2),直到训练集中没有误分类的点;
补充。测试数据的话,直接带入感知机模型,如果大于0就标记为1,否则就标记为-1
'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Perceptron


# 生成数据集
def creatData():
    # np.array,将列表转化为数组
    x=np.array([[3, 3], [4, 3], [1, 1]])
    y=np.array([1, 1, -1])
    return x, y
    pass


# 感知机学习算法实现
# shape[0]与shape[1]描述的是矩阵的行数和列数
def perceptronTrain1(x, y, r):
    # 选取初值w0,b0
    w=np.zeros(x.shape[1])
    b=0
    # 在训练集中选择数据点,计算yi.(w.xi+b),如果小于等于0,则更新w,b,并从头计算,直到没有误判点
    i=0
    while i < x.shape[0]:
        xt=x[i]
        yt=y[i]
        if yt*(np.dot(w, xt)+b) <= 0:
            w=w+r*np.dot(yt, xt)
            b=b+r*yt
            i=0
        else:
            i+=1
    return w, b
    pass


# 感知机模型的对偶式算法实现
def sign(X, Y, x, y, alpha, b, r):
    result=np.sum(alpha*Y*np.dot(X, x))+b
    if result >= 0:
        return 1
    else:
        return -1
    pass


def perceptronTrain2(x, y, r):
    # 选取初值w0,b0
    alpha=np.zeros(len(x), dtype=np.float32)
    flag=False
    w=0
    b=0
    # 在训练集中选择数据点,计算yi.(w.xi+b),如果小于等于0,则更新w,b,并从头计算,直到没有误判点
    while not flag:  # not false等于true的意思
        wrongCnt=0
        for i in range(len(x)):
            xt=x[i]
            yt=y[i]
            if yt*sign(x, y, xt, yt, alpha, b, r) <= 0:
                alpha[i]=alpha[i]+r
                b=b+r*yt
                w=np.dot(alpha*y, x)  # 主要是每一步计算后显示W ,可以在最后计算
                # print("误分类点:{} a[{}]:{} w{}  b:{}".format(x, i, alpha[i], w, b))
                wrongCnt+=1
        if wrongCnt==0:
            flag=True
    w=np.dot(alpha*y, x)
    return w, b
    pass


# 绘制超平面上的图像
def draw(X, w, b):
    # 生成分离超平面上的两点
    X_new=np.array([[0], [6]])
    y_predict=-b-(w[0]*X_new)/w[1]
    # 绘制训练数据集的散点图
    plt.plot(X[:2, 0], X[:2, 1], "g*", label="1")
    plt.plot(X[2:, 0], X[2:, 1], "rx", label="-1")
    # 绘制分离超平面
    plt.plot(X_new, y_predict, "b-")
    # 设置两坐标轴起止值
    plt.axis([0, 6, 0, 6])
    # 设置坐标轴标签
    plt.xlabel('x1')
    plt.ylabel('x2')
    # 显示图例
    plt.legend()
    # 显示图像
    plt.show()
    pass


def makeByOwn():
    # 在下面的代码行中使用断点来调试脚本。
    [x, y]=creatData()
    [w, b]=perceptronTrain2(x, y, 1)
    print("f(x)=sign("+str(w)+".x+"+str(b))
    draw(x, w, b)
    pass


# 调用系统提供的函数来进行感知机算法的学习
def makeBySystem():
    [x, y]=creatData()
    # 构建Perceptron对象,训练数据并输出结果
    perceptron=Perceptron()
    perceptron.fit(x, y)
    print("w:", perceptron.coef_, "\n", "b:", perceptron.intercept_, "\n", "n_iter:", perceptron.n_iter_)
    # 测试模型预测的准确率
    res=perceptron.score(x, y)
    print("correct rate:{:.0%}".format(res))
    # draw(x, perceptron.coef_, perceptron.intercept_)
    # 绘制

    # 画出正例和反例的散点图
    plt.plot(x[:2, 0], x[:2, 1], "g*", label="1")
    plt.plot(x[2:, 0], x[2:, 1], "rx", label="-1")

    # 画出超平面(在本例中即是一条直线)
    line_x=np.arange(-4, 4)
    # 出现错误
    # divide by zero encountered in double_scalars
    # invalid value encountered in multiply
    line_y=line_x*(-perceptron.coef_[0][0]/perceptron.coef_[0][1])-perceptron.intercept_
    plt.plot(line_x, line_y)
    plt.show()

    pass


# 按间距中的绿色按钮以运行脚本。
if __name__=='__main__':
    # makeByOwn()
    makeBySystem()

3 小结

纸上得来终觉浅,绝知此事要躬行。
本次代码还有一些小瑕疵,在makeBySystem()函数中,没有成功画出预测线条。目前还不知道如何修改。先挖个坑,以后完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值