1 概述

02 kNN-k邻近算法 - 图1邻近算法(k-Nearest Neighbors):在特征空间中,如果一个样本附近的02 kNN-k邻近算法 - 图2个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。

2 算法

2.1 k近邻算法

算法2.1(k近邻算法)
输入:训练数据集
02 kNN-k邻近算法 - 图3
其中,02 kNN-k邻近算法 - 图4为实例的特征向量,02 kNN-k邻近算法 - 图5为实例的类别,02 kNN-k邻近算法 - 图6;实例特征向量02 kNN-k邻近算法 - 图7
输出:实例02 kNN-k邻近算法 - 图8属于的类02 kNN-k邻近算法 - 图9
(1)根据给定的距离度量,在训练集02 kNN-k邻近算法 - 图10中找出与02 kNN-k邻近算法 - 图11最邻近的02 kNN-k邻近算法 - 图12个点,涵盖这02 kNN-k邻近算法 - 图13个点的02 kNN-k邻近算法 - 图14的领域基座02 kNN-k邻近算法 - 图15
(2)在02 kNN-k邻近算法 - 图16中根据分类决策规则(如多数表决)决定02 kNN-k邻近算法 - 图17的类别02 kNN-k邻近算法 - 图18
02 kNN-k邻近算法 - 图19 (2.1)
式(1.1)中,02 kNN-k邻近算法 - 图20为只是函数,即当02 kNN-k邻近算法 - 图21时I为1,否则02 kNN-k邻近算法 - 图22为0
02 kNN-k邻近算法 - 图23近邻法的特殊情况是02 kNN-k邻近算法 - 图24的情形,称为最近邻算法。对于输入的实例点(特征向量)02 kNN-k邻近算法 - 图25,最近邻法将训练数据集中与02 kNN-k邻近算法 - 图26最近邻的类作为02 kNN-k邻近算法 - 图27的类。
02 kNN-k邻近算法 - 图28近邻法没有显式的学习过程。

2.2 k近邻模型

02 kNN-k邻近算法 - 图29近邻法使用的模型实际上对应于特征空间的划分。模型由三个基本要素——距离度量、02 kNN-k邻近算法 - 图30值的选择和分类决策规则决定。

模型

距离度量

特征空间中两个实例点的距离是两个实例点相似程度的反映。02 kNN-k邻近算法 - 图31近邻模型的特征空间一般是02 kNN-k邻近算法 - 图32维实数向量空间02 kNN-k邻近算法 - 图33。使用的距离是欧氏距离,但也可以是其他距离,如更一般的02 kNN-k邻近算法 - 图34距离(02 kNN-k邻近算法 - 图35 distance)或Minkowski距离(Minkowski distacne)。
设特征空间02 kNN-k邻近算法 - 图36是n维实数向量空间02 kNN-k邻近算法 - 图37,02 kNN-k邻近算法 - 图3802 kNN-k邻近算法 - 图3902 kNN-k邻近算法 - 图40距离定义为
02 kNN-k邻近算法 - 图41 (2.1)
这里02 kNN-k邻近算法 - 图42。当02 kNN-k邻近算法 - 图43时,称为欧式距离(Euclidean distance),即
02 kNN-k邻近算法 - 图44 (2.2)
02 kNN-k邻近算法 - 图45时,成为曼哈顿距离(Manhattan distance),即
02 kNN-k邻近算法 - 图46 (2.3)
02 kNN-k邻近算法 - 图47时,它是各个坐标距离的最大值,即
02 kNN-k邻近算法 - 图48 (2.4)

k值的选择

02 kNN-k邻近算法 - 图49值的选择会对02 kNN-k邻近算法 - 图50近邻法的结果产生重要影响。

  • 02 kNN-k邻近算法 - 图51值的减少就意味着整体模型变得复杂,容易过拟合
  • 02 kNN-k邻近算法 - 图52值的增大就意味着整体的模型变得简单
  • 如果02 kNN-k邻近算法 - 图53时,模型过于简单,完全忽略训练实例中的大量有用信息,实不可取的

在应用中,02 kNN-k邻近算法 - 图54值一般取一个比较小的数值,通常采用交叉验证法来选取最优的02 kNN-k邻近算法 - 图55值。

分类决策规则

02 kNN-k邻近算法 - 图56近邻法中的分类决策规则往往是多数表决,即由输入实例的02 kNN-k邻近算法 - 图57个邻近的训练实例中的多数类决定输入实例的类。
多数表决规则(majority voting rule)有如下解释:如果分类的损失函数为0-1损失函数,分类函数为
02 kNN-k邻近算法 - 图58
那么误分类的概率是
02 kNN-k邻近算法 - 图59
对给定的实例02 kNN-k邻近算法 - 图60,其最邻近的02 kNN-k邻近算法 - 图61个训练实例点沟通集合02 kNN-k邻近算法 - 图62。如果涵盖02 kNN-k邻近算法 - 图63的区域的类别是02 kNN-k邻近算法 - 图64,那么误分类率是
02 kNN-k邻近算法 - 图65
要使误分类率最小即经验风险最小,就要使02 kNN-k邻近算法 - 图66最大,所以多数表决规则等价于经验风险最小化。

3 实现

3.1 一般实现(基于sklearn)

  1. class KNNClassifier:
  2. def __init__(self, k):
  3. """初始化kNN分类器"""
  4. assert k > 1, "k must be valid"
  5. self.k = k
  6. self._X_train = None
  7. self._y_train = None
  8. def fit(self, X_train, y_train):
  9. """根据训练数据集X_train和y_train训练kNN分类器"""
  10. assert X_train.shape[0] == y_train.shape[0], \
  11. "the size of X_train must equal to the size of y_train"
  12. assert self.k <= X_train.shape[0], \
  13. "the size of X_train must be at least k."
  14. self._X_train = X_train
  15. self._y_train = y_train
  16. return self
  17. def predict(self, X_predict):
  18. """给定待预测数据集X_predict,返回表示X_predict的结果向量"""
  19. assert self._X_train is not None and self._y_train is not None, \
  20. "must fit before predict!"
  21. assert X_predict.shape[1] == self._X_train.shape[1], \
  22. "the feature number of X_predict must be equal to X_train"
  23. y_predict = [self._predict(x) for x in X_predict]
  24. return np.array(y_predict)
  25. def _predict(self, x):
  26. """给定单个待预测数据x,返回x的预测结果值"""
  27. assert x.shape[0] == self._X_train.shape[1], \
  28. "the feature number of X_predict must be equal to X_train"
  29. distances = [sqrt(np.sum((x_train - x) ** 2))
  30. for x_train in self._X_train]
  31. nearest = np.argsort(distances)
  32. topK_y = [self._y_train[i] for i in nearest[:self.k]]
  33. votes = Counter(topK_y)
  34. return votes.most_common(1)[0][0]
  35. def __repr__(self):
  36. return "KNN(k=%d)" % self.k
  37. import numpy as np
  38. from sklearn import datasets
  39. iris = datasets.load_iris()
  40. X = iris.data
  41. y = iris.target
  42. # 数据拆分成训练集和验证集合
  43. from sklearn.model_selection import train_test_split
  44. X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)
  45. # 数据归一化
  46. from sklearn.preprocessing import StandardScaler
  47. standardScaler = StandardScaler()
  48. standardScaler.fit(X_train)
  49. X_train_standard = standardScaler.transform(X_train)
  50. X_test_standard = standardScaler.transform(X_test)
  51. # 训练
  52. knn_clf = KNeighborsClassifier(n_neighbors=3)
  53. knn_clf.fit(X_train_standard, y_train)
  54. # 预测准确率
  55. knn_clf.score(X_test_standard, y_test)

3.2 构造kd树实现

3.3 搜索kd树实现

4 实践

4.1 一般使用流程

  1. 1)收集数据:可以使用任何方法
  2. 2)准备数据:距离计算所需要的数值,最好是结构化的数据格式
  3. 3)分析数据:可以使用任何方法
  4. 4)训练算法:此步骤不适合k-邻近算法
  5. 5)测试算法:计算错误率
  6. 6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-临近算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理

4.2 超参数和模型参数

  • kNN算法没有模型参数
  • kNN算法中的k是典型的超参数

    4.3 基于scikit-learn的使用

    5 问题集合

    1. 参照图1(待补上),在二维空间中给出实例点,画出02 kNN-k邻近算法 - 图67为1和2的02 kNN-k邻近算法 - 图68近邻构成的空间划分,并对其进行比较,体会02 kNN-k邻近算法 - 图69值选择与模型复杂度及预测准确率的关系。
    2. 利用例题2(待补上)构造的02 kNN-k邻近算法 - 图70树求02 kNN-k邻近算法 - 图71的最紧邻点。
    3. 参照算法3(待补上),写出输出为02 kNN-k邻近算法 - 图7202 kNN-k邻近算法 - 图73近邻的算法。

    6 继续阅读

    详见《统计机器学习》第二版02 kNN-k邻近算法 - 图74参考文献

CHANGELOG

2020年12月14日20:42:31
第一版更新,结合《统计机器学习》和《机器学习实战》