持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
KNN算法是寻找最近的K个数据,以此推测新数据的分类算法。 所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法。
通用步骤
K的选取
数据集结构如下图所示:
数据标签
其他字段组成八维的数据集,为后续判断良性 、 恶性的依据
取数据的1/3作为测试集,2/3作为训练集
import random
import csv
# 癌症预测数据文件读取
with open("Prostate_Cancer.csv", "r") as file:
reader = csv.DictReader(file)
datas = [row for row in reader]
# 分组 -训练集2/3 -测试集1/3
# 将数据打乱,每次得到不同的分组
random.shuffle(datas)
n = len(datas) // 3
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
分类计算加权平均距离,多数表决预测
import random
import csv
# 癌症预测数据文件读取
with open("Prostate_Cancer.csv", "r") as file:
reader = csv.DictReader(file)
datas = [row for row in reader]
# 分组 -训练集2/3 -测试集1/3
# 将数据打乱,每次得到不同的分组
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 = 5
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("准确个数:", correct)
print("测试总数:", len(test_set))
print("准确率:{:.2f}%".format(100 * correct / len(test_set)))