基于双月数据集单层感知机_python


前言

本文主要针对双月数据集实现二分类问题。


一、单层感知机

单层感知机目标是将被感知数据集划分为两类的分离超平面,并计算出该超平面。单层感知机是二分类的线性分类模型,输入是被感知数据集的特征向量,输出时数据集的类别{+1,-1}。感知器的模型可以简单表示为:
在这里插入图片描述

该函数称为单层感知机,其中w是网络的N维权重向量,b是网络的N维偏置向量, w.x是w和x的内积,w和b的N维向量取值要求在实数域。

本文是将感知机模型简化,将权值b合并到w里进行更新,简化了计算。在这里插入图片描述

sign函数是感知机的早期激活函数,后面又演化出一系列的激活函数。激活函数一般采用非线性激活函数,以增强网络的表达能力。常见的激活函数有:sign, sigmoid,tanh,ReLU等。
在这里插入图片描述

二、双月数据集

根据圆的参数方程,设置圆的角度与双月宽度两个随机参数生成双月数据点集。
初始值为:
N = 1000 # 单个月亮数据集数据量
w = 2
r = 8
d = 1
iter = 50 # 迭代次数
learning_rate = 0.001 # 学习率
wn = np.array([1,0,0])

def moon(N,w,r,d):
    '''
    # :param w: 半月宽度
    # :param r: x轴偏移量
    # :param d: y轴偏移量
    # :param N: 半月散点数量
    :return: data (2*N*3) 月亮数据集
             data_dn (2*N*1) 标签
    '''
    data = np.ones((2*N,4))
    # 半月1的初始化
    r1 = 10  # 半月1的半径,圆心
    w1 = np.random.uniform(-w / 2, w / 2, size=N)  # 半月1的宽度范围
    theta1 = np.random.uniform(0, np.pi, size=N)  # 半月1的角度范围
    x1 = (r1 + w1) * np.cos(theta1)  # 行向量
    y1 = (r1 + w1) * np.sin(theta1)
    label1 = [1 for i in range(1,N+1)]  # label for Class 1

    # 半月2的初始化
    r2 = 10  # 半月1的半径,圆心
    w2 = np.random.uniform(-w / 2, w / 2, size=N)  # 半月1的宽度范围
    theta2 = np.random.uniform(np.pi, 2 * np.pi, size=N)  # 半月1的角度范围
    x2 = (r2 + w2) * np.cos(theta2) + r
    y2 = (r2 + w2) * np.sin(theta2) - d
    label2 = [-1 for i in range(1,N+1)]  # label for Class 2

    data[:,1] = np.concatenate([x1, x2])
    data[:,2] = np.concatenate([y1, y2])
    data[:,3] = np.concatenate([label1, label2])
    return data

在这里插入图片描述

三、程序

1.引入库

import numpy as np
import matplotlib.pyplot as plt

# from sklearn.cross_validation import train_test_split #用于分割数据。
from sklearn.model_selection import train_test_split

# ##################### 添加图片文字 ###########################################
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimSun']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
# ############################################################################

2.主函数

if __name__ == '__main__':
    # 初始化参数
    N = 1000    # 单个月亮数据集数据量
    w = 2
    r = 8
    d = 1
    iter = 50   # 迭代次数
    learning_rate = 0.001   # 学习率
    wn = np.array([1,0,0])
    data = moon(N,w,r,d)

    '''随机采用20%的数据用于测试,剩下的80%用于构建训练集合'''
    data_train,data_test,dn_train,dn_test=train_test_split(data[:,1:3],data[:,3],test_size=0.20,random_state=None)
    '''训练数据调整'''
    train_data = np.ones((1600,3))
    train_data[:,1:3] = data_train
    train_dn = dn_train
    '''迭代 训练 寻找最优解wn'''
    loss,wn = train(train_data,train_dn,wn,iter,learning_rate)
    print(wn)   # 最优解wn
    '''测试数据调整'''
    test_data = np.ones((400,3))
    test_data[:,1:3] = data_test
    test_dn = dn_test
    '''测试'''
    err,acc = test(test_data,test_dn)
    print('测试结果 错误率:','%.2f'%err)
    print('测试结果 正确率:','%.2f'%acc)
    '''决策平面 y+wx+b=0'''
    x = np.array(range(-15,25))
    y = -x*wn[1]/wn[2]-wn[0]/wn[2]
    '''月亮数据集'''
    plt.figure()
    plt.title('月亮数据集', size=14)
    plt.xlabel('x 轴', size=14)
    plt.ylabel('y 轴', size=14)
    plt.grid(ls=':', color='gray', alpha=0.5)  # alpha是透明度
    plt.scatter(data[0:N,1],data[0:N,2],c='b',s=20,marker='+')
    plt.scatter(data[N:2*N,1],data[N:2*N,2],c='r',s=20,marker='+')
    plt.plot(x,y,'k--')
    plt.savefig('./月亮数据集.png')

    '''损失函数'''
    x = [i for i in range(len(loss))]
    plt.figure()
    plt.title('损失函数曲线图', size=14)
    plt.xlabel('迭代次数', size=14)
    plt.ylabel('均方误差', size=14)
    # plt.grid(ls=':', color='gray', alpha=0.5)  # alpha是透明度
    plt.plot(x,loss,c='r',linewidth=2,linestyle='-',marker='o')
    plt.savefig('./损失函数.png')
    plt.show()

总结

从N=1000*2个点中随机选取80%的点作为训练集,20%的点作为测试集。迭代50次后,返回最优值wn,测试结果的错误率与正确率:
[ 0.656 -0.01167188 0.66452531]
测试结果 错误率: 0.00
测试结果 正确率: 1.00

画出决策平面与损失函数,如图:
在这里插入图片描述

在这里插入图片描述

完整程序

https://download.csdn.net/download/weixin_43816216/62520810

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

眰恦I

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值