机器学习笔记—k近邻(KNN
)算法介绍(3)—附完整代码
以下都是本人在学习机器学习过程中的一些心得和笔记,仅供参考。
KNN
算法应该可以说是最简单的机器学习算法了,构建KNN
模型只需要保存训练数据集即可。
想要对新的数据点做出预测,算法会在训练数据集中找到最近的数据点,也就是它的"最近邻"。
文章目录
1. KNN
算法的简单介绍
1.1 KNN
算法的流程
对每一个未知数据点皆执行:
- 计算未知数据点到所有已知数据点的距离
- 按照所得距离进行排序
- 选取其中前
K
个与未知数据点离得最近的数据点 - 统计
K
个点中各个类别的个数 - 上述
K
个点里类别出现频率最高的作为未知点的类别
- 简而言之:
KNN
算法的核心三要素——衡量距离,选择K值,分类决策
对于衡量距离来说:KNN
算法中要求数据的所有特征都可以做比较量化若在数据特征中存在非数值类型,必须采用手段将其量化为数值。(由此也引发了量化时量纲不同的问题,最后由在距离度量中引入期望,方差来解决)
用于计算距离的方法也有很多,例如:欧几里得距离,曼哈顿距离,上确界距离,闵可夫斯基距离等等,这里不一一介绍,需读者自行查阅!
对于选择K值来说: K值选择是KNN
算法的关键,K值选择对近邻算法的结果有重大影响。
- K值的具体含义:在决策时通过依据测试样本的K个最近邻"数据样本"做决策判断。
K值一般取较小值,通常采用交叉验证法来选取最优K值,也就是比较不同的K值时的交叉验证平均误差,选择平均误差最小的那个K值。
可以理解为对K值的选择就是对训练模型中参数的选择,交叉验证法(后面做了详细介绍)就可以理解为损失函数。
对于分类决策来说:主要有两种方法
- 投票表决
少数服从多数,输入实例的K个最近邻中哪种类(label)的实例点最多,流分为该类
- 加权投票法(改进)
根据距离的远近,对K个近邻的投票做加权,距离越近权重越大(比如权重为距离的倒数)
KNN
算法的步骤
1.2 KNN
算法的优缺点
- 优点
- 理论成熟,思想简单,既可以用来做分类又可以做回归
- 可以用于非线性分类
- 训练时间复杂度比支持向量机之类的算法低
- 和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
- 由于
KNN
算法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属的类别,因此对于类域的交叉或重叠较多的待分类样本集来说,KNN
算法较其他方法更为适合 - 该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量比较小的类域采用这种算法比较容易产生误分类情况
- 缺点
- 计算量大,尤其是特征数非常多的时候
- 样本不平衡的时候,对稀有类别的预测准确率低
KD
树,球树之类的模型建立需要大量的内存- 是惰性学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
- 相比决策树模型,
KNN
模型的可解释性不强
2. K近邻分类
KNN
算法最简单的版本只考虑一个最近邻,也就是与我们想要预测的数据点最近的训练数据点。预测结果就是这个训练数据点的已知输出。
2.1 forge
数据集的简单应用
下面给出KNN
算法分类在forge
数据集上的应用:
ps
:forge
,wave
等数据集都是内置的
import mglearn
import matplotlib.pyplot as plt
mglearn.plots.plot_knn_classification(n_neighbors=1) #利用mglearn库画图
plt.show()
forge
数据集的预测结果
图中添加了3个新数据点(用五角星表示)。对于每个新的数据点,我们标记了训练集中与它最近的点。单一最近邻算法的预测结果就是那个点的标签(对应五角星的颜色)。
当然,我们不仅可以考虑最近邻,还可以考虑任意个(K个)邻居,这也是KNN
算法名字的由来!
例如我们取3个近邻:
import mglearn
import matplotlib.pyplot as plt
mglearn.plots.plot_knn_classification(n_neighbors=3)#利用mglearn库画图
plt.show()
forge
数据集的预测结果
和上面一样,预测结果可以从五角星的颜色看出。你可以发现,左上角新数据点的预测结果与只用一个邻居时的预测结果不同。
当然上面的都是二分类问题,KNN
算法也适用于多分类的数据集!
对于多分类问题,我们数出每个类别分别有多少个邻居,然后将最常见的类别作为预测结果。
2.2 通过sklearn
来应用KNN
算法
- 首先将数据分为训练集和测试集,以便评估泛化性能:
from sklearn.model_selection import train_test_split
#导入sklearn库的train_test_split方法
X, y = mglearn.datasets.make_forge() #导入forge数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
#利用sklearn的train_test_split方法划分数据集
- 然后,导入类并且将其实例化。这是可以设定超参数,比如邻居的个数:
from sklearn.neighbors import KNeighborsClassifier
#导入sklearn中的KNeighborsClassifier算法(KNN分类)
clf = KNeighborsClassifier(n_neighbors=3)
#实例化,并且设定超参数,即K=3
- 随之,利用训练集对这个分类器进行拟合。
- 对于
KNeighborsClassifier
来说就是保存数据集,以便在预测时计算与邻居之间的距离:
clf.fit(X_train