最近邻与K近邻的matlab实现最近邻与K近邻算法实验报告——matlab实现班级:02105051学号:02105058姓名:张俊飞时间:2012年11月27日最近邻与K近邻的matlab实现1最近邻与k近邻算法的编程实现一、对iris数据的最近邻与k近邻1、程序代码%对iris数据进行模式分类,其中定义有K,当K=1是即为最近邻法,%当K为部位1的奇数时,即为k近邻法。load('c:\iris.txt');%将数据保存在C盘下。forq=1:10%十次随机,有randperm指令disp(sprintf('\n第%d次判定',q));A1=randperm(50);%对第一类样本做随机a11=A1(1,1:25);a21=A1(1,26:50);%fori=1:25sample1=zeros(1,25);sample1=iris(a11,:);%第一类随机取25个做训练样本,剩余作测试样本test1=iris(a21,:);%endA2=randperm(50);%对第二类样本做随机b=A2+50;a12=b(1,1:25);a22=b(1,26:50);fori=1:25sample2(i,:)=iris(a12(1,i),:);test2(i,:)=iris(a22(1,i),:);%第二类随机取25个做训练样本,剩余作测试%样本endA3=randperm(50);%对第三类样本做随机c=A3+100;a13=c(1,1:25);a23=c(1,26:50);fori=1:25sample3(i,:)=iris(a13(1,i),:);test3(i,:)=iris(a23(1,i),:);End%第三类随机取25个做训练样本,剩余作测试样本train=cat(1,sample1,sample2,sample3);test=cat(1,test1,test2,test3);%此处为止,随机取得训练样本与测试样本存于train和test中。k=11;%说明近邻方式,当K=1时为最近邻,K为其他数时为相应的k近邻,为%避免程序出现二义性此处K取奇数。decimal=zeros(1,75);category1=0;category2=0;category3=0;sum=0;%统计每个类分类正确的个数,%sum是总的正确的个数。最近邻与K近邻的matlab实现2forx=1:75fory=1:75distance=((test(x,1)-train(y,1))^2+(test(x,2)-train(y,2))^2+(test(x,3)-train(y,3))^2+(test(x,4)-train(y,4))^2);decimal(1,y)=distance;%求欧氏距离的平方并保存end[z,local]=sort(decimal);%调用sort函数进行排序,local中存它们原来的%位置num1=0;num2=0;num3=0;%三个临时变量存取个数forn=1:k%找距离最近的k个值。iflocal(1,n)=25%若在前25个测验样本内的个%数多,相应的num1加1.num1=num1+1;elseiflocal(1,n)25&&local(1,n)=50%若在中间25个样本内,即%第二类num2=num2+1;elsenum3=num3+1;%即第三类endendifnum1num2&&num1num3m=1;elseifnum2=num1&&num2=num3m=2;elsem=3;end%下面代码是为了统计正确率ifx=25&&m==1%第一类分类正确category1=category1+1;elseifx=50&&x=26&&m==2%第二类分类正确category2=category2+1;elseifx50&&x=75&&m==3category3=category3+1;%第三类分类正确endif(x=25&&m==1)||(x25&&x=50&&m==2)||(x50&&x=75&&m==3)sum=sum+1;%分类正确的总个数endtestoutput(x,1:5)=test(x,1:5);%将每次的识别样本存于矩阵%中,便于直观比较每个样本的分类。testoutput(x,6)=m;enddisp(sprintf('第一类的识别率为%f',category1/25));%输出设置最近邻与K近邻的matlab实现3disp(sprintf('第二类的识别率为%f',category2/25));disp(sprintf('第三类的识别率为%f',category3/25));disp(sprintf('总的识别率为%f',sum/75));Testoutput%每次都输出判定的样本用以比较End2、结果统计iris的识别率统计1——最近邻(k=1)第一次第二次第三次第四次第五次第六次第七次第八次第九次第十次第一类1.001.001.001.001.001.001.001.001.001.00第二类0.960.960.960.920.960.960.920.920.921.00第三类1.000.880.920.920.920.960.960.920.960.92平均0.9870.9470.9600.9470.9600.9730.9600.9470.9600.973总平均0.9614iris的识别率统计2——11近邻(k=11)第一次第二次第三次第四次第五次第六次第七次第八次第九次第十次第一类1.001.001.001.001.001.001.001.001.001.00第二类0.920.960.960.920.960.960.921.000.920.88第三类0.960.960.960.881.001.001.000.880.960.92平均0.960.9730.9730.9330.9870.9870.9730.960.9600.933总平均0.96393、实验结果分析由数据统计,可见该算法对第一类样本的识别率极高,无论是最近邻还是11近邻。分析样本数据可知,第一类样本的第三维特征与第四维特征与第二类样本和第三类样本有着明显的差别。同时,通过统计数据,不难发现总平均识别率也是相当高的,这是因为三类样本的特征维数较低,而且相应的分界较为明显。二、对wine数据的最近邻与k近邻最近邻与K近邻的matlab实现41、程序代码%最近邻与K近邻实现对wine数据的分类%每行注释基本与iris程序一致,不做赘述。load('c:\wine.txt');forp=1:10disp(sprintf('\n第%d次判定',p));A1=randperm(59);%产生随机排列。a11=A1(1,1:30);a21=A1(1,31:59);%fori=1:25sample1=zeros(1,30);sample1=wine(a11,:);test1=zeros(1,29);test1=wine(a21,:);%end%第一类随机取30个做训练样本,剩余29作测试样本A2=randperm(71);b=A2+59;a12=b(1,1:35);a22=b(1,36:71);sample2=zeros(1,35);sample2=wine(a12,:);test2=zeros(1,36);test2=wine(a22,:);%第二类随机取35个做训练样本,剩余36个作测试样本A3=randperm(48);c=A3+130;a13=c(1,1:24);a23=c(1,25:48);sample3=zeros(1,24);sample3=wine(a13,:);test3=zeros(1,24);test3=wine(a23,:);%第一类随机取24个做训练样本,剩余24个作测试样本train_sample=cat(1,sample1,sample2,sample3);test=cat(1,test1,test2,test3);k=1;%说明近邻方式decimal=zeros(1,89);sunum1=0;sunum2=0;sunum3=0;sum=0;forx=1:89fory=1:89result=0;forq=2:14%求欧氏距离result=result+(test(x,q)-train_sample(y,q))^2;end最近邻与K近邻的matlab实现5decimal(1,y)=result;end[z,ind]=sort(decimal);num1=0;num2=0;num3=0;forn=1:kifind(1,n)=29num1=num1+1;elseifind(1,n)=30&&ind(1,n)=65num2=num2+1;elsenum3=num3+1;endendifnum1num2&&num1num3m=1;elseifnum2=num1&&num2num3m=2;elsem=3;endoutputtest(x,1)=test(x,1);outputtest(x,2)=m;outputtest(x,3:15)=test(x,2:14);%disp(sprintf('第%d个样本判定为%d类',x,m));ifx=29&&m==1sunum1=sunum1+1;elseifx=65&&x=31&&m==2sunum2=sunum2+1;elseifx65&&x=89&&m==3sunum3=sunum3+1;endif(x=29&&m==1)||(x29&&x=65&&m==2)||(x65&&x=89&&m==3)sum=sum+1;endenddisp(sprintf('第一类的识别率为%f',sunum1/29));disp(sprintf('第二类的识别率为%f',sunum2/36));disp(sprintf('第三类的识别率为%f',sunum3/24));disp(sprintf('总的识别率为%f',sum/89));Outputtest%将判定的测验样本放入outputtest矩阵中,易于直观分析end2、结果统计最近邻与K近邻的matlab实现6wine的识别统计1--最近邻(K=1)第一次第二次第三次第四次第五次第六次第七次第八次第九次第十次第一类0.8280.8620.9310.8970.7240.8620.8280.8620.8620.828第二类0.6940.6670.6390.6940.750.6670.6670.6670.6390.639第三类0.5420.5420.5420.6250.5830.50.6250.8330.50.5平均0.6970.7080.7190.7420.7080.6970.7190.7750.6740.674总平均0.7113wine的识别统计2--11近邻(K=11)第一次第二次第三次第四次第五次第六次第七次第八次第九次第十次第一类0.8970.8280.8280.9660.82810.8280.7590.9310.966第二类0.6670.4720.7220.5280.50.5280.750.6390.5830.639第三类0.5830.8330.4580.4580.750.7080.50.6250.7080.5平均0.7190.6970.6970.6970.6850.730.7190.6740.730.719总平均0.70673、实验结果分析由于第一类样本的第十四维特征明显与二、三类样本有较大差别,故第一类样本的识别率相对高于二、三类。第二类样本与第三类样本的各维特征的分界不是很明显,故这两类的识别率低于第一类的识别率。由于样本的维数很高,加之第十四维特征在欧氏距离中占得比重较大,故出错率也就很高,所以总平均识别率无论是在最近邻还是11近邻算法中都是不太理想。三、存在问题及实验收获最近邻与K近邻的matlab实现7存在问题:刚开始时打用C语言做,写