前言
提示:KNN效果其实很拉。
提示:以下是本篇文章正文内容,下面案例可供参考
一、KNN原理
如果说这个世界上有最简单的分类方法,那么毫无疑问就算KNN了。物以类聚,人以群分,KNN的精髓一句话概括,对任何一个样本,找出K个相似的样本进行投票决定新样本类别。
那么相似怎么判断?就引入了距离度量和相似度度量:距离度量说人话就算欧几里得距离,再说人话就算,算了没啥好说的了,两个数据之间如何求欧几里得距离这个我就不教了吧。相似度度量就算余弦相似度和皮尔逊相似度这些,大同小异。但是它们有不同的计算场景,一个算法要有好的效果,必须要理解背后的原理以及数据中的内含意义。
①在给电影人群喜好分类的时候,更加应该注重方向感,应该选用相似度度量。
②在衡量一个人身高体重一作人群分类时,更应该注重距离感。
其他需要注意的地方:
1. K值设置:作为唯一的超参数,大多数情况直接设为1就好了,这个时候就变成了1NN,对于每个测试样本,哪个训练样本更近,那么就和它是同一类别。
①K最好设为单数吧,不然二分类投票票数可能相等,然后if结构会反复讲相等的票数判为同一类别,造成算法出问题。
②K值越大,能够找的近邻数更多,能够获取的信息增加了,但是误差信息也随之增加了。
2. 样本不平衡的数据慎用,数据多的内别会欺负数据少的类别。
3. 改进方案:如果两个类别票数相等,其实可以通过计算距离和再来比一次,距离更近的票当然更重要,不过已经把K设成了奇数不会有这种情况了。
4. 改进方案:为每个特征值增加一个权重W,这个权重需要自己求解。需了解一下Weighted KNN。
二、源码
1.matlab
代码如下(示例):还剩一个for循环撸不掉了,这个for循环是对每个测试样本进行计算的过程。
%% MAT_WeightKNN
function predictarray = MAT_WeightedKNN(traindata,testdata,trainlable,testlable)
K = evalin('base','gK');
[r1,~] = size(traindata);
[r2,~] = size(testdata);
% weight = ones(1,c1) / c1;
% fprintf('KNN-traindata size is equal to %d*%d,testdata size is equal to %d*%d\n',r1,c1,r2,c2);
predictarray = zeros(r2,1);%预测结果数字
%%下面开始KNN算法
for i = 1:r2
%为每个一个测试数据计算一个数组-该数组描述的是该测试数据到所有训练数据的距离
%求测试数据和训练数据的所有维度的距离,欧式距离(或马氏距离)
par_trainlable = trainlable;
MAT_CUT = ones(r1,1)*testdata(i,:)-traindata;
MAT_distance = sqrt(sum(MAT_CUT.*MAT_CUT,2));
MAT_distance = [MAT_distance,(1:r1)'];
MAT_distance = sortrows(MAT_distance,1);
neighborflag = MAT_distance(1:K,2);
neighborlabel = par_trainlable(neighborflag',:);
%% K个近邻在每个类别中距离最小
maxlabelname = mode(neighborlabel);
predictarray(i,1) = maxlabelname;
end
end
总结
今天KNN分享就到这啦。