1,学习并理解knn算法的原理
邻近算法,或者说K最邻近(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法。
KNN算法的思想非常简单:对于任意n维输入向量,分别对应于特征空间中的一个点,输出为该特征向量所对应的类别标签或预测值。
2,knn算法的数学实现
1)距离
1.欧几里得距离:它也被称为L2范数距离。欧几里得距离是我们在平面几何中最常用的距离计算方法,即两点之间的直线距离。在n维空间中,两点之间的欧几里得距离计算公式为:
2.曼哈顿距离:KNN算法通常的距离测算方式为欧式距离和曼哈顿距离,相比之下欧氏距离会更常用欧式距离公式
2)k的取值
一般是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的方差,最终找到一个比较合适的K值。
3,算法实践(python)
完整代码和注释
import operator
import matplotlib.pyplot as plt
import numpy as np
# 定义颜色列表,用于可视化不同类别的数据点
color = ['b', 'c', 'g', 'k', 'm', 'r', 'y', 'orange', 'tan', 'teal', 'darkblue', 'darkred', 'gold']
def knn(x, y, labels, k):
# 计算欧氏距离
dist = ((x - y) ** 2).sum(1)
dist = np.sqrt(dist)
# 对距离进行排序并获取索引
indx = dist.argsort()
# 计算前 k 个最近邻的类别
cnt = {}
for i in range(k):
if cnt.get(labels[indx[i]]) is None:
cnt[labels[indx[i]]] = 1
else:
cnt[labels[indx[i]]] += 1
# 按类别计数排序,获取出现频率最高的类别
c = sorted(cnt.items(), key=operator.itemgetter(1), reverse=True)
print(cnt)
return c[0][0]
# 生成随机数据
x, y = np.random.random(2) * 100, np.random.random([10, 2]) * 100
# 样本的类别标签
labels = [1, 0, 1, 2, 2, 1, 2, 1 ,0, 1]
# 使用 KNN 算法进行预测
pred = knn(x, y, labels, 3)
print(f'{x} 的类别是 {pred} {color[pred]}')
# 按类别将数据点分组
cls = {}
for i, label in enumerate(labels):
if cls.get(label) is None:
cls[label] = [y[i]]
else:
cls[label].append(y[i])
# 可视化数据点及其类别
for c in cls:
plt.plot([i[0] for i in cls[c]], [i[1] for i in cls[c]], 'o', color=color[c], label=str(c) + f' {color[c]}')
plt.legend()
# 绘制预测点
plt.plot(x[0], x[1], 'o', color='darkred', label=str(pred) + f' {color[pred]}')
plt.legend()
plt.show()
结果:
红色点根据knn算法分类为:1c