KNN-K最近邻算法
什么是KNN算法
KNN算法是寻找最近的K个数据,推测新数据的分类
算法原理
通用步骤
- 计算距离(常用有欧几里得距离、马氏距离)
- 升序排序
- 取前K个
- 加权平均
K的选取
- K太大:会导致分类模糊
- K太小:容易受个例影响,波动较大
- 选取:均方根误差(找到峰值
实例:预测癌症良性 OR 恶性
数据分析与预处理
M:恶性
B:良性
其他数据为判断良性 、 恶性的依据
划分数据集
取数据的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值
先尝试K取5
将运算后的数据按距离升序排列
选取距离最小的k个样点
加权平均
分类计算加权平均距离,多数表决预测
源码
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)))