KNN算法(鸢尾花做数据集)

题目:原生python实现knn分类算法,用鸢尾花数据集。

一、题目分析

Knn的基本思想就是在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前k个数据,则该测试数据对应的类别就是k个数据中出现次数最多的那个分类。其算法描述为:

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

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

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

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

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

二、算法构造

 

三、程序实现源代码

# -*- coding: utf-8 -*-
"""
Created on Mon Oct 14 16:24:51 2019

@author: Administrator
"""

import csv     #用于处理csv文件  
import random    #用于随机数  
import math           
import operator  
 
  
#加载数据集  
def loadDataset(filename,split,trainingSet=[],testSet = []):  
    with open(filename,"r") as csvfile: 
        lines = csv.reader(csvfile)  
        dataset = list(lines)  
        for x in range(len(dataset)-1):  
            for y in range(4):  
                dataset[x][y] = float(dataset[x][y])  
            if random.random()<split:  
                trainingSet.append(dataset[x])  
            else:  
                testSet.append(dataset[x])  
  
#计算距离(此处用欧式距离):同一个维度上的东西的差值,求平方,相加,最后再开方
def euclideanDistance(instance1,instance2,length):  
    res = 0  
    for x in range(length):  
        res += pow((instance1[x] - instance2[x]),2)  #两者求差值的平方
    return math.sqrt(res)   #再开方
  
#返回K个最近邻  
def getNeighbors(trainingSet,testInstance,k):  
    distances = []  
    length = len(testInstance) -1  
    #计算每一个测试实例到训练集实例的距离  
    for x in range(len(trainingSet)):  
        dist = euclideanDistance(testInstance, trainingSet[x], length)  
        distances.append((trainingSet[x],dist))  
    #对所有的距离进行排序  
    distances.sort(key=operator.itemgetter(1))  #定义函数key,获取对象的第1个域的值,并对其进行升序
    neighbors = []  
    #返回k个最近邻  
    for x in range(k):  
        neighbors.append(distances[x][0])  
    return neighbors  
  
#对k个近邻进行合并,返回value最大的key  
def getResponse(neighbors):  
    classVotes = {}  
    for x in range(len(neighbors)):  
        response = neighbors[x][-1]  
        if response in classVotes:  
            classVotes[response]+=1  
        else:  
            classVotes[response] = 1  
    #排序(其中reverse参数是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列)
    sortedVotes = sorted(classVotes.items(),key = operator.itemgetter(1),reverse =True)  
    return sortedVotes[0][0]  
  
#计算准确率  
def getAccuracy(testSet,predictions):  
    correct = 0  
    for x in range(len(testSet)):  
        if testSet[x][-1] == predictions[x]:  
            correct+=1  
    return (correct/float(len(testSet))) * 100.0  
    return ("{:2f}%".format(100*correct/len(testSet)))

  
def main():  
    trainingSet = []  #训练集  
    testSet = []      #测试集  
    split = 0.7      #分割的比例  
    loadDataset("iris.csv", split, trainingSet, testSet)   
    print ("训练集:" + repr(len(trainingSet))  )
    print ("测试集:" + repr(len(testSet))  )    #其中repr() 函数将对象转化为供解释器读取的形式。        
    predictions = []  #预测值
    k=5
    #k = 5  #定义返回5个最近邻居数  
    for x in range(len(testSet)):  
        neighbors = getNeighbors(trainingSet, testSet[x], k)  
        result = getResponse(neighbors)  
        predictions.append(result)  
        print( "预测值为: " + repr(result) + ",实际值为: " + repr(testSet[x][-1])  )
    accuracy = getAccuracy(testSet, predictions)  
    print ("准确率为:" + repr(accuracy) + "%" ) 
  
if __name__ =="__main__":  
    main()  

四、调试、测试及运行结果

4.1调试结果

4.2测试结果

4.2.1测试代码(加载数据集)

测试结果

4.2.2测试代码(计算准确率):

测试结果:

4.3.运行结果

五、总结

1.不足:刚开始不知道knn算法从何入手,查询了相关资料后了解了knn算法的大致过程,在网上找了相关视频从基础看了下理清了思路后才开始着手写,但是实现过程中还是遇到了很多问题:

  1. 刚开始iris.csv鸢尾花数据集导入不成功,经过检查发现没有导入csv文件,并且要将.py文件和.csv文件放在一个目录下;
  2. 由于粗心大意,过程中出现了一些细小错误,打开csv文件时,错把“:”写成“;”,报错了,可见还是要细心。

打开csv文件如下所示:

2.心得:此次knn算法我也收获了很多,通过查找资料,学习视频我了解了knn的基本算法过程,总体分为5步,此次作业是通过导入鸢尾花的数据集做的,而不是导入库函数;同时我对列表,字典等的应用也有了一定的掌握!

参考网址:https://www.cnblogs.com/momo072994MLIA/p/9435102.html

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页