K 临近分类是一种监督式的分类方法, 首先根据已标记的数据对模型进行训练, 然后根据模型对新的数据点进行预测, 预测新数据点的标签(label), 也就是该数据所属的分类.
一, kNN 算法的逻辑
kNN 算法的核心思想是: 如果一个数据在特征空间中最相邻的 k 个数据中的大多数属于某一个类别, 则该样本也属于这个类别(类似投票), 并具有这个类别上样本的特性. 通俗地说, 对于给定的测试样本和基于某种度量距离的方式, 通过最靠近的 k 个训练样本来预测当前样本的分类结果.
例如, 借用百度的一张图来说明 kNN 算法过程, 要预测图中 Xu 的分类结果, 先预设一个距离值, 只考虑以 Xu 为圆心以这个距离值为半径的圆内的已知训练样本, 然后根据这些样本的投票结果来预测 Xu 属于 w1 类别, 投票结果是 4:1.
kNN 算法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别. kNN 算法在类别决策时, 只与极少量的相邻样本有关. 由于 kNN 算法主要靠周围有限的邻近的样本, 而不是靠判别类域的方法来确定所属类别的, 因此对于类域的交叉或重叠较多的待分样本集来说, kNN 方法较其他方法更为适合.
1,kNN 算法的计算步骤
kNN 算法就是根据距离待分类样本 A 最近的 k 个样本数据的分类来预测 A 可能属于的类别, 基本的计算步骤如下:
对数据进行标准化, 通常是进行归一化, 避免量纲对计算距离的影响;
计算待分类数据与训练集中每一个样本之间的距离;
找出与待分类样本距离最近的 k 个样本;
观测这 k 个样本的分类情况;
把出现次数最多的类别作为待分类数据的类别.
计算距离的方法有:"euclidean"(欧氏距离),"minkowski"(明科夫斯基距离), "maximum"(切比雪夫距离), "manhattan"(绝对值距离),"canberra"(兰式距离), 或 "minkowski"(马氏距离)等.
2,kNN 算法如何计算距离?
在计算距离之前, 需要对每个数值属性进行规范化, 这有助于避免较大初始值域的属性比具有较小初始值域的属性的权重过大.
对于数值属性, kNN 算法使用距离公式来计算任意两个样本数据之间的距离.
对于标称属性(如类别),kNN 算法使用比较法, 当两个样本数据相等时, 距离为 0; 当两个样本数据不等时, 距离是 1.
对于缺失值, 通常取最大的差值, 假设每个属性都已经映射到 [0,1] 区间, 对于标称属性, 设置差值为 1; 对于数值属性, 如果两个元组都缺失值, 那么设置差值为 1; 如果只有一个值缺失, 另一个规范化的值是 v, 则取差值为 1-v 和 v 的较大者.
3,kNN 算法如何确定 k 的值?
k 的最优值, 需要通过实验来确定. 从 k=1 开始, 使用检验数据集来估计分类器的错误率. 重复该过程, 每次 k 增加 1, 允许增加一个近邻, 选取产生最小错误率的 k. 一般而言, 训练数据集越多, k 的值越大, 使得分类预测可以基于训练数据集的较大比例. 在应用中, 一般选择较小 k 并且 k 是奇数. 通常采用交叉验证的方法来选取合适的 k 值.
二, KNeighborsClassifier 函数
使用 KNeighborsClassifier 创建 K 临近分类器:
- sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30,
- p=2, metric='minkowski', metric_params=None, n_jobs=None, **kwargs)
参数注释:
1,n_neighbors
临近的节点数量, 默认值是 5
2,weights
权重, 默认值是 uniform,
uniform: 表示每个数据点的权重是相同的;
distance: 离一个簇中心越近的点, 权重越高;
callable: 用户定义的函数, 用于表示每个数据点的权重
3,algorithm
auto: 根据值选择最合适的算法
ball_tree: 使用 BallTree
kd_tree:KDTree
brute: 使用 Brute-Force 查找
4,leaf_size
leaf_size 传递给 BallTree 或者 KDTree, 表示构造树的大小, 用于影响模型构建的速度和树需要的内存数量, 最佳值是根据数据来确定的, 默认值是 30.
5,p,metric,metric_paras
p 参数用于设置 Minkowski 距离的 Power 参数, 当 p=1 时, 等价于 manhattan 距离; 当 p=2 等价于 euclidean 距离, 当 p>2 时, 就是 Minkowski 距离.
metric 参数: 设置计算距离的方法
metric_paras: 传递给计算距离方法的参数
6,n_jobs
并发执行的 job 数量, 用于查找邻近的数据点. 默认值 1, 选取 - 1 占据 CPU 比重会减小, 但运行速度也会变慢, 所有的 core 都会运行.
7, 举个例子
下面的代码是最简单的 knn 分类器, 可以看出, knn 分类模型是由两部分构成的: 第一部分是训练数据(fit), 第二部分是预测数据(predict)
- from sklearn.neighbors import KNeighborsClassifier
- knn = KNeighborsClassifier(n_neighbors=3)
- x_train = [[0], [1], [2], [3]]
- y_train = [0, 0, 1, 1]
- knn.fit(x_train,y_train)
- x_new=[[1.1]]
- pred=knn.predict(x_new)
- print('pred:{0}'.format(pred))
三, 观察数据
由于 knn 分类是监督式的分类方法之前, 在构建一个复杂的分类模型之前, 首先需要已标记的数据集. 我们可以从 sklearn 的数据集中加载已有的数据进行学习:
- from sklearn.datasets import load_iris
- iris_dataset=load_iris()
查看 iris_dataset 的数据, 该对象的结构和字典非常类型:
- >>> iris_dataset.keys()
- dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])
1, 样本数据
data 是样本数据, 共 4 列 150 行, 列名是由 feature_names 来确定的, 每一列都叫做矩阵的一个特征(属性), 前 4 行的数据是:
- >>> iris_dataset.data[0:4]
- array([[5.1, 3.5, 1.4, 0.2],
- [4.9, 3. , 1.4, 0.2],
- [4.7, 3.2, 1.3, 0.2],
- [4.6, 3.1, 1.5, 0.2]])
2, 标签
target 是标签, 用数字表示, target_names 是标签的文本表示
- >>> iris_dataset.target[0:4]
- array([0, 0, 0, 0])
- >>> iris_dataset.target_names
- array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
3, 查看数据的散点图
查看数据的散点图矩阵, 按照数据的类别进行着色, 观察数据的分布:
- import pandas as pd
- import mglearn
- iris_df=pd.DataFrame(x_train,columns=iris_dataset.feature_names)
- pd.plotting.scatter_matrix(iris_df,c=y_train,figsize=(15,15),marker='o',hist_kwds={'bins':20}
- ,s=60,alpha=.8,cmap=mglearn.cm3)
四, 创建模型
我们使用 sklearn 数据集中的鸢尾花测量数据来构建一个复杂的分类模型, 并根据输入的数据点来预测鸢尾花的类别.
1, 拆分数据
把鸢尾花数据拆分为训练集和测试集:
- from sklearn.model_selection import train_test_split
- x_train,x_test,y_train,y_test=train_test_split(iris_dataset['data'],iris_dataset['target'],random_state=0)
2, 创建分类器
使用 KNeighborsClassifier 创建分类器, 设置参数 n_neighbors 为 1:
- from sklearn.neighbors import KNeighborsClassifier
- knn = KNeighborsClassifier(n_neighbors=1)
3, 使用训练集来构建模型
对于监督学习, 训练数据集包括两部分: 输入和结果(Lable), 每一行输入都对应一行结果, 结果是输入的正确分类(标签).
通常, 记 X_train 是训练的输入数据集, X_train 对应的结果是 y_train, 是训练数据集的输出, 通过 fit()函数来训练模型, 构建模型:
knn.fit(x_train, y_train)
4, 预测新数据
对于训练之后的模型, 使用 predict()函数来预测数据的结果.
- x_new=np.array([[5, 2.9, 1, 0.2]])
- prediction= knn.predict(x_new)
- print("prediction :{0} ,classifier:{1}".format(prediction,iris_dataset["target_names"][prediction]))
5, 评估模型
使用训练集和测试集来评估模型:
- y_pred=knn.predict(x_test)
- assess_model_socre=knn.score(x_test,y_test)
- print('Test set score:{:2f}'.format(assess_model_socre))
参考文档:
来源: https://www.cnblogs.com/ljhdo/p/10600613.html