ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【KNN】使用KNN算法实现对iris数据集的分类

2022-03-19 21:02:53  阅读:231  来源: 互联网

标签:KNN iris set list1 count 算法 train split test


**

一、实验报告

**
1、 实验目的:使用KNN算法实现对iris数据集的分类
2、 实验要求:(1)5次随机选取,对比分类准确率(2)探讨不同k值对分类准确率的影响

二、实验内容

1、 数据预处理

  1. 调用numpy库读取Iris.txt数据集,
  2. 使用shuffle随机打乱数据,用replace函数把最后一列label替换成012,便于数据处理。
  3. 用切片函数iloc将原始数据拆分成为data和label数据
  4. 训练集和测试集按照设置好的比例分配
  5. 返回训练集与测试集
    2、 模型构建
    定义一个计算欧式距离的函数,test数据减去train数据,再平方,把每个特征相加,最好开方。
    KNN算法原理:
  6. 计算出样本数据和测试数据的欧氏距离距离
  7. 为测试数据选择k个与其距离最小的样本
  8. 统计出k个样本所在类别的出现频率
  9. 返回前K个点中出现频率最高的类别作为测试数据的预测分类
    实现:
  10. 定义一个空的预测列表,得到每个训练数据的长度
  11. 用两次for循环计算每一个测试集与每一个训练集的距离,使用argsort函数从低到高排序并返回索引,定义一个空计数列表count
  12. 用for循环,每一次循环获得下标所对应的标签值,将标签存入字典之中并存入个数,取出k个最短距离
  13. 用sorted函数对标签进行排序,将出现频次最高的列表放入预测列表中,循环结束return预测列表
    3、 计算准确度
  14. 计算在测试数据集中算法正确预测的比例。
    4、 主函数设计
    设定好训练集和测试集比例0.3,用for循环设置k的值,从2到20取值,输出精度,并绘制图如下所示:

三、 结果分析

在这里插入图片描述

KNN算法易于实现,无需估计参数,K值用于选择最近邻的数目,K的选择非常敏感。K值越小意味着模型复杂度越高,从而容易产生过拟合;K值越大则 意味着整体的模型变得简单,学习的近似误差会增大,由于数据集很小,并每次都随机选取,每次测试结果会有所变动,通过结果对比k值 取5、6、7准确率比较高。

四、 代码

import operator
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.utils import shuffle
def split_data_set(path, split_rate):
    list1 = pd.read_csv(path)
    list1 = shuffle(list1)
    total_length = len(list1)
    split_point = int(total_length * split_rate)
    list1 = list1.replace("Iris-setosa", "0")
    list1 = list1.replace("Iris-versicolor", "1")
    list1 = list1.replace("Iris-virginica", "2")
    x = list1.iloc[:, 0:4]
    x_train = x.iloc[:split_point, :]
    x_test = x.iloc[split_point:total_length + 1, :]
    y = list1.iloc[:, 4]
    y_train = y.iloc[:split_point]
    y_test = y.iloc[split_point:total_length + 1]
    return np.array(x_train), np.array(x_test), np.array(y_train), np.array(y_test)
def data_diatance(x_test, x_train):
    distances = np.sqrt(sum((x_test - x_train) ** 2))
    return distances
def knn(x_test, x_train, y_train, k):
    predict_result_set = []
    train_set_size = len(x_train)
    distances = np.array(np.zeros(train_set_size))
    # 计算每一个测试集与每一个训练集的距离
    for i in x_test:
        for indx in range(train_set_size):
            # 计算数据之间的距离
            distances[indx] = data_diatance(i, x_train[indx])
        # 排序后的距离的下标
        sorted_dist = np.argsort(distances)
        class_count = {}
        # 取出k个最短距离
        for i in range(k):
            # 获得下标所对应的标签值
            sort_label = y_train[sorted_dist[i]]
            class_count[sort_label] = class_count.get(sort_label, 0) + 1
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        predict_result_set.append(sorted_class_count[0][0])

    return predict_result_set
def score(predict_result_set, y_test):
    count = 0
    for i in range(0, len(predict_result_set)):
        if predict_result_set[i] == y_test[i]:
            count += 1
    score = count / len(predict_result_set)
    return score
if __name__ == "__main__":
    # 载入数据集
    path = 'Iris.txt'
    split_rate = 0.3
    x_train, x_test, y_train, y_test=split_data_set(path,split_rate)
    X = []
    Y = []
    for k in range(2, 20):
        result = knn(x_test, x_train, y_train, k)
        # print("原有标签:", y_test)
        # # 为了方便对比查看,此处将预测结果转化为array,可直接打印结果
        # print("预测结果:", np.array(result))
        acc = score(result, y_test)
        X.append(k)
        Y.append(acc)
        # print("测试集的精度:%.2f" % acc)
    print(X, Y)
    plt.xlabel('k')
    plt.ylabel('acc')
    plt.plot(X, Y)
    plt.show()

标签:KNN,iris,set,list1,count,算法,train,split,test
来源: https://blog.csdn.net/beautifullyu/article/details/123602208

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有