0.基本介绍:
1.优点:
- 简单
- 精度高
- 对异常值不敏感
- 无需数据独立性假设
2.缺点:
- 时间复杂度高:要计算测试点与所有样本间的距离
- 空间复杂度高:要存储所有样本
- 数据分布不均匀时,会受到样本分布偏置的影响
3.应用:
4.关键参数:
- K值:越大,对数据集拟合程度越差,但泛化性能越好,对噪声越不敏感
- 距离度量:度量方式与待求解问题越接近效果越好
KNN_19">5.加权KNN:
- 通过给K个最近邻样本赋予一个与距离有关的权重,来平衡样本分布不平衡的问题。
-
反比例权重:最简单的形式是返回距离的倒数,有时候,完全一样或非常接近的样本权重会很大甚至无穷大。基于这样的原因,在距离求倒数时,在距离上加一个常量:weight = 1 / (distance + const),同时可以保证数值稳定性。
这种方法的潜在问题是,它为近邻分配很大的权重,稍远一点的会衰减的很快,对噪声会更加敏感。weights = 1/(dist_topk+delta)
-
高斯权重:使用正态分布赋值权重,使用时要注意距离的取值范围,结合高斯函数里的标准差取值,理论上会有很大影响,这里有一些参数相关实验和简单的数学原理。
import math sigma = 0.24 #越大越平缓 weights = (math.e)**((-1*dist_topk**2/(2*sigma**2))) *(1/(sigma*1.732*3.14))
-
sigmod函数加权:
import math alpha = 5 #越小越平缓 weight = 1/(1+ (math.e)**(-dist_topk*alpha))
-
其他函数加权:根据实际任务的需求,综合考量加权函数斜率、凹凸性、拟合能力和泛化能力、距离分布等情况选取合适函数,或自己设计对应函数,cos等函数均可以。
6.距离优化:几种距离的度量方式
- 欧式距离:两点间距离公式(对应维度作差的平方和开根号),
- 曼哈顿距离(城市街区距离):每个维度差的绝对值之和(走直角路线的路程)
- 切比雪夫距离:max(每个维度差的绝对值)
- 闵氏距离(闵可夫斯基距离):类似LP正则化,P=1:曼哈顿距离;P=2:欧氏距离;P无穷大:切比雪夫距离
上述距离都将各个维度分量的量纲、影响、分布相同看待了
- 标准化欧氏距离/加权欧氏距离:每个维度标准化后再进行欧氏距离(可以将方差的倒数看做一种加权,)
- 马氏距离:马氏距离是基于样本分布的一种距离。物理意义就是在规范化的主成分空间中的欧氏距离。所谓规范化的主成分空间就是利用主成分分析对一些数据进行主成分分解。再对所有主成分分解轴做归一化,形成新的坐标轴。由这些坐标轴张成的空间就是规范化的主成分空间。
马氏距离的特点:
1.量纲无关,排除变量之间的相关性的干扰;
2.马氏距离的计算是建立在总体样本的基础上的,如果拿同样的两个样本,放入两个不同的总体中,最后计算得出的两个样本间的马氏距离通常是不相同的,除非这两个总体的协方差矩阵碰巧相同;
3.计算马氏距离过程中,要求总体样本数大于样本的维数,否则得到的总体样本协方差矩阵逆矩阵不存在,这种情况下,用欧式距离计算即可。
- 余弦距离:夹角余弦可用来衡量两个向量方向的差异;机器学习中,借用这一概念来衡量样本向量之间的差异。 取值范围为[-1,1]。余弦越大表示两个向量的夹角越小,余弦越小表示两向量的夹角越大。当两个向量的方向重合时余弦取最大值1,当两个向量的方向完全相反余弦取最小值-1。
- 汉明距离:两个等长字符串s1与s2的汉明距离为:将其中一个变为另外一个所需要作的最小字符替换次数。例如:
The Hamming distance between “1011101” and “1001001” is 2.
(汉明重量:非零元素个数,即与0的汉明距离)
- 杰卡德距离:两个集合中不同元素占所有元素的比例来衡量两个集合的区分度
- 相关距离:1-相关系数(相关系数:衡量随机变量X与Y相关程度,取值范围是[-1,1],绝对值越大,越相关。当X与Y线性相关时,相关系数取值为1(正线性相关)或-1(负线性相关))
以上的距离度量方法度量的皆为两个样本(向量)之间的距离
- 信息熵:系统内部样本之间的一个距离,样本分布越分散(或者说分布越平均),信息熵就越大
7.速度优化:
- 基本思想是在存储数据样本的时候通过特定的数据结构,提前完成部分比较大小或排序的相关工作,从而实现新样本推理的加速。
- KD树:二叉树,相当于不断用垂直与坐标轴的超平面将K维空间切分构成一系列K维超矩形区域;以中值作为切割点,划分左右子树
- BallTree:抛弃了kd树画的方形,而建立球形,去掉棱角。简而言之,就是使用超球面而不是超矩形划分区域
sklearn_81">8.sklearn实现:
from sklearn.neighbors import KNeighborsRegressor
#使用KNN回归模型拟合数据,调整参数,使得预测方式为平均回归
uni_knr = KNeighborsRegressor(weights='uniform')
uni_knr.fit(X_train, y_train)
y_uni_knr_predict = uni_knr.predict(X_test)
r_squared['uniform weighted KNN'] = uni_knr.score(X_test, y_test)