赞
踩
K-近邻算法,也叫做KNN算法(K-Nearest Neighbor,KNN),其定义为:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
并且拥有如下的特性:
距离公式:
其中,欧式距离也被称为欧几里得距离,例如在二维平面上,两点之间的距离表示如图所示
在多维平面中,欧氏距离表示为
其他距离的衡量还有:余弦值距离(cos), 相关度 (correlation), 曼哈顿距离 (Manhattan distance)
如图所示,在图中有两块区域的点,绿色的点和红色的点,可以将这个图想象成是我们疫情期间的绿码和红码。
这时候出现了一个新的人,我们将他的位置看成是蓝色的点,那么这个人是绿码还是红码呢?
在K近邻算法中,K的意思就是图中我们画的以蓝点为圆心的圈圈中的点的个数,我们可以发现,当我们K值取1的时候,圈里面只有绿点(1个),当我们K值取3的时候,圈里面也只有绿点(3个),根据K近邻算法的算法思想,这个时候我们就可以认为该点(也就是蓝点)属于绿色的阵营里面。
由刚刚的例子我们也可以总结出来,KNN算法的算法过程如下所示:
1) 确定K的大小和距离计算方法
2) 从训练样本中得到K个与测试最相似的样本
3) 根据K个组相似样本的类别,通过少数服从多数的方式来确定测试样本的类别
K=1 K=5
优点:
缺点:
链接:https://pan.baidu.com/s/1Zq2w-fZivzaDfLDGs8DUxQ?pwd=5jfn
提取码:5jfn
--KNN算法的实例
画图picture.py(本文一开始的绿色和红色图)
- import numpy as np
- import matplotlib.pyplot as plt
-
- # 定义特征值
- raw_data_x = [[3.3144558, 2.33542461],
- [3.75497175, 1.93856648],
- [1.38327539, 3.38724496],
- [3.09203999, 4.47090056],
- [2.58593831, 2.13055653],
- [7.41206251, 4.80305318],
- [5.912852, 3.72918089],
- [9.21547627, 2.8132231],
- [7.36039738, 3.35043406],
- [7.13698009, 0.40130301]]
-
- # 定义目标值
- raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
-
- X_train = np.array(raw_data_x)
- y_train = np.array(raw_data_y)
-
- # 利用matplotlib绘制图像
- plt.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], color='g')
- plt.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1], color='r')
- plt.show()
-
-
- #加入预测点
- x = np.array([2.093607318, 2.365731514])
-
- plt.scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], color='g')
- plt.scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1], color='r')
- plt.scatter(x[0], x[1], color='b')
- plt.show()
样本集为网盘中的Prostate_Cancer.py
训练test.py
- import random
- import csv
-
- #读取
- with open('Prostate_Cancer.csv','r') as file:
- reader = csv.DictReader(file)
- datas=[row for row in reader]
-
- # print(datas)
-
- #分组
- random.shuffle(datas)
- n = len(datas)//3
- test_set = datas[0:n]
- train_set = datas[n:]
-
- #KNN
- def distance(d1,d2):
- res = 0
- for key in ("radius","texture","perimeter","area","smoothness","compactness","symmetry","fractal_dimension"):
- res += (float(d1[key])-float(d2[key]))**2
- return res**0.5
-
- K=33
-
- def knn(data):
- #1.距离
- res = [
- {"result":train['diagnosis_result'],"distance":distance(data,train)}
- for train in train_set
- ]
- #2.排序-升序
- res = sorted(res,key=lambda item:item['distance'])
- #3.取前K个
- res2 = res[0:K]
- #4.加权平均
- result = {'B': 0,'M': 0}
-
- #总距离
- sum = 0
- for r in res2:
- sum +=r['distance']
-
- for r in res2:
- result[r['result']]+=1-r['distance']/sum
-
- print(result)
- print(data['diagnosis_result'])
-
- if result['B']>result['M']:
- return 'B'
- else:
- return 'M'
-
- #测试阶段
- correct=0
- for test in test_set:
- result = test['diagnosis_result'] #真实结果
- result2 = knn(test)#测试集结果
-
- if result == result2:
- correct+=1
-
- print(f"检测正确的数目:{correct}") #正确的个数
- print(f"一共检测的样本数目:{len(test_set)}") #一共的个数
-
- # knn(test_set[0])
- print("检测的正确率:{:.2f}%".format(100*correct/len(test_set)))
实验结果
此时取的K值是5,当我们将K值取的过于大或者过于小时,可以发现实验的检测结果变差了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。