用python实现KNN算法对鸢尾花的分类

一.KNN算法
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
二.算法设计
1.算距离:采用欧式距离公式,计算出测试集与训练集中每个对象的距离
欧式距离:
在这里插入图片描述
2.寻找邻居:圈定距离最近的k个训练对象,作为测试对象的近邻
3.做分类:根据k个近邻归属的主要类别,来对测试集进行分类
4.数据集:
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.3,“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”
5.8,2.7,4.1,1,“versicolor”
6.2,2.2,4.5,1.5,“versicolor”
5.6,2.5,3.9,1.1,“versicolor”
5.9,3.2,4.8,1.8,“versicolor”
6.1,2.8,4,1.3,“versicolor”
6.3,2.5,4.9,1.5,“versicolor”
6.1,2.8,4.7,1.2,“versicolor”
6.4,2.9,4.3,1.3,“versicolor”
6.6,3,4.4,1.4,“versicolor”
6.8,2.8,4.8,1.4,“versicolor”
6.7,3,5,1.7,“versicolor”
6,2.9,4.5,1.5,“versicolor”
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”
4.8,3,1.4,0.1,“setosa”
4.3,3,1.1,0.1,“setosa”
5.8,4,1.2,0.2,“setosa”
5.7,2.6,3.5,1,“versicolor”
5.5,2.4,3.8,1.1,“versicolor”
5.5,2.4,3.7,1,“versicolor”
7.7,3.8,6.7,2.2,“virginica”
7.7,2.6,6.9,2.3,“virginica”
6,2.2,5,1.5,“virginica”
三.源代码


```python
import math

#训练集和测试集       
group = []
labels = []
s1=[]         #训练集
labels1=[]    #训练集花类
s2=[]         #测试集
labels2=[]    #测试集花类
fr = open("data.txt")
for line in fr.readlines():
    lineArr = line.strip().split(",")
    group.append([float(lineArr[0]), float(lineArr[1]), float(lineArr[2]), float(lineArr[3])])
    s1=group[:36]
    s2=group[36:45]
    labels.append(lineArr[4])
    labels1=labels[:36]
    labels2=labels[36:45]
    #print([elm for i in s2 for elm in i])
#测试集
#test_data=[14,3,10]
knn=[]
#遍历计算测试集与训练集中所有数据的距离
for i in s2:
    for k in s1:
        #求距离
        d=math.sqrt((i[0]-k[0])**2+(i[1]-k[1])**2+(i[2]-k[2])**2+(i[3]-k[3])**2)
    
        #取小数点后两位
    knn.append([labels1[s1.index(k)],round(d,2)])
#print(knn)
for i in knn:
    for j in i:
    #按距离大小升序并取前7项
        knn.sort(key=lambda x:x[1])
print(knn)
knn=knn[: 7]
#print(knn)
#类
labels={
        '"setosa"':0,
        '"versicolor"':0,
        '"virginica"':0,
        }
#确定前7个样本所在科出现的频率
for i in knn:
    for key,value in labels.items():
        if i[0]==key:
            labels[key]+=1
print(labels)
#对所得结果按照出现的次数倒序
labels=sorted(labels.items(),key=lambda l:l[1],reverse=True)
print(labels)
score =labels[0][1]/ len(labels2)
print(score)     

``

四.调试和测试
1.调试
(1).设置断点
在这里插入图片描述
(2).调试结果
在这里插入图片描述
在这里插入图片描述
2.测试
在这里插入图片描述
五.总结
1.调试
·以Debug模式运行文件
·在debug之前记得用%reset 指令清空一下ipython工作空间中的变量,以免影响debug中变量值的查看
·无论是否打断点,都会在第一行语句执行之前中断一次
·!(python语句)可以在pdb提示符下执行python语句,可以用来查看变量值或者给变量临时指定值
·c命令或者Ctrl+F12可以让程序执行到下一个断点
·q命令退出调试
·Ctrl+F10 单行执行
·双击行首设置断点,按住Ctrl+Shift 双击行首可以设置条件断点
2.遍历列表中的列表的元素
List=[list1,list2,…listn]
用两个for循环:
for i in List:
: for elm in i:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值