[飞桨机器学习]KNN算法

[飞桨机器学习]KNN算法

这次简要介绍knn算法和具体实现的案例代码,依旧会是很基础并且不会刻意利用python的高级特性。

整个内容大概分成三个部分,knn介绍,python实现,和进阶方法。

不论你现在熟悉哪种语言,感兴趣的话都可以动手自己尝试一下。

一、KNN介绍

在我看来,knn就是计算测试数据与每一个训练数据的距离,取出距离最近的K个训练数据的标签,以其中数量最多的作为测试数据的预测标签。

官方地说:

邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。Cover和Hart在1968年提出了最初的邻近算法。KNN是一种分类(classification)算法,它输入基于实例的学习(instance-based learning),属于懒惰学习(lazy learning)即KNN没有显式的学习过程,也就是说没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理。与急切学习(eager learning)相对应。

KNN是通过测量不同特征值之间的距离进行分类。

思路是:如果一个样本在特征空间中的k个最邻近的样本中的大多数属于某一个类别,则该样本也划分为这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

提到KNN,网上最常见的就是下面这个图。

我们要确定绿点属于哪个颜色(红色或者蓝色),要做的就是选出距离目标点距离最近的k个点,看这k个点的大多数颜色是什么颜色。当k取3的时候,我们可以看出距离最近的三个,分别是红色、红色、蓝色,因此得到目标点为红色。

算法流程:

1)计算测试数据与各个训练数据之间的距离;

2)按照距离的递增关系进行排序;

3)选取距离最小的K个点;

4)确定前K个点所在类别的出现频率;

5)返回前K个点中出现频率最高的类别作为测试数据的预测分类

K的取值

K:临近数,即在预测目标点时取几个临近的点来预测。

K值得选取非常重要,因为:

如果当K的取值过小时,一旦有噪声得成分存在们将会对预测产生比较大影响,例如取K值为1时,一旦最近的一个点是噪声,那么就会出现偏差,K值的减小就意味着整体模型变得复杂,容易发生过拟合;

如果K的值取的过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。这时与输入目标点较远实例也会对预测起作用,使预测发生错误。K值的增大就意味着整体的模型变得简单;

如果K==N的时候,那么就是取全部的实例,即为取实例中某分类下最多的点,就对预测没有什么实际的意义了;

K的取值尽量要取奇数,以保证在计算结果最后会产生一个较多的类别,如果取偶数可能会产生相等的情况,不利于预测。

常用的方法是从k=1开始,使用检验集估计分类器的误差率。重复该过程,每次K增值1,允许增加一个近邻。选取产生最小误差率的K。一般k的取值不超过20,上限是n的开方,随着数据集的增大,K的值也要增大。

二、KNN的实现代码(以Iris为例)

1.将会用到的库

import math
import operator
import csv
import matplotlib.pyplot as plt
import numpy as np
import copy

2.数据集的划分

本次数据集划分采用了最简单的holdout的方法,将训练集和测试机三(测)七(训)分。

import random
import csv
import pandas as pd

def loadDataset(filename, split, trainingSet = [], testSet = []):
     with open(filename, 'r') as f:
         lines = csv.reader(f)
         dataset = list(lines)
         for x in range(len(dataset)-1):
             if random.random() < split:  #将数据集随机划分
                 trainingSet.append(dataset[x])
             else:
                 testSet.append(dataset[x])


if __name__ == "__main__":
    train = []
    test = []
    loadDataset('', 0.7, train, test)//填补文件目录
    print(train)
    print(test)

    train2 = pd.DataFrame(data=train)
    train2.to_csv('')//填补文件目录

    test2 = pd.DataFrame(data=test)
    test2.to_csv('')//填补文件目录

我运行时训练集为98条数据,部分示例如下

测试集52条数据,部分示例如下:

3.数据集的读取和划分

删除第一列序号,并把数据读入list

# 读取数据集
def loaddata(filename1, filename2, train_set=[], test_set=[]):

    with open(filename1, 'r') as f:
        lines = csv.reader(f)
        train_set = list(lines)
        for i in range(len(train_set)):
            del(train_set[i][0])
            for j in range(4):
                train_set[i][j] = float(train_set[i][j])
    with open(filename2, 'r') as f:
        lines = csv.reader(f)
        test_set = list(lines)
        for i in range(len(test_set)):
            del(test_set[i][0])
            for j in range(4):
                test_set[i][j] = float(test_set[i][j])

    return train_set, test_set

4.计算距离

此处计算距离选择欧式距离

