一、什么是knn算法
KNN(K-Nearest Neighbor)算法是机器学习算法中最基础、最简单的算法之一。它既能用于分类,也能用于回归。KNN通过测量不同特征值之间的距离来进行分类。对于任意n维输入向量,分别对应于特征空间中的一个点,输出为该特征向量所对应的类别标签或预测值。K是用于识别新数据点的类似邻居的数字。
“看一个人什么样,看他身边的朋友什么样就知道了”,寻找最近的K个数据,推测新数据的分类。
二、算法原理
- 通用步骤
- 计算距离(常用欧几里得距离或马氏距离)
- 升序排列
- 区前K个
- 加权平均
- K的选取
- K太大:导致分类模糊
- K太小: 受个例影响,波动较大
- 如何选取K
- 经验
- 均方根误差
计算距离
欧几里德距离
曼哈顿距离
闵可夫斯基距离
马氏距离
K近邻参数-官网教程:
API Reference — scikit-learn 0.24.2 documentation
三、实战应用
数据集:
链接:https://pan.baidu.com/s/1w8cyvknAazrAYnAXdvtozw
提取码:zxmt
import random #随机数据
import csv
#读取数据
with open('Prostate_Cancer.csv','r') as file:
reader = csv.DictReader(file)
datas = [row for row in reader]
#分组
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=4#可以任一值,但不能太大太小
def knn(data):
#1.距离
res=[{"result":train ['diagnosis_result'],"distance":distance(data,train)}
for train in train_set]
#2.排序(从小到大)
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
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("准确率:{:.2f}%".format(100*correct/len(test_set)))