学习B站 【什么是KNN(K近邻算法)?【知多少】】 https://www.bilibili.com/video/BV1Ma411F7Y4/?share_source=copy_web&vd_source=d928ac2eb2c6b562d9488d15f78dfbf4
什么是KNN
NN neural network
并不是
KNN 是k-Nearest Neighbors
K 近邻算法 是机器学习中常见的分类算法
K-Nearest neighbors for classification
要判断一个新数据的类别
就要看他的邻居都是谁
KNN 中的K指的是【K个】邻居
eg: K=3 就是通过离得最近得3个样本,来判断新数据的类别
大小、颜色是数据的特征
苹果和梨是数据的【标签】
欧式距离:两点之间的直线距离
坐标轴距离的绝对值的和:曼哈顿距离
K的值太小,会受到个别因素的影响
K的值太大,又会受距离较远的特殊数据影响
K的取值受问题自身和数据集大小决定
KNN算法能做什么
讲文本分词、统计词频等处理后判断文章的类型
电商、视频网站可以找到与你类似的用户
But
计算新样本与所有样本的距离
按由近及远的顺序排列后
再按K值进行分类
因此数据越多KNN的计算量越大
效率就越低
很难
# # sklearn中的k近邻分类器在sklearn库中,可以使sklearn.neighbors.KNeighborsClassifier
# from sklearn.neighbors import KNeighborsClassifier
# #设置最近的3个邻居作为分类的依据
# neigh = KNeighborsClassifier(n_neighbors= 3, weights = 'uniform', algorithm = 'auto')
#
# X=[[0],[1],[2],[3]]
# y=[0,0,1,1]
#
# neigh.fit(X,y)
#
# text = [[1.1],[2.1]]
# data = neigh.predict(text)
# print(data)
# print(neigh.score(X,y))
import csv
# 读取
import random
with open('Prostate_Cancer.csv','r') as file:
# 以一个字典的形式来读取文件
reader = csv.DictReader(file)
# for row in reader:
# orderdict 是有序的字典
# print(row)
# for row in reader是做一个推到
# row把所有的row都给抽出来
# 存到一个datas里面
datas = [row for row in reader]
#读取
# [{'id': '1', 'diagnosis_result': 'M', 'radius': '23', 'texture': '12', 'perimeter': '151', 'area': '954', 'smoothness': '0.143', 'compactness': '0.278', 'symmetry': '0.242', 'fractal_dimension': '0.079'},
# print(datas)
# 分组
# 先打乱顺序
random.shuffle(datas)
# 一个训练组,一个测试组
# 确保我的算法是有效的
# 出来是个小数,用整除
n = len(datas)//3
# print(n)
test_set = datas[0:n]
train_set= datas[n:]
# 距离
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 = 5
def knn(data):
#距离
res=[
{"result":train['diagnosis_result'],"distance":distance(data,train)}
for train in train_set
]
#升序排列
sorted(res,key=lambda item:item['distance'])
# print(res)
#取前K个
res2 = res[0:K]
# print(res2)
#加权平均
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)))
knn(test_set[0])