【原创】Liu_LongPo <http://blog.csdn.net/llp1992> 转载请注明出处 
【CSDN】http://blog.csdn.net/llp1992 <http://blog.csdn.net/llp1992>

参考https://blog.csdn.net/llp1992/article/details/45040685






         KNN
算法其实简单的说就是“物以类聚”,也就是将新的没有被分类的点分类为周围的点中大多数属于的类。它采用测量不同特征值之间的距离方法进行分类,思想很简单:如果一个样本的特征空间中最为临近(欧式距离进行判断)的K个点大都属于某一个类,那么该样本就属于这个类。这就是物以类聚的思想。

       
 当然,实际中,不同的K取值会影响到分类效果,并且在K个临近点的选择中,都不加意外的认为这K个点都是已经分类好的了,否则该算法也就失去了物以类聚的意义了。

<>KNN算法的不足点:


1、当样本不平衡时,比如一个类的样本容量很大,其他类的样本容量很小,输入一个样本的时候,K个临近值中大多数都是大样本容量的那个类,这时可能就会导致分类错误。改进方法是对K临近点进行加权,也就是距离近的点的权值大,距离远的点权值小。 
2、计算量较大,每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点,改进方法是:先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

<>适用性:

适用于样本容量比较大的类域的自动分类,而样本容量较小的类域则容易误分

<>算法描述:
1、计算已知类别数据集合汇总的点与当前点的距离 2、按照距离递增次序排序 3、选取与当前点距离最近的K个点 4、确定距离最近的前K个点所在类别的出现频率
5、返回距离最近的前K个点中频率最高的类别作为当前点的预测分类



Matlab 实现

这里以一个完整实例呈现,代码如下:
function relustLabel = KNN(inx,data,labels,k) %% % inx 为
输入测试数据,data为样本数据,labels为样本标签 %% [datarow , datacol] = size(data); diffMat =
repmat(inx,[datarow,1]) - data ; distanceMat = sqrt(sum(diffMat.^2,2)); [B , IX]
= sort(distanceMat,'ascend'); len = min(k,length(B)); relustLabel =
mode(labels(IX(1:len))); end
      实际调用中,我们利用一个数据集进行测试,该数据集是由1000个样本的3维坐标组成,共分为3个类

      首先可视化我们的数据集,看看它的分布:

      第一维和第二维:可以清晰地看到数据大致上分为 3 类



      第1维和第3维:从这个角度看,3类的分布就有点重叠了,这是因为我们的视角原因



       画出3维,看看它的庐山真面目:



     
 由于我们已经编写了KNN代码,接下来我们只需调用就行。了解过机器学习的人都应该知道,很多样本数据在代入算法之前都应该进行归一化,这里我们将数据归一化在[0,1]的区间内,归一化方式如下:

newData = (oldData-minValue)/(maxValue-minValue)

      其中,maxValue为oldData的最大值,minValue为 oldData 的最小值。

     
同时,我们对于1000个数据集,采取10%的数据进行测试,90%的数据进行训练的方式,由于本测试数据之间完全独立,可以随机抽取10%的数据作为测试数据,代码如下:
function KNNdatgingTest %% clc clear close all %% data = load(
'datingTestSet2.txt'); dataMat = data(:,1:3); labels = data(:,4); len = size
(dataMat,1); k = 4; error = 0; % 测试数据比例 Ratio = 0.1; numTest = Ratio * len; %
归一化处理 maxV = max(dataMat); minV = min(dataMat); range = maxV-minV; newdataMat =
(dataMat-repmat(minV,[len,1]))./(repmat(range,[len,1])); % 测试 for i = 1:numTest
classifyresult = KNN(newdataMat(i
,:),newdataMat(numTest:len,:),labels(numTest:len,:),k); fprintf('测试结果为:%d
真实结果为:%d\n',[classifyresult labels(i)]) if(classifyresult~=labels(i)) error =
error+1; end end fprintf('准确率为:%f\n',1-error/(numTest)) end
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31
当我们选择K为4的时候,准确率为:97%

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信