def calculate_euclidean_distance(data1, data2, length):
    distance = 0.0
    for i in range(length):
            distance += pow((data1[i]-data2[i]), 2)
    return math.sqrt(distance)

5.核心部分

# 从训练集选出离测试集中一个实例最近的数据
def get_neighbors(k, test):
    distance = []
    length = len(test) - 1
    for i in range(len(train_set)):
        dist = calculate_euclidean_distance(test, train_set[i], length)
        distance.append((train_set[i], dist))
    distance.sort(key=operator.itemgetter(1))
    neighbors = []
    for i in range(k):
        neighbors.append(distance[i][0])
    return neighbors

6.统计类别个数并返回k个中的最多数

# 统计类别个数
def get_response(neighbors):
    class_vote = {}
    for i in range(len(neighbors)):
        response = neighbors[i][-1]
        if response not in class_vote:
            class_vote[response] = 1
        else:
            class_vote[response] += 1
    softed_vote = sorted(class_vote.items(), key=operator.itemgetter(1), reverse=True)
    return softed_vote[0][0]

7.计算准确率

评估模型效果的指标

# 计算准确率
def get_accurancy(predictions):
    correct = 0
    for i in range(len(test_set)):
        if test_set[i][-1] == predictions[i]:
            correct += 1
    return correct / float(len(test_set))

8.主程序

if __name__ == "__main__":
    train_set = []
    test_set = []
    train_set, test_set = loaddata('iris_train.csv', 'iris_test.csv')
    print(train_set)
    print(len(train_set))
    print(test_set)
    print(len(test_set))

    prediction = []
    k = 3
    for i in range(len(test_set)):
        neighbors = get_neighbors(k, test_set[i])
        result = get_response(neighbors)
        prediction.append(result)
        print(prediction[i],test_set[i][-1])

    accurancy = get_accurancy(prediction)
    print(accurancy*100)

9.运行结果

准确率:94.23076923076923%

可视化:

关于可视化不是这次的重点,并且涉及PCA降维,所以相关代码在此次不重点介绍,后续将会补充相关的介绍。

三、进阶方法

这里再补充介绍一些关于knn的改进后的方案,例如kdtree和BFPTR算法等,但是这里不给出具体代码,有兴趣可以自己实现,欢迎分享。

1.kdtree

k-d树是每个节点都为k维点的二叉树。所有非叶子节点可以视作用一个超平面把空间分割成两个半空间。节点左边的子树代表在超平面左边的点,节点右边的子树代表在超平面右边的点。选择超平面的方法如下:每个节点都与k维中垂直于超平面的那一维有关。因此,如果选择按照x轴划分,所有x值小于指定值的节点都会出现在左子树,所有x值大于指定值的节点都会出现在右子树。这样,超平面可以用该x值来确定,其法线为x轴的单位向量

简单来说,就是:

  • 选择一个维度(x,y,z …)
  • 选出这些点这个维度值的中位数
  • 将数据按中位数分为两部分
  • 对这两部分数据同样执行上述操作,直到数据点的数目为 1

而kdtree的意义在于使得knn算法的搜索环节更快,提升整体运行速度。

2.BFPTR

该算法也是一个排序算法,被称作中位数的中位数算法。

这就牵扯到上一期的排序算法中的快排了。

通常,我们需要在一大堆数中求前K大的数,或者求前K小的。比如在搜索引擎中求当天用户点击次数排名前10000的热词;在文本特征选择中求IF-IDF值按从大到小排名前K个的等等问题,都涉及到一个核心问题,即TOP-K问题

通常来说,TOP-K问题可以先对所有数进行快速排序,然后取前K大的即可。但是这样做有两个问题。

**(1)**快速排序的平均复杂度为O(n log (n)),但最坏时间复杂度为O(n2),不能始终保证较好的复杂度。

(2)我们只需要前K大的,而对其余不需要的数也进行了排序,浪费了大量排序时间。

除这种方法之外,堆排序也是一个比较好的选择,可以维护一个大小为K的堆,时间复杂度为O(n log (k))。

我们的目的是求前K大的或者前K小的元素,实际上有一个比较好的算法,叫做BFPTR算法,又称为中位数的中位数算法,它的最坏时间复杂度为O(n),它是由Blum、Floyd、Pratt、Tarjan、Rivest 提出。

该算法的思想是修改快速选择算法的主元选取方法,提高算法在最坏情况下的时间复杂度。

我们先回忆一下快排。

BFPTR算法中,仅仅是改变了快速排序Partion中的pivot值的选取,在快速排序中,我们始终选择第一个元素或者最后一个元素作为pivot,而在BFPTR算法中,每次选择五分中位数的中位数作为pivot,这样做的目的就是使得划分比较合理,从而避免了最坏情况的发生。算法步骤如下:

本算法的最坏时间复杂度为O(n),值得注意的是通过BFPTR算法将数组按第K小(大)的元素划分为两部分,而这高低两部分不一定是有序的,通常我们也不需要求出顺序,而只需要求出前K大的或者前K小的。

本人正在学习人工智能方向,日常更新一些学习记录,欢迎互相交流

欢迎三连,互粉,等你呦

import math
import operator
import csv
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import numpy as np
import copy


# 读取数据集
def loaddata(filename1, filename2, train_set=[], test_set=[]):

    with open(filename1, 'r') as f:
        lines = csv.reader(f)
        train_set = list(lines)
        for i in range(len(train_set)):
            del(train_set[i][0])
            for j in range(4):
                train_set[i][j] = float(train_set[i][j])
    with open(filename2, 'r') as f:
        lines = csv.reader(f)
        test_set = list(lines)
        for i in range(len(test_set)):
            del(test_set[i][0])
            for j in range(4):
                test_set[i][j] = float(test_set[i][j])

    return train_set, test_set


# 计算欧式距离
def calculate_euclidean_distance(data1, data2, length):
    distance = 0.0
    for i in range(length):
            distance += pow((data1[i]-data2[i]), 2)
    return math.sqrt(distance)


# 从训练集选出离测试集中一个实例最近的数据
def get_neighbors(k, test):
    distance = []
    length = len(test) - 1
    for i in range(len(train_set)):
        dist = calculate_euclidean_distance(test, train_set[i], length)
        distance.append((train_set[i], dist))
    distance.sort(key=operator.itemgetter(1))
    neighbors = []
    for i in range(k):
        neighbors.append(distance[i][0])
    return neighbors


# 统计类别个数
def get_response(neighbors):
    class_vote = {}
    for i in range(len(neighbors)):
        response = neighbors[i][-1]
        if response not in class_vote:
            class_vote[response] = 1
        else:
            class_vote[response] += 1
    softed_vote = sorted(class_vote.items(), key=operator.itemgetter(1), reverse=True)
    return softed_vote[0][0]


# 计算准确率
def get_accurancy(predictions):
    correct = 0
    for i in range(len(test_set)):
        if test_set[i][-1] == predictions[i]:
            correct += 1
    return correct / float(len(test_set))


# 可视化
def visualization():
    x = []
    y = []
    z = []
    tx = []
    ty = []
    tz = []

    data = copy.deepcopy(train_set)
    for i in data:
        del(i[-1])

    data2 = copy.deepcopy(test_set)
    for i in data2:
        del(i[-1])

    data = np.array(data)
    data2 = np.array(data2)

    mean_vector = np.mean(data, axis=0)
    mean_vector2 = np.mean(data2, axis=0)

    cov_mat = np.cov(data - mean_vector, rowvar=0)
    cov_mat2 = np.cov(data2 - mean_vector2, rowvar=0)

    fvalue, fvector = np.linalg.eig(cov_mat)
    fvalue2, fvector2 = np.linalg.eig(cov_mat2)

    fvaluesort = np.argsort(-fvalue)
    fvaluesort2 = np.argsort(-fvalue2)

    fValueTopN = fvaluesort[:3]
    fValueTopN2 = fvaluesort2[:3]

    newdata = fvector[:, fValueTopN]
    newdata2 = fvector2[:, fValueTopN2]

    new = np.dot(data, newdata)
    new2 = np.dot(data2, newdata2)

    for i in range(len(new)):
        x.append(new[i][0])
        y.append(new[i][1])
        z.append(new[i][2])


    for i in range(len(new2)):
        tx.append(new2[i][0])
        ty.append(new2[i][1])
        tz.append(new2[i][2])

    x = np.array(x)
    y = np.array(y)
    z = np.array(z)

    tx = np.array(tx)
    ty = np.array(ty)
    tz = np.array(tz)

    x1 = x.data[:38]
    x2 = x.data[38:66]
    x3 = x.data[66:]
    y1 = y.data[:38]
    y2 = y.data[38:66]
    y3 = y.data[66:]
    z1 = z.data[:38]
    z2 = z.data[38:66]
    z3 = z.data[66:]

    tx1 = tx.data[:12]
    tx2 = tx.data[12:34]
    tx3 = tx.data[34:]
    ty1 = ty.data[:12]
    ty2 = ty.data[12:34]
    ty3 = ty.data[34:]
    tz1 = tz.data[:12]
    tz2 = tz.data[12:34]
    tz3 = tz.data[34:]

    ax = plt.figure().add_subplot(111, projection='3d')
    ax.scatter(x1, y1, z1, marker='^')
    ax.scatter(x2, y2, z2, marker='*')
    ax.scatter(x3, y3, z3, marker='+')

    ax.scatter(tx1, ty1, tz1)
    ax.scatter(tx2, ty2, tz2)
    ax.scatter(tx3, ty3, tz3)

    plt.show()


if __name__ == "__main__":
    train_set = []
    test_set = []
    train_set, test_set = loaddata('data/data42984/iris_train.csv', 'data/data42984/iris_test.csv')
    print(train_set)
    print(len(train_set))
    print(test_set)
    print(len(test_set))

    prediction = []
    k = 3
    for i in range(len(test_set)):
        neighbors = get_neighbors(k, test_set[i])
        result = get_response(neighbors)
        prediction.append(result)
        print(prediction[i],test_set[i][-1])

    accurancy = get_accurancy(prediction)
    print(accurancy*100, end='')
    print('%')
    visualization()
[[5.1, 3.5, 1.4, 0.2, 'Iris-setosa'], [4.9, 3.0, 1.4, 0.2, 'Iris-setosa'], [4.7, 3.2, 1.3, 0.2, 'Iris-setosa'], [5.0, 3.6, 1.4, 0.2, 'Iris-setosa'], [4.6, 3.4, 1.4, 0.3, 'Iris-setosa'], [5.0, 3.4, 1.5, 0.2, 'Iris-setosa'], [4.4, 2.9, 1.4, 0.2, 'Iris-setosa'], [4.9, 3.1, 1.5, 0.1, 'Iris-setosa'], [5.4, 3.7, 1.5, 0.2, 'Iris-setosa'], [4.8, 3.0, 1.4, 0.1, 'Iris-setosa'], [4.3, 3.0, 1.1, 0.1, 'Iris-setosa'], [5.8, 4.0, 1.2, 0.2, 'Iris-setosa'], [5.7, 4.4, 1.5, 0.4, 'Iris-setosa'], [5.4, 3.9, 1.3, 0.4, 'Iris-setosa'], [5.1, 3.5, 1.4, 0.3, 'Iris-setosa'], [5.7, 3.8, 1.7, 0.3, 'Iris-setosa'], [5.1, 3.8, 1.5, 0.3, 'Iris-setosa'], [5.4, 3.4, 1.7, 0.2, 'Iris-setosa'], [5.1, 3.7, 1.5, 0.4, 'Iris-setosa'], [4.6, 3.6, 1.0, 0.2, 'Iris-setosa'], [4.8, 3.4, 1.9, 0.2, 'Iris-setosa'], [5.0, 3.4, 1.6, 0.4, 'Iris-setosa'], [5.2, 3.5, 1.5, 0.2, 'Iris-setosa'], [5.2, 3.4, 1.4, 0.2, 'Iris-setosa'], [4.8, 3.1, 1.6, 0.2, 'Iris-setosa'], [5.2, 4.1, 1.5, 0.1, 'Iris-setosa'], [5.5, 4.2, 1.4, 0.2, 'Iris-setosa'], [4.9, 3.1, 1.5, 0.1, 'Iris-setosa'], [5.5, 3.5, 1.3, 0.2, 'Iris-setosa'], [4.9, 3.1, 1.5, 0.1, 'Iris-setosa'], [4.4, 3.0, 1.3, 0.2, 'Iris-setosa'], [5.1, 3.4, 1.5, 0.2, 'Iris-setosa'], [5.0, 3.5, 1.3, 0.3, 'Iris-setosa'], [4.5, 2.3, 1.3, 0.3, 'Iris-setosa'], [5.0, 3.5, 1.6, 0.6, 'Iris-setosa'], [5.1, 3.8, 1.9, 0.4, 'Iris-setosa'], [5.3, 3.7, 1.5, 0.2, 'Iris-setosa'], [5.0, 3.3, 1.4, 0.2, 'Iris-setosa'], [6.4, 3.2, 4.5, 1.5, 'Iris-versicolor'], [6.9, 3.1, 4.9, 1.5, 'Iris-versicolor'], [5.5, 2.3, 4.0, 1.3, 'Iris-versicolor'], [6.5, 2.8, 4.6, 1.5, 'Iris-versicolor'], [5.7, 2.8, 4.5, 1.3, 'Iris-versicolor'], [6.3, 3.3, 4.7, 1.6, 'Iris-versicolor'], [6.6, 2.9, 4.6, 1.3, 'Iris-versicolor'], [5.2, 2.7, 3.9, 1.4, 'Iris-versicolor'], [5.9, 3.0, 4.2, 1.5, 'Iris-versicolor'], [5.6, 2.9, 3.6, 1.3, 'Iris-versicolor'], [6.7, 3.1, 4.4, 1.4, 'Iris-versicolor'], [5.6, 3.0, 4.5, 1.5, 'Iris-versicolor'], [5.9, 3.2, 4.8, 1.8, 'Iris-versicolor'], [6.3, 2.5, 4.9, 1.5, 'Iris-versicolor'], [6.4, 2.9, 4.3, 1.3, 'Iris-versicolor'], [6.6, 3.0, 4.4, 1.4, 'Iris-versicolor'], [6.0, 2.9, 4.5, 1.5, 'Iris-versicolor'], [5.5, 2.4, 3.7, 1.0, 'Iris-versicolor'], [5.4, 3.0, 4.5, 1.5, 'Iris-versicolor'], [6.0, 3.4, 4.5, 1.6, 'Iris-versicolor'], [5.6, 3.0, 4.1, 1.3, 'Iris-versicolor'], [5.5, 2.5, 4.0, 1.3, 'Iris-versicolor'], [5.0, 2.3, 3.3, 1.0, 'Iris-versicolor'], [5.6, 2.7, 4.2, 1.3, 'Iris-versicolor'], [5.7, 3.0, 4.2, 1.2, 'Iris-versicolor'], [5.7, 2.9, 4.2, 1.3, 'Iris-versicolor'], [6.2, 2.9, 4.3, 1.3, 'Iris-versicolor'], [5.7, 2.8, 4.1, 1.3, 'Iris-versicolor'], [6.5, 3.0, 5.8, 2.2, 'Iris-virginica'], [7.6, 3.0, 6.6, 2.1, 'Iris-virginica'], [6.7, 2.5, 5.8, 1.8, 'Iris-virginica'], [6.5, 3.2, 5.1, 2.0, 'Iris-virginica'], [6.8, 3.0, 5.5, 2.1, 'Iris-virginica'], [5.7, 2.5, 5.0, 2.0, 'Iris-virginica'], [6.4, 3.2, 5.3, 2.3, 'Iris-virginica'], [6.5, 3.0, 5.5, 1.8, 'Iris-virginica'], [7.7, 3.8, 6.7, 2.2, 'Iris-virginica'], [7.7, 2.6, 6.9, 2.3, 'Iris-virginica'], [5.6, 2.8, 4.9, 2.0, 'Iris-virginica'], [7.7, 2.8, 6.7, 2.0, 'Iris-virginica'], [6.3, 2.7, 4.9, 1.8, 'Iris-virginica'], [6.7, 3.3, 5.7, 2.1, 'Iris-virginica'], [7.2, 3.2, 6.0, 1.8, 'Iris-virginica'], [6.2, 2.8, 4.8, 1.8, 'Iris-virginica'], [7.9, 3.8, 6.4, 2.0, 'Iris-virginica'], [6.4, 2.8, 5.6, 2.2, 'Iris-virginica'], [6.3, 2.8, 5.1, 1.5, 'Iris-virginica'], [6.1, 2.6, 5.6, 1.4, 'Iris-virginica'], [7.7, 3.0, 6.1, 2.3, 'Iris-virginica'], [6.3, 3.4, 5.6, 2.4, 'Iris-virginica'], [6.4, 3.1, 5.5, 1.8, 'Iris-virginica'], [6.0, 3.0, 4.8, 1.8, 'Iris-virginica'], [6.9, 3.1, 5.4, 2.1, 'Iris-virginica'], [6.7, 3.1, 5.6, 2.4, 'Iris-virginica'], [5.8, 2.7, 5.1, 1.9, 'Iris-virginica'], [6.7, 3.3, 5.7, 2.5, 'Iris-virginica'], [6.7, 3.0, 5.2, 2.3, 'Iris-virginica'], [6.3, 2.5, 5.0, 1.9, 'Iris-virginica'], [6.2, 3.4, 5.4, 2.3, 'Iris-virginica'], [5.9, 3.0, 5.1, 1.8, 'Iris-virginica']]
98
[[4.6, 3.1, 1.5, 0.2, 'Iris-setosa'], [5.4, 3.9, 1.7, 0.4, 'Iris-setosa'], [4.8, 3.4, 1.6, 0.2, 'Iris-setosa'], [5.1, 3.3, 1.7, 0.5, 'Iris-setosa'], [5.0, 3.0, 1.6, 0.2, 'Iris-setosa'], [4.7, 3.2, 1.6, 0.2, 'Iris-setosa'], [5.4, 3.4, 1.5, 0.4, 'Iris-setosa'], [5.0, 3.2, 1.2, 0.2, 'Iris-setosa'], [4.4, 3.2, 1.3, 0.2, 'Iris-setosa'], [4.8, 3.0, 1.4, 0.3, 'Iris-setosa'], [5.1, 3.8, 1.6, 0.2, 'Iris-setosa'], [4.6, 3.2, 1.4, 0.2, 'Iris-setosa'], [7.0, 3.2, 4.7, 1.4, 'Iris-versicolor'], [4.9, 2.4, 3.3, 1.0, 'Iris-versicolor'], [5.0, 2.0, 3.5, 1.0, 'Iris-versicolor'], [6.0, 2.2, 4.0, 1.0, 'Iris-versicolor'], [6.1, 2.9, 4.7, 1.4, 'Iris-versicolor'], [5.8, 2.7, 4.1, 1.0, 'Iris-versicolor'], [6.2, 2.2, 4.5, 1.5, 'Iris-versicolor'], [5.6, 2.5, 3.9, 1.1, 'Iris-versicolor'], [6.1, 2.8, 4.0, 1.3, 'Iris-versicolor'], [6.1, 2.8, 4.7, 1.2, 'Iris-versicolor'], [6.8, 2.8, 4.8, 1.4, 'Iris-versicolor'], [6.7, 3.0, 5.0, 1.7, 'Iris-versicolor'], [5.7, 2.6, 3.5, 1.0, 'Iris-versicolor'], [5.5, 2.4, 3.8, 1.1, 'Iris-versicolor'], [5.8, 2.7, 3.9, 1.2, 'Iris-versicolor'], [6.0, 2.7, 5.1, 1.6, 'Iris-versicolor'], [6.7, 3.1, 4.7, 1.5, 'Iris-versicolor'], [6.3, 2.3, 4.4, 1.3, 'Iris-versicolor'], [5.5, 2.6, 4.4, 1.2, 'Iris-versicolor'], [6.1, 3.0, 4.6, 1.4, 'Iris-versicolor'], [5.8, 2.6, 4.0, 1.2, 'Iris-versicolor'], [5.1, 2.5, 3.0, 1.1, 'Iris-versicolor'], [6.3, 3.3, 6.0, 2.5, 'Iris-virginica'], [5.8, 2.7, 5.1, 1.9, 'Iris-virginica'], [7.1, 3.0, 5.9, 2.1, 'Iris-virginica'], [6.3, 2.9, 5.6, 1.8, 'Iris-virginica'], [4.9, 2.5, 4.5, 1.7, 'Iris-virginica'], [7.3, 2.9, 6.3, 1.8, 'Iris-virginica'], [7.2, 3.6, 6.1, 2.5, 'Iris-virginica'], [6.4, 2.7, 5.3, 1.9, 'Iris-virginica'], [5.8, 2.8, 5.1, 2.4, 'Iris-virginica'], [6.0, 2.2, 5.0, 1.5, 'Iris-virginica'], [6.9, 3.2, 5.7, 2.3, 'Iris-virginica'], [6.1, 3.0, 4.9, 1.8, 'Iris-virginica'], [6.4, 2.8, 5.6, 2.1, 'Iris-virginica'], [7.2, 3.0, 5.8, 1.6, 'Iris-virginica'], [7.4, 2.8, 6.1, 1.9, 'Iris-virginica'], [6.9, 3.1, 5.1, 2.3, 'Iris-virginica'], [6.8, 3.2, 5.9, 2.3, 'Iris-virginica'], [6.5, 3.0, 5.2, 2.0, 'Iris-virginica']]
52
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-setosa Iris-setosa
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-virginica Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-virginica Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-versicolor Iris-versicolor
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-versicolor Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
Iris-virginica Iris-virginica
94.23076923076923%

运行代码请点击:https://aistudio.baidu.com/aistudio/projectdetail/619297?shared=1

欢迎三连!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值