(一)作业题目:
原生python实现knn分类算法(使用鸢尾花数据集)
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
(二)算法设计
(三)源码及实现结果展示
import numpy as np
import matplotlib.pyplot as plt
from decimal import Decimal
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 计算距离的函数
# v1,v2是两个向量,此处对应测试数据与训练数据
def distance(v1, v2):
dis = np.sqrt(np.sum(np.square(v1 - v2))) # 求出两个数据(向量)之间的距离
return dis
# 选出k近邻数组,并选出近邻数组中出现次数最多的数据作为选中点,记录对应的类别标签
def select_knn(testdata, traindata, labeltrain, k):
Dis = [] # 放置训练数据列表
dis=[]
for i in range(len(traindata)):
dis.append(distance(testdata, traindata[i]))#将测试数据与所有的训练数据之间的距离存储在一个列表中
index = np.argsort(dis) # 按照距离排序,得到排序后的索引值返回给index
Labels = {}
label = [labeltrain[t] for t in index[:k]]
for j in range(len(label)):
if label[j] not in Labels:
Labels[label[j]] = 1
else:
Labels[label[j]] += 1
sort_dict = sorted(Labels.items(), reverse=True, key=lambda item: item[1])#对字典按照value值进行降序排序
return sort_dict[0][0] # 返回k近邻中出现次数最多的数据点对应的标签值
# 计算准确率
def score(traindata, testdata, labeltest, labeltrain, k):
succNum = 0#成功测试的测试数据个数
for i in range(len(labeltest)):
TestData = testdata[i]#取出一个测试数据进行测试
knndata = select_knn(TestData, traindata, labeltrain, k)#得到预测的结果标签值
if knndata == labeltest[i]:
succNum += 1#预测成功则计数值加一
accutacy_rate = succNum / len(labeltest)#成功数比上总数得到成功概率
return accutacy_rate
def main():
n = int(input("请输入k的取值范围,从1到n,请输入n的值:"))
#加载鸢尾花数据集
iris = load_iris()
# print(iris)
data = iris
#分割数据集
traindata, testdata, labeltrain, labeltest = train_test_split(data['data'], data['target'] , test_size=0.3)
# accuracy = score(traindata, testdata, labeltest, labeltrain, k)
knums=range(1,n+1)#k的取值范围n
scores=[]#每次得分的列表
for k in knums:
s=score(traindata, testdata, labeltest, labeltrain, k)
accuracy = Decimal(s).quantize(Decimal('0.000000'))#准确率保留6位小数
scores.append(accuracy)
print("k=%d时的测试准确率为:%f \n" % (k, accuracy) )
plt.plot(knums,scores)#使用qt对k值与准确值的变化情况进行绘图
plt.xlabel('k-value')
plt.ylabel('accuracy of knn')
plt.show()
if __name__ == "__main__":
main()
(四)测试用例设计及调试过程截屏
测试用例,输入k的范围值,即k的范围是1~你输入的那个值之间的所有整数
运行完程序之后,程序会将k值与测试准确率之间的关系图画出来,便于观察两者之间的关系
一开始使用QT时,出现下列问题
解决办法:
原因是Anaconda中的pyqt5在windows下运行需要对应的一些dll文件,这里python在使用pyqt5时在当前目录下找不到qwindows.dll等之类的文件,在qt5的安装目录下找到plaforms文件夹(里面包含上面说的必要的dll文件)后,将其复制到python.exe(即为python运行的同级目录下即可)的同级目录下,既可以如下图所示,得到相应的图了
调试过程截屏
(五)总结
此次的knn原生实现,使得自己对于python的基本操作更加熟悉,比如字典,列表的一些基本操作等等;除此之外,对于一些库函数的使用也更加熟练,特别是在此次的作业中,使用了QT相关的画图函数。