matlab用svm实现分类_教程 | matlab实现KNN分类

25da7b49f9da038f12f516eeebe1100d.gif

KNN基本思路

KNN学习(K-Nearest Neighbor algorithm,K最邻近方法 )是一种非常简单的分类器,其基本思想是:输入没有标签(标注数据的类别),即没有经过分类的新数据,首先提取新数据的特征并与测试集中的每一个数据特征进行比较;然后从测试集中提取K个最邻近(最相似)的数据样本标签,统计这K个最邻近数据中出现次数最多的分类,将其作为新的数据类别。KNN的这种基本思想有点类似于生活中的“物以类聚,人以群分”。

KNN分类器K的大小选择

我们都知道,当K=1时,其抗干扰能力就较差,因为假如样本中出现了某种偶然的类别,那么新的数据很有可能被分错。为了增加分类的可靠性,可以考察待测数据的K个最近邻样本 ,统计这K个近邻样本中属于哪一类别的样本最多,就将样本判属于该类。但是存在另外一个极端,当K等于训练样本总数时,分类结果完全取决于训练数据中各类别数据的总数量,与待分类数据本身无关。因此,应选择合适大小的K值。

KNN分类器距离测度 当然,如果在样本有限的情况下,KNN算法的误判概率和距离的具体测度方法就有了直接关系。即用何种方式判定哪些数据与新数据近邻。不同的样本选择不同的距离测量函数,这能够提高分类的正确率。通常情况下,KNN可以采用Euclidean(欧几里得)、Manhattan(曼哈顿)、Mahalanobis(马氏距离)等距离用于计算。

KNN分类方法中数据的标准化

在开始实现算法之前,我们要考虑一个问题,不同特征的特征值范围可能有很大的差别,例如,使用身高和体重两维数据判断一个人的性别时,若身高以米为单位,而体重以千克为单位,那么当选择欧几里得距离作为距离测度时,体重这一维数据就会对距离大小产生压倒性的影响。这对性别分类是很不利的。此时,我们需要将数据标准化(normalize),把每一个特征值除以该特征的范围,保证标准化后每一个特征值都在0~1之间。

各类标签的训练样本数量不均衡对KNN分类器的影响

若某些类别的样本容量很大,而其他类样本容量很小,即已知的样本数量不均衡,有可能当输入一个和小容量类相同的的新样本时,该样本的K个近邻中,大容量类的样本占多数,从而导致误分类。针对此种情况可以采用加权的方法,即和该样本距离小的近邻所对应的权值越大,将权值纳入分类的参考依据。

为了方便学习KNN,我们实现了一个简单的版本,内置欧几里得距离、汉明距离、余弦距离三类距离测度。详细注释版代码如下:

function predictclass=myknn(traindata,trainclass,testdata,disFun,K)% K近邻方法分类% % INPUTS:% traindata:已知类别的训练数据,每一行代表一个样本,每一列代表一项特征% trainclass:训练数据的类别标签% testdata:待分类数据% disFun:距离函数% K: 近邻个数% OUTPUT:% predictclass:使用k近邻方法预测的样本类别% 公众号【数学建模公会】HCLO4原创,20191013% 首先对训练数据和待分类数据按列标准化(使特征之间不受量纲影响)numtrainsample=size(traindata,1);numtestsample=size(testdata,1);alldata=[traindata;testdata];alldata=(alldata-repmat(min(alldata),size(alldata,1),1))./repmat(max(alldata)-min(alldata),size(alldata,1),1);% 标准化后的数据traindata=alldata(1:numtrainsample,:);testdata=alldata(numtrainsample+1:end,:);% 计算待测试样本和训练样本之间的距离,并分类dis=caldis(traindata,testdata,disFun);predictclass=zeros(numtestsample,1);for i=1:numtestsample    tempdata=[dis(:,i),trainclass];    sortdata=sortrows(tempdata,1);  % 按照tempdata第一列,也就是距离排序    knearclass=sortdata(1:K,2);    frq=tabulate(knearclass);    predictclass(i)=frq(end,1); % 注意K近邻中有可能出现多个class频数一样的情况endendfunction dis=caldis(traindata,testdata,disFun)numtrainsample=size(traindata,1);numtestsample=size(testdata,1);dis=zeros(numtrainsample,numtestsample);switch disFun    case 'euclidean'        for i=1:numtrainsample            for j=1:numtestsample                sample1=traindata(i,:);                sample2=testdata(j,:);                             dis(i,j)=sqrt(sum((sample1-sample2).^2));            end        end            case 'hamming'        for i=1:numtrainsample            for j=1:numtestsample                sample1=traindata(i,:);                sample2=testdata(j,:);                             dis(i,j)=mean(sample1~=sample2);            end        end            case 'cosin'        for i=1:numtrainsample            for j=1:numtestsample                sample1=traindata(i,:);                sample2=testdata(j,:);                             dis(i,j)=mean(sample1~=sample2);                dis(i,j)=sample1*sample2'/(sqrt(sum(sample1.^2))*sqrt(sum(sample2.^2)));            end        end        endend
以下代码为测试my knn的代码:
%%%%%%%%%%%%%%%%%%%%%%%%% 随机生成训练数据和测试数据  %%%%%%%%%%%%%%%%%%%%% 第一类数据,二维正态分布,第一维均值为3,标准差为1;第二维均值维6,标准差为1meanval1=[3,6];stdval1=[1,1];% 第一类数据,二维正态分布,第一维均值为8,标准差为1;第二维均值维4,标准差为1meanval2=[8,4];stdval2=[1,1];% 产生第一类数据的训练数据traindata1=[normrnd(meanval1(1),stdval1(1),100,1),normrnd(meanval1(2),stdval1(2),100,1)];% 产生第二类数据的训练数据traindata2=[normrnd(meanval2(1),stdval2(1),100,1),normrnd(meanval2(2),stdval2(2),100,1)];% 合并两类训练数据traindata=[traindata1;traindata2]; % 前一百个是一类,后一百个是一类% 训练数据的标签trainclass=[ones(100,1);2*ones(100,1)];% 产生第一类待测数据testdata1=[normrnd(meanval1(1),stdval1(1),100,1),normrnd(meanval1(2),stdval1(2),100,1)]; % 实际标签为第一类% 产生第二类待测数据testdata2=[normrnd(meanval2(1),stdval2(1),100,1),normrnd(meanval2(2),stdval2(2),100,1)]; % 实际标签为第二类%%%%%%%%%%%%%%%%%%%%%%%%% 使用myknn进行分类  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 使用KNN进行分类predictclass1=myknn(traindata,trainclass,testdata1,'euclidean',5);predictclass2=myknn(traindata,trainclass,testdata2,'euclidean',5);%%%%%%%%%%%%%%%%%%%%%%%%%%%  统计分类准确率  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 统计分类正确率% 第一类分类准确率disp(mean(predictclass1==1))% 第二类分类准确率disp(mean(predictclass2==2))

撰文:HCLO4

编辑:花毛

校对:VickieQ

e4156bf4d1d1c8ba53fce11b0432acbc.png

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页