数据挖掘中,K-NN(最近邻)算法是常用的分类技术之一。与决策树和基于规则的算法不同,K-NN算法采用消极学习方法,只在需要分类测试集时才对训练集进行建模。
K-NN算法简单易理解,不需要建模,参数简单,对于多类别的分类效果明显,缺点是对于异常值很敏感,计算量大,对于样本不平衡的数据集敏感。
K-NN算法原理
对于一个未知点,我们选择不同的距离算法,计算所有训练集中的点与未知点的距离,选择K个距离未知点最近的点,那么我们得到K个训练集的点,在这K个点中,我们选择类别数最多的类别,作为这个未知点的类别。
K-NN算法实现步骤
选择K值;
根据不同的距离算法,选择K个最近邻点;
在K个最近邻点中,计算每一类的数;
选择最多数的类别作为预测类别;
KNN算法中,当我们指定了计算距离的方法,选择一个合适的K值就很关键了。
图1:摘自《数据挖掘导论》
图1a:K =1,未知点与“-”最近邻,所以被划分为“-”;
图1b:K = 2,未知点与一个“-”和“+”最近邻,则随机选择一个符号作为类别;
图1c:K = 3,这时候,最近邻中“+”有两个,则划分为“+”;
接下来,我们来看另一种情况:
图2:摘自《数据挖掘导论》
在图2,根据我们的经验,未知点显然属于“+”类别,但是由于我们将K值取得较大,K-NN算法将未知点划分到了“-”。
所以K值的选择就显得很重要了:
K太小了,则容易受训练集的噪声影响而产生过拟合;
K太大了,则可能会误分测试集;
在实际应用中,K值一般取一个比较小的数值,可以采用交叉验证法(简单来说,就是一部分样本做训练集,一部分做测试集)来选择最优的K值。
使用R语言实现K-NN算法
在使用R语言实现K-NN算法前,我们先来假设这么一个场景:
根据我们投放了一个广告,并收集了观看了我们的广告的客户的一部分详细信息,得到一份客户在观看了广告后是否购买我们产品的数据集。现在根据这份数据,我们将其他客户分类并针对潜在客户投放广告。
首先,我们来看一下数据集。
该数据集总共有400条观测,5个字段:
User ID:客户ID;
Gender:性别;
Age:年龄;
EstimatedSalary:估计年薪;
Purchased:客户是否购买产品;
User ID是按序生成的,对我们的K-NN算法没影响,我们先对数据进行预处理。后面再剔除这个变量
在
logistic回归模型
中,我们将因子型的变量转换为哑变量,我们在这里也用相同的方法处理。在后面使用的K-NN算法,需要响应变量为因子型,这里预先处理了。最后,我们将Age、EstimatedSalary和Male变量进行标准化转换。因为我们发现这几个变量的数量级不在同一水平上,进行标准化后,可以消除量纲的影响。
图:预处理后的数据集
预处理后,我们将数据集分成训练集和测试集。
我们将数据集按80%和20%分成训练集和测试集。使用dplyr包中sample_frac()函数。
我们知道K-NN是消极学习方法,只在需要预测时才进行建模,所以我们在这里就不需要建模。使用class包中的knn()函数来预测测试集。
knn()函数使用欧氏距离来计算距离,参数使用说明:
train:训练集;
test:测试集;
cl:训练集对应的分类结果;
k:最近邻个数;
prob:是否显示概率值;
接下来,我们看一下混淆矩阵。
准确率达到了95%,非常高的准确率,效果不错。
尝试将改变K值,看看准确率如何变化。
从准确率来看,k = 10或者k = 11时,准确率是最高的。当然,除了k =1外,其他k值的准确率都达到90%以上,所以选择哪个K值,完全取决于你。k的选择,有人用Cross Validation,有人用贝叶斯,还有的用bootstrap,更多的时候,靠经(xia)验(meng)。
总结
了解了K-NN算法的基本知识,K-NN算法的优缺点,选择K值的重要性。接着我们使用R语言实现了K-NN算法,介绍了class包中knn()函数的用法,预测了测试集的类别并计算出准确率,最后我们计算了不同K值下的准确率。
参考:
从K近邻算法、距离度量谈到KD树、SIFT+BBF算法:
http://blog.csdn.net/v_july_v/article/details/8203674#comments
R语言与机器学习学习笔记(分类算法)(1)K-近邻算法:
KNN算法及R语言实现:
扫一扫,关注我的个人公众号:DataTurtle,获取源码,更有各种数据分析视频免费获取。
领取专属 10元无门槛券
私享最新 技术干货