k近邻算法 c语言,k近邻算法(knn)的c语言实现

c4468b3f4df77e96b0a416fa2a870fba.png

最近在看knn算法,顺便敲敲代码。

knn属于数据挖掘的分类算法。基本思想是在距离空间里,如果一个样本的最接近的k个邻居里,绝大多数属于某个类别,则该样本也属于这个类别。俗话叫,“随大流”。

简单来说,KNN可以看成:有那么一堆你已经知道分类的数据,然后当一个新的数据进入的时候,就开始跟训练里的每个点求距离,然后挑出离这个数据最近的K个点,看看这K个点属于什么类型,然后用少数服从多数的原则,给新数据归类。

该算法的示意图,简单明了:

296f4635c008d04efb2d9212c65fc2d5.png

下面的算法步骤取自于百度文库(文库是一个好东西),代码是参照这个思路实现的:

467b2617ef976762a317d1f31897968c.png

code:

1 #include

2 #include

3 #include

4

5 #define K 3 //近邻数k

6 typedef floattype;7

8 //动态创建二维数组

9 type **createarray(int n,intm)10 {11 inti;12 type **array;13 array=(type **)malloc(n*sizeof(type *));14 array[0]=(type *)malloc(n*m*sizeof(type));15 for(i=1;i

19 void loaddata(int *n,int *d,type ***array,type ***karray)20 {21 inti,j;22 FILE *fp;23 if((fp=fopen("data.txt","r"))==NULL) fprintf(stderr,"can not open data.txt!\n");24 if(fscanf(fp,"N=%d,D=%d",n,d)!=2) fprintf(stderr,"reading error!\n");25 *array=createarray(*n,*d);26 *karray=createarray(2,K);27

28 for(i=0;i

31

32 for(i=0;i<2;i++)33 for(j=0;j

35 if(fclose(fp)) fprintf(stderr,"can not close data.txt");36 }37 //计算欧氏距离

38 type computedistance(int n,type *avector,type *bvector)39 {40 inti;41 type dist=0.0;42 for(i=0;i

47 void bublesort(int n,type **a,intchoice)48 {49 inti,j;50 type k;51 for(j=0;ja[0][i+1]){55 k=a[0][i];56 a[0][i]=a[0][i+1];57 a[0][i+1]=k;58 k=a[1][i];59 a[1][i]=a[1][i+1];60 a[1][i+1]=k;61 }62 }63 else if(1==choice){64 if(a[1][i]>a[1][i+1]){65 k=a[0][i];66 a[0][i]=a[0][i+1];67 a[0][i+1]=k;68 k=a[1][i];69 a[1][i]=a[1][i+1];70 a[1][i+1]=k;71 }72 }73 }74 }75 //统计有序表中的元素个数

76 type orderedlist(int n,type *list)77 {78 int i,count=1,maxcount=1;79 type value;80 for(i=0;i

83 if(count>maxcount){84 maxcount=count;85 value=list[i];86 count=1;87 }88 }89 else

90 count++;91 }92 if(count>maxcount){93 maxcount=count;94 value=list[n-1];95 }96 //printf("value %f has a Maxcount:%d\n",value,maxcount);

97 returnvalue;98 }99

100 intmain()101 {102 inti,j,k;103 int D,N; //维度,数据量

104 type **array=NULL; //数据数组

105 type **karray=NULL; //K近邻点的距离及其标签

106 type *testdata; //测试数据

107 type dist,maxdist;108

109 loaddata(&N,&D,&array,&karray);110 testdata=(type *)malloc((D-1)*sizeof(type));111 printf("input test data containing %d numbers:\n",D-1);112 for(i=0;i

114 while(1){115 for(i=0;iN) exit(-1);117 karray[0][i]=computedistance(D-1,testdata,array[i]);118 karray[1][i]=array[i][D-1];119 //printf("first karray:%6.2f %6.0f\n",karray[0][i],karray[1][i]);

120 }121

122 bublesort(K,karray,0);123 //for(i=0;i

124 maxdist=karray[0][K-1]; //初始化k近邻数组的距离最大值

125

126 for(i=K;ij;k--){ //j后元素复制到后一位,为插入做准备

132 karray[0][k]=karray[0][k-1];133 karray[1][k]=karray[1][k-1];134 }135 karray[0][j]=dist; //插入到j位置

136 karray[1][j]=array[i][D-1];137 //printf("i:%d karray:%6.2f %6.0f\n",i,karray[0][j],karray[1][j]);

138 break; //不比较karray后续元素

139 }140 }141 maxdist=karray[0][K-1];142 //printf("i:%d maxdist:%6.2f\n",i,maxdist);

143 }144 //for(i=0;i

145 bublesort(K,karray,1);146 //for(i=0;i

147 printf("\nThe data has a tag: %.0f\n\n",orderedlist(K,karray[1]));148

149 printf("input test data containing %d numbers:\n",D-1);150 for(i=0;i

实验:

训练数据data.txt:

N=6,D=9

1.0 1.1 1.2 2.1 0.3 2.3 1.4 0.5 1

1.7 1.2 1.4 2.0 0.2 2.5 1.2 0.8 1

1.2 1.8 1.6 2.5 0.1 2.2 1.8 0.2 1

1.9 2.1 6.2 1.1 0.9 3.3 2.4 5.5 0

1.0 0.8 1.6 2.1 0.2 2.3 1.6 0.5 1

1.6 2.1 5.2 1.1 0.8 3.6 2.4 4.5 0

预测数据:

1.0 1.1 1.2 2.1 0.3 2.3 1.4 0.5

1.7 1.2 1.4 2.0 0.2 2.5 1.2 0.8

1.2 1.8 1.6 2.5 0.1 2.2 1.8 0.2

1.9 2.1 6.2 1.1 0.9 3.3 2.4 5.5

1.0 0.8 1.6 2.1 0.2 2.3 1.6 0.5

1.6 2.1 5.2 1.1 0.8 3.6 2.4 4.5

程序测试的结果:

1.0 1.1 1.2 2.1 0.3 2.3 1.4 0.5 类别为: 1

1.7 1.2 1.4 2.0 0.2 2.5 1.2 0.8 类别为: 1

1.2 1.8 1.6 2.5 0.1 2.2 1.8 0.2 类别为: 1

1.9 2.1 6.2 1.1 0.9 3.3 2.4 5.5 类别为: 0

1.0 0.8 1.6 2.1 0.2 2.3 1.6 0.5 类别为: 1

1.6 2.1 5.2 1.1 0.8 3.6 2.4 4.5 类别为: 0

实验截图:

6bc6d0571bed0ae280fb2fdb02614641.png

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值