一、KNN算法概念
KNN算法,全称为 K-Nearest Neighbors 算法,是一种基于实例的学习(instance-based learning)方法,在机器学习领域中被广泛应用于分类和回归问题。
二、KNN算法原理
KNN算法的基本假设是“相似的事物往往会有相似的输出”。即一个观测样本的类别可以通过观察它周围邻近的K个最相似样本的类别来确定。
分类过程:
1.在进行分类时,对于新的待分类数据点,首先计算它与训练集中所有已知类别数据点的距离(常用的距离度量包括欧氏距离、马氏距离、切比雪夫距离等)。
计算距离:对于测试集中的每个样本,计算它与训练集中每个样本的距离。
①曼哈顿距离
②欧几里得距离
2.接着,按照距离从小到大排序,选取前K个最近邻的数据点作为参考。
3.最后,统计这K个最近邻数据点所属类别的频数或采用加权投票的方式,将出现频率最高的类别作为新数据点的预测类别。
回归过程:
对于回归问题,KNN算法则是通过计算K个最近邻的平均值或者其他聚合函数(如中位数)来预测目标变量的数值。
三、实例
KNN算法:
def KNN(in_x, x_lables, y_lables, k):
x_lables_size = x_lables.shape[0]
# 计算两个颜色之间的欧氏距离
distances = (np.tile(in_x, (x_lables_size, 1)) - x_lables) ** 2
ad_distance = distances.sum(axis=1)
sq_distance = ad_distance ** 0.5 # 开方后得到最后的欧式距离
ed_distance = sq_distance.argsort()
classdict = {}
for i in range(k):
voteI_lable = y_lables[ed_distance[i]]
classdict[voteI_lable] = classdict.get(voteI_lable, 0) + 1
sort_classdict = sorted(classdict.items(), key=operator.itemgetter(1), reverse=True)
return sort_classdict[0][0]
训练数据:
def DataSet():
group = np.array([[3, 104], [2, 100], [1, 81], [10, 80], [10, 51], [51, 10], [76, 21], [101, 10], [99, 5], [98, 2]])
lables = ['red', 'red', 'red', 'red', 'red', 'green', 'green', 'green', 'green', 'green']
return group, lables
测试数据:
def TestData():
test_x = [30, 50]
return test_x
绘图:
def draw(color):
plt.scatter(group[:, 0], group[:, 1], c=lable, alpha=0.5)
plt.scatter(test_x[0], test_x[1], c=color, marker='x')
plt.show()
运行结果:
输入数据所对应的类别是:red
完整代码:
import numpy as np
import operator
import matplotlib.pyplot as plt
# 训练数据
def DataSet():
group = np.array([[3, 104], [2, 100], [1, 81], [10, 80], [10, 51], [51, 10], [76, 21], [101, 10], [99, 5], [98, 2]])
lables = ['red', 'red', 'red', 'red', 'red', 'green', 'green', 'green', 'green', 'green']
return group, lables
# 测试数据
def TestData():
test_x = [30, 50]
return test_x
def KNN(in_x, x_lables, y_lables, k):
x_lables_size = x_lables.shape[0]
# 计算两个颜色之间的欧氏距离
distances = (np.tile(in_x, (x_lables_size, 1)) - x_lables) ** 2
ad_distance = distances.sum(axis=1)
sq_distance = ad_distance ** 0.5 # 开方后得到最后的欧式距离
ed_distance = sq_distance.argsort()
classdict = {}
for i in range(k):
voteI_lable = y_lables[ed_distance[i]]
classdict[voteI_lable] = classdict.get(voteI_lable, 0) + 1
sort_classdict = sorted(classdict.items(), key=operator.itemgetter(1), reverse=True)
return sort_classdict[0][0]
def draw(color):
plt.scatter(group[:, 0], group[:, 1], c=lable, alpha=0.5)
plt.scatter(test_x[0], test_x[1], c=color, marker='x')
plt.show()
if __name__ == '__main__':
group, lable = DataSet()
test_x = TestData()
print('输入数据所对应的类别是:{}'.format(KNN(test_x, group, lable, 3)))
draw(KNN(test_x, group, lable, 3))
四、总结
KNN算法的优点:
1.理论简单:KNN算法原理直观易懂,无需构建复杂的数学模型,只需存储训练数据即可。
2.对异常值不敏感:由于直接比较临近样本,因此对离群点的敏感度相对较低。
3.无须做特征选择:KNN不需要对数据进行特殊预处理,也不需要事先了解数据分布,适用于非线性分类问题。
KNN算法的缺点:
1.计算复杂度高:随着样本数量增加,计算所有样本的距离以及排序操作的时间成本会迅速增大,尤其在大型数据集上效率较低。
2.内存消耗大:需要存储所有训练样本,当样本空间维度高或样本数量多时,占用大量内存资源。
3.参数K的选择:K值的选择对模型性能有很大影响,没有统一的标准来决定最优K值。