概述
KNN,全称 K-NearestNeighbor,可以用来执行分类、回归任务。
名词解释
基本原理
KNN通过观察离预测点最近的点的类别,来决定预测点的类别,计算过程为:
- 计算训练样本和测试样本中每个样本点的距离(常见的距离度量有欧式距离,马氏距离等);
- 对上面所有的距离值进行排序;
- 选前k个最小距离的样本;
- 根据这k个样本的标签进行投票,得到最后的分类类别;
如下图所示:
中间绿色的点是要预测的点,蓝色和红色的点是已经预测完的点。
- k=1:即取最近的1个邻居为红色,则预测结果为红色。
- k=2:取最近的2个邻居,都是红色,则预测结果为红色。
- k=5:取最近的5个邻居,3个蓝色,2个红色,则预测结果为蓝色。
该算法的核心是如何获取k个邻居,即获得距离最近的k个点。这里的距离一般使用:
计算距离的算法多种多样,sklearn中常用的算法有:
- ball_tree
- kd_tree
- brute
找到k个邻居后,通过判断多数邻居的类别就可以计算出最终的类别,也可以为邻居指定不同的权重:比如根据距离预测点的距离设置不同的权重。也可以自定义权重规则。
适用场景
什么情况下选用knn算法,没有找到相关资料。
优缺点
优点
- 原理简单,容易理解,精度高,理论成熟。
- 既可以用来做分类也可以用来做回归;
- 可用于连续性、离散型数据;
- 训练时间复杂度为O(n):实际是在计算的时候对比的,根本不需要训练。
- 无数据输入假定:无优化参数。
- 对异常值不敏感:因为对比的是多个点,一个点的异常不影响结果。
缺点
- 计算复杂性高:数据量大的时候对耗费时间太长。
- 空间复杂性高;
- 样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);
- 计算结果不容易解释。
示例
sklearn实现knn算法的示例:
# train_data:训练集
# test_data:测试集
# columns:列名
# n_neighbors:k个数
# weights:权重,uniform:一样,distance:距离近的权重大,callable:自定义函数
# algorithm : {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}
# p:1, using manhattan_distance (l1), 2, euclidean_distance (l2),否则是 minkowski_distance (l_p).
def kNeighbors2(train_data, test_data, columns, n_neighbors, weights, algorithm, p):
print("n_neighbors %s, weights %s, algorithm %s, p %s" % (n_neighbors, weights, algorithm, p))
knn = KNeighborsRegressor(n_neighbors=n_neighbors, weights=weights, algorithm=algorithm, p=p)
# fit:训练集,目标值。
knn.fit(train_data[columns], train_data['price'])
score = knn.score(test_data[columns], test_data['price'])
print("score", score)
return score