鸢尾花数据集knn算法python实现

1.作业题目
原生python实现knn分类算法,用鸢尾花数据集。
2.算法设计
首先需要设置数据集(以50个为例),然后在程序中导入数据集,根据数据集画出散点图。另外还需要定义两个函数,其中一个函数来计算两个数据点之间的欧氏距离,另一个函数设置knn模型,即计算训练数据与测试数据之间的欧氏距离,然后根据距离来排序,提取top k近邻,并且计算邻居中出现次数最多的类。最后还需要设置测试集(设置不同的k值)用来测试程序正确性。
数据集存入到文件“dataset.csv”中,具体数据为:
sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,setosa
4.9,3,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5,3.6,1.4,0.2,setosa
5.4,3.9,1.7,0.4,setosa
4.6,3.4,1.4,0.3,setosa
5,3.4,1.5,0.2,setosa
4.4,2.9,1.4,0.2,setosa
4.9,3.1,1.5,0.1,setosa
5.4,3.7,1.5,0.2,setosa
4.8,3.4,1.6,0.2,setosa
4.5,2.3,1.3,0.3,setosa
4.4,3.2,1.3,0.2,setosa
5,3.5,1.6,0.6,setosa
4.6,3.2,1.4,0.2,setosa
5.3,3.7,1.5,0.2,setosa
7,3.2,4.7,1.4,versicolor
6.4,3.2,4.5,1.5,versicolor
6,2.7,5.1,1.6,versicolor
5.6,3,4.1,1.3,versicolor
5.5,2.5,4,1.3,versicolor
5.5,2.6,4.4,1.2,versicolor
6.1,3,4.6,1.4,versicolor
5.8,2.6,4,1.2,versicolor
5,2.3,3.3,1,versicolor
5.6,2.7,4.2,1.3,versicolor
5.7,3,4.2,1.2,versicolor
5.7,2.9,4.2,1.3,versicolor
6.2,2.9,4.3,1.3,versicolor
5.1,2.5,3,1.1,versicolor
5.7,2.8,4.1,1.3,versicolor
6.3,3.3,6,2.5,virginica
5.8,2.7,5.1,1.9,virginica
7.1,3,5.9,2.1,virginica
6.3,2.9,5.6,1.8,virginica
6.5,3,5.8,2.2,virginica
7.6,3,6.6,2.1,virginica
4.9,2.5,4.5,1.7,virginica
7.3,2.9,6.3,1.8,virginica
6.7,2.5,5.8,1.8,virginica
7.2,3.6,6.1,2.5,virginica
6.5,3.2,5.1,2,virginica
6.4,2.7,5.3,1.9,virginica
6.8,3,5.5,2.1,virginica
5.7,2.5,5,2,virginica
5.8,2.8,5.1,2.4,virginica
6.4,3.2,5.3,2.3,virginica
6.5,3,5.5,1.8,virginica

3.源代码如下

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import os
import operator
import csv
#读取数据
data=pd.read_csv(os.getcwd() + '/data/' + os.sep + 'dataset.csv')
#输出数据
print('数据集为:')
print(data)
#绘制散点图
def draw_iris_data(csvpath='data/dataset.csv'):
    x_list1=[]
    y_list1=[]
    x_list2=[]
    y_list2=[]
    x_list3=[]
    y_list3=[]
    csv_reader=csv.reader(open(csvpath))
    for one_line in csv_reader:
        if one_line[4]=='setosa':#类1
            x_list1.append(one_line[0])
            y_list1.append(one_line[1])
        if one_line[4]=='versicolor':#类2
            x_list2.append(one_line[0])
            y_list2.append(one_line[1])
        if one_line[4]=='virginica':#类3
            x_list3.append(one_line[0])
            y_list3.append(one_line[1])
    #设置xy坐标
    plt.xlabel('x') 
    plt.ylabel('y')
    plt.title("iris_data_pic") 
    plt.scatter(x_list1,y_list1,c='g',marker='.')#类1表示为“ . ”
    plt.scatter(x_list2,y_list2,c='b',marker='+')#类2表示为“ + ”
    plt.scatter(x_list3,y_list3,c='y',marker='*')#类3表示为“ * ”
    plt.legend('123')
    #画图
    plt.show() 
print('数据集绘制的散点图如下:')
draw_iris_data()

#定义一个函数来计算两个数据点之间的欧氏距离
def CalculateDistance(data1, data2, length):
   distance = 0
   for x in range(length):
       distance += np.square(data1[x] - data2[x])
   return np.sqrt(distance)
#定义KNN模型
def knn(trainingSet, testInstance, k):
   length = testInstance.shape[1]
   distances = {}
#计算训练数据与测试数据之间的欧氏距离
   for x in range(len(trainingSet)):
       dist = CalculateDistance(testInstance, trainingSet.iloc[x], length)
       distances[x] = dist[0]
#根据距离来排序
   sorted_d = sorted(distances.items(), key=operator.itemgetter(1))
   neighbors = []
#提取top k近邻
   for x in range(k):
       neighbors.append(sorted_d[x][0])
   classVotes = {}
#计算邻居中出现次数最多的类
   for x in range(len(neighbors)):
       answer = trainingSet.iloc[neighbors[x]][-1]
       if answer in classVotes:
           classVotes[answer] += 1
       else:
           classVotes[answer] = 1
   sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
   return(sortedVotes[0][0])
#创建一个测试集
testSet = [[5.1, 3.5, 4.8, 2.7]]
test = pd.DataFrame(testSet)
print('测试数据',end='')
print(testSet)
#设置k为1
k = 1
print('k=1时即选取一个邻居来判断时结果为:')
result = knn(data, test, k)
print(result)
#设置k为3
k = 3
print('k=3时即选取三个邻居来判断时结果为:')
result = knn(data, test, k)
print(result)
#设置k为5
k = 5
print('k=5时即选取五个邻居来判断时结果为:')
result = knn(data, test, k)
print(result) 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值