K最近邻(k-Nearest Neighbor,KNN)分类算法的核心思想是如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法可用于多分类,KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,作为预测值。
一、kNN概念描述
kNN算法又称为k最近邻(k-nearest neighbor classification)分类算法。所谓的k最近邻,就是指最接近的k个邻居(数据),即每个样本都可以由它的K个邻居来表达。
kNN算法的核心思想是,在一个含未知样本的空间,可以根据离这个样本最邻近的k个样本的数据类型来确定样本的数据类型。
该算法涉及3个主要因素:训练集、距离与相似的衡量、k的大小;主要考虑因素:距离与相似度;
二、举例说明
右图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?
KNN的算法过程是是这样的:
最小的圈K=3,第二个圈K=5
从上图中我们可以看到,图中的数据集是良好的数据,即都打好了label,一类是蓝色的正方形,一类是红色的三角形,那个绿色的圆形是我们待分类的数据。
如果K=3,那么离绿色点最近的有2个红色三角形和1个蓝色的正方形,这3个点投票,于是绿色的这个待分类点属于红色的三角形。
如果K=5,那么离绿色点最近的有2个红色三角形和3个蓝色的正方形,这5个点投票,于是绿色的这个待分类点属于蓝色的正方形。(参考 酷壳的 K Nearest Neighbor 算法 )
我们可以看到,KNN本质是基于一种数据统计的方法!其实很多机器学习算法也是基于数据统计的。
三、kNN算法的特点
KNN算法不仅可以用于分类,还可以用于过渡,比如在两个色度之间取过渡色。
KNN算法当前主要使用加权投票法,即根据距离的远近,对近邻的投票进行加权,距离越近则权重越大(权重为距离平方的倒数)。
优点:易于实现,无需估计参数,无需训练,支持增量学习,能对超多边形的复杂决策空间建模;
KNN 算法的主要缺点是, 当训练样本数量很大时将导致很高的计算开销。KNN 算法是懒散的分类算法, 对于分类所需的计算都推迟到分类时才进行, 在其分类器中存储有大量的样本向量, 在未知类别样本需要分类时, 再计算和所有存储样本的距离, 对于高维文本向量或样本集规模较大的情况, 其时间和空间复杂度较高。
四、sk-learn中的KNN
sklearn.neighbors可以处理 Numpy 数组或 scipy.sparse矩阵作为其输入。 对于密集矩阵,大多数可能的距离度量都是支持的。对于稀疏矩阵,支持搜索任意的 Minkowski 度量。
尽管它简单,但最近邻算法已经成功地适用于很多的分类和回归问题,例如手写数字或卫星图像的场景。 作为一个 non-parametric(非参数化)方法,它经常成功地应用于决策边界非常不规则的分类情景下。
1、为了完成找到两组数据集中最近邻点的简单任务, 可以使用 sklearn.neighbors 中的无监督算法:
from sklearn.neighbors import NearestNeighbors
import numpy as np
#生成数组
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
nbrs = NearestNeighbors(n_neighbors=2, algorithm='ball_tree').fit(X)
distances, indices = nbrs.kneighbors(X)
print(indices)
print(distances)
'''
输出:
[[0 1]
[1 0]
[2 1]
[3 4]
[4 3]
[5 4]]
[[0. 1. ]
[0. 1. ]
[0. 1.41421356]
[0. 1. ]
[0. 1. ]
[0. 1.41421356]]
'''
2、利用KNeighborsClassifier 分析鸢尾花的数据集
from sklearn import datasets
#导入内置数据集模块
from sklearn.neighbors import KNeighborsClassifier
#导入sklearn.neighbors模块中KNN类
import numpy as np
iris=datasets.load_iris()
# print(iris)
#导入鸢尾花的数据集,iris是一个数据集,内部有样本数据
iris_x=iris.data
iris_y=iris.target
indices = np.random.permutation(len(iris_x))
#permutation接收一个数作为参数(150),产生一个0-149一维数组,只不过是随机打乱的
iris_x_train = iris_x[indices[:-10]]
#随机选取140个样本作为训练数据集
iris_y_train = iris_y[indices[:-10]]
# 并且选取这140个样本的标签作为训练数据集的标签
iris_x_test = iris_x[indices[-10:]]
# 剩下的10个样本作为测试数据集
iris_y_test = iris_y[indices[-10:]]
# 并且把剩下10个样本对应标签作为测试数据及的标签
knn = KNeighborsClassifier()
# 定义一个knn分类器对象
knn.fit(iris_x_train, iris_y_train)
# 调用该对象的训练方法,主要接收两个参数:训练数据集及其样本标签
iris_y_predict = knn.predict(iris_x_test)
# 调用该对象的测试方法,主要接收一个参数:测试数据集
score = knn.score(iris_x_test, iris_y_test, sample_weight=None)
# 调用该对象的打分方法,计算出准确率
print('iris_y_predict = ')
print(iris_y_predict)
# 输出测试的结果
print('iris_y_test = ')
print(iris_y_test)
# 输出原始测试数据集的正确标签,以方便对比
print('Accuracy:', score)
# 输出准确率计算结果</span>
'''
iris_y_predict =
[2 0 2 2 2 0 0 1 2 0]
iris_y_test =
[2 0 2 2 2 0 0 1 1 0]
Accuracy: 0.9
'''
end...
网友评论