机器学习笔记3-k近邻法
k近邻法输入为实例的特征向量,对应于特征空间中的点;输出为实例的类别。分类时,会根据其k个最近邻的训练实例的类别,通过多数表决等方式进行预测。因此,k近邻法不具有显示的学习过程。它包括三个基本要素:k值的选择、距离度量以及分类决策规则。
- k值的选择会对算法结果产生重要影响。当选择较小的k值时,只有与实例点较近的训练实例会对预测结果起作用,近似误差会减小。但预测结果会对近邻的训练实例非常敏感,估计误差会增大。如果邻近训练实例恰好是噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合;如果选择较大的k值,可以减少学习的估计误差,但近似误差会增大。这时与实例较远的训练实例也会对预测起作用。k值的增大意味着模型变得简单。在应用中,k值一般取一个比较小的数值,可以用grid_search来找一个最佳k值。
- 距离度量,能反映出特征空间中两个实例点的相似程度。这里距离一般用欧式距离,也可以用更一般的
距离。
这里 。当 时,为欧氏距离;当 时,为曼哈顿距离;当 时,为各个坐标距离的最大值。 - 分类决策规则一般会采用多数表决
k近邻法的实现:kd树
k近邻法最简单的实现方法是线性扫描,这时要计算实例与每个训练实例的距离。这种方法非常耗时。为了提高算法效率,可以用特殊的结构存储训练数据,进而基于这个数据结构进行搜索。比如构建kd树的方法。kd树有点类似于二叉搜索树,两者都满足对于一个根节点,其值不小于左子树的任何节点,且不大于右子树的任何节点。所不同的是构造过程,kd树是基于
空间,会直接对特征空间每一维进行划分;二叉搜索树是将元素一个一个添加的过程,与堆的构建一样。
- 如何构造kd树
输入:k维空间数据集T={ },其中
(1)选择 为坐标轴,以T中所有实例的 坐标的中位数为切分点(根结点),将 这一维分成两个子树,左子树对应坐标 小于根节点的坐标,右子树对应坐标 大于根节点的坐标。
(2)重复:对深度为 的结点,选择 这一维进行切分, ,以 这一维的中位数作为切分点(根结点),将该结点所包含的数据集划分到左右两个子树中。
(3)直到所有叶结点只包括一个样本,则停止划分。 - 如何搜索kd树
从根结点出发,向下访问kd树。若目标点当前维的坐标小于切分点的坐标,则移动到左子结点,否则移到右子结点,直到子结点为叶结点。以此叶结点为当前最近点,递归地向上回退,在每个结点进行以下操作:
(1)若该结点保存的实例点距离目标点更近,则以该实例点为当前最近点
(2)检查该结点的另一子结点所包含的数据集是否有更近的点。如果有,则移到该子结点区域递归地进行最近邻搜索,否则向上回退
(3)当回退到根结点,搜索结束。(此处写的比较粗糙,具体可参考李航《统计学习方法》,从划分区域和球体相交的角度更好理解)
在python的机器学习库scikit-learn中,有能直接拿来用的knn函数KNeighborsClassifier,其参数n_neighbors即为k值。以下是利用KNeighborsClassifier实现的一小段代码,数据集是sklearn中的内置数据集:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.neighbors import KNeighborsClassifier
iris = load_iris()
x, y = iris.data, iris.target
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25,random_state=33)
scaler=preprocessing.StandardScaler()
x_train=scaler.fit_transform(x_train)
x_test=scaler.transform(x_test)
knn=KNeighborsClassifier(n_neighbors=3)
knn.fit(x_train,y_train)
y_train_predict=knn.predict(x_train)
from sklearn import metrics
print(metrics.accuracy_score(y_train,y_train_predict))
y_predict=knn.predict(x_test)
print(metrics.accuracy_score(y_test,y_predict))
参考
李航《统计学习方法》
https://mlnote.wordpress.com/2015/12/16/python机器学习实践与kaggle实战-machine-learning-for-kaggle-competition-in-python/