基于 iris 数据集采用感知器 Perceptron 实现线性二分类

该博客介绍了如何使用感知器算法对鸢尾花数据集进行线性二分类。首先,通过可视化展示了数据的分布,选取了sepallength和sepalwidth两个特征,区分第0类和第1类。接着,运用Perceptron模型进行训练,绘制了迭代次数与正确率的关系图,验证了模型效果。最后,尝试了不同的特征组合,同样实现了有效分类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于 iris 数据集采用感知器 Perceptron 实现线性二分类

题目简述:

基于 iris 数据集(四个特征,三个类别),选取两个特征和两个类别,采用感知器 Perceptron 实现线性二分类,对分类结果进行可视化,并画出迭代次数与正确率的关系,注意:代码实现数据的预分析,说明两特征和两类别选取的原因。


iris数据集:

链接在这里: iris数据集介绍


代码使用介绍:

  • 此处sample1=0,sample2=1表示鸢尾花的四个特征中,我选取第一个特征和第二个特征,即图中的sepal length 和sepal width特征


  • 鸢尾花的四个特征即三个类别如下

在这里插入图片描述


  • 接下来先运行下面的代码,得到如下结果:

    draw_relation(df,sample1,sample2)
    

    image-20221109235709430

    由上图可知,第0类和第1类线性可分,第0类和第2类线性可分,接下来,我们只需要选取可分的其中两类进行分类即可,此处我选择对第0类和第1类进行区分


  • 由于是对第0类和第1类进行区分,我将trains()函数中的class1=0,class2=1,表示我要选择分的类。运行后得到如下结果:

trains(df,sample1,sample2,class1=0,class2=1,epoch=400)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


再次分类:

  • 此时如果还需要选取其他特征,如sample1=1,sample=2,运行后得到如下结果,可知第0类和第1类线性可分 ,第0类和第2类线性可分。

    • draw_relation(df,sample1,sample2)
      


  • 由上述结果,我选择class1=0,class2=2对其进行分类,得到如下结果:

    • trains(df,sample1,sample2,class1=0,class2=1,epoch=400)
      

image-20221110001422782

在这里插入图片描述

image-20221110001521592


代码如下:

import pandas as pd
import numpy as np
from pylab import *
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron
from sklearn.model_selection import train_test_split



# 通过图像的方式得到可分类的特征,默认为第0,1类特征
def draw_relation(df,sample1=0,sample2=1):
    x = np.array(df.iloc[:, [sample1, sample2]])
    y = np.array(df.iloc[:, -1])
    lenth = len(x)
    n11 = [x[i, 0] for i in range(lenth) if y[i] == 0]
    n12 = [x[i, 1] for i in range(lenth) if y[i] == 0]
    n21 = [x[i, 0] for i in range(lenth) if y[i] == 1]
    n22 = [x[i, 1] for i in range(lenth) if y[i] == 1]
    n31 = [x[i, 0] for i in range(lenth) if y[i] == 2]
    n32 = [x[i, 1] for i in range(lenth) if y[i] == 2]
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 添加这条可以让图形显示中文
    plt.figure()
    plt.xlim(0, 8)
    plt.ylim(0, 8)
    plt.title(f"特征{sample1}和特征{sample2}的三个种类分布")
    plt.xlabel(f'{df.columns[sample1]}')
    plt.ylabel(f'{df.columns[sample2]}')
    plt.scatter(n11, n12, label='0', c='r', marker='v')
    plt.scatter(n21, n22, label='1', c='b', marker='x')
    plt.scatter(n31, n32, label='2', c='g',marker='o')
    plt.legend('012')
    plt.show()
#对数据类别进行选择并训练
def trains(dfs,sample1=0,sample2=1,class1=0,class2=1,epoch=50):
    data1 = np.array(df.iloc[50*class1:50*class1+50, [sample1, sample2, -1]])
    data2 = np.array(df.iloc[50*class2:50*class2+50, [sample1, sample2, -1]])
    #将选择的两个类的数据合并在一起
    data = np.concatenate((data1, data2), axis = 0)
    x, y = data[:, :-1], data[:, -1]
    lenth = len(x)
    # 将选择的两个类分为正例和反例
    positive_x1 = [x[i, 0] for i in range(lenth) if y[i] == class1]
    positive_x2 = [x[i, 1] for i in range(lenth) if y[i] == class1]
    negetive_x1 = [x[i, 0] for i in range(lenth) if y[i] == class2]
    negetive_x2 = [x[i, 1] for i in range(lenth) if y[i] == class2]
    # 测试集和训练集都用所有的数据
    x_data_train,y_data_train = x,y
    x_data_test,y_data_test = x,y
    # x_data_train, x_data_test, y_data_train, y_data_test = train_test_split(x, y, test_size=0.4,random_state=False)
    # 用于存储损失结果
    y_data = []
    x_data = []
    # 中文
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    plt.figure()
    # 将图表和颜色设定为与draw_relation()画出的图像一致
    class_pic = ['v','x','o']
    class_color = ['r','b','g']
    for i in range(1, epoch, 5):
        # 使用Perceptron进行训练
        clf = Perceptron(fit_intercept=False, n_iter_no_change=i, shuffle=False)
        # 使用训练数据进行训练
        clf.fit(x_data_train, y_data_train)
        # 得到训练结果
        print("训练结果w:", clf.coef_)  # w 参数
        print("训练结果b:", clf.intercept_)  # b 参数
        # clf.n_iter_ #迭代次数
        print("迭代次数:", clf.n_iter_)

        # 使用测试集进行验证
        acc = clf.score(x_data_test, y_data_test)
        print("测试集评估:", acc)
        x_data.append(i)
        y_data.append(acc)

        # 画出正例和反例的散点图
        plt.cla()
        plt.title(f"第{class1}类和{class2}类的超平面和散点图")
        plt.xlabel(f'{df.columns[sample1]}')
        plt.ylabel(f'{df.columns[sample2]}')
        plt.xlim(0, 8)
        plt.ylim(0, 8)
        plt.scatter(positive_x1, positive_x2, c=class_color[class1],marker=class_pic[class1])
        plt.scatter(negetive_x1, negetive_x2, c=class_color[class2],marker=class_pic[class2])
        # 画出超平面(在本例中即是一条直线)
        line_x = np.arange(2, 8)
        line_y = line_x * (-clf.coef_[0][0] / clf.coef_[0][1]) - clf.intercept_ / clf.coef_[0][1]
        plt.plot(line_x, line_y)
        plt.legend(f'线{class1}{class2}')
        plt.pause(0.005)
    # 显示标签
    plt.figure()
    plt.plot(x_data, y_data, 'o-',color="g", alpha=0.8, linewidth=0.8)
    plt.title("迭代次数与正确率", fontsize=10)
    plt.xlabel('迭代次数')
    plt.ylabel('正确率')
    x_ticks = np.arange(0, 401, 50)
    y_ticks = np.arange(0.5, 1.01, 0.05)
    plt.xticks(x_ticks)
    plt.yticks(y_ticks)
    plt.show()

if __name__ == '__main__':
    #加载鸢尾花数据集
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)  # iris.data包含一个(150, 4)的数据,设置列名为iris.feature_names
    df['label'] = iris.target  # iris.target为类别标签(150, 1)
    #此处sample1=0,sample2=1表示鸢尾花的四个特征中,我选取第一个特征和第二个特征,即
    sample1 = 0
    sample2 = 1
    #对数据进行分析,将trans()函数注释一下,通过观察draw_relation()函数得到的3个类的分布,对接下来的类进行选取
    draw_relation(df,sample1,sample2)
    #对数据类别进行选择并训练
    trains(df,sample1,sample2,class1=0,class2=1,epoch=400)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BTU_YC

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

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

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

打赏作者

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

抵扣说明:

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

余额充值