KNN (K-最近邻分类)算法源代码 模式识别
模式识别P86
K-近邻法是最近邻法的推广
using namespace std;
#include <iostream>
#include <cmath>
#include <fstream>
#define NATTRS 5 //属性数
#define MAXSZ 1700 //训练集的最大尺寸
#define MAXVALUE 10000.0 //最大属性10000
#define K 5 //定义最邻近值
struct vector {
double attributes[NATTRS];
double classlabel;
};
struct item {
double distance;
double classlabel;
};
struct vector trSet[MAXSZ];//全局变量。训练集
struct item knn[K];//全局变量。K-最邻近集合
int curTSize = 0; //当前训练集的尺寸
int AddtoTSet(struct vector v)
{
if(curTSize>=MAXSZ)
{
cout<<endl<<"The training set has "<<MAXSZ<<" examples!"<<endl<<endl;
return 0;
}
trSet[curTSize] = v;
curTSize++;
return 1;
}
double Distance(struct vector v1,struct vector v2)
{
double d = 0.0;
double tem = 0.0;
for(int i = 0;i < NATTRS;i++)
tem += (v1.attributes[i]-v2.attributes[i])*(v1.attributes[i]-v2.attributes[i]);
d = sqrt(tem);
return d;
}
int max(struct item knn[]) //返回值为项目间的最大距离
{
int maxNo = 0;
if(K > 1)
for(int i = 1;i < K;i++)
if(knn[i].distance>knn[maxNo].distance)
maxNo = i;
return maxNo;
}
double Classify(struct vector v)//决定分到哪一类中
{
double dd = 0;
int maxn = 0;
int freq[K];
double mfreqC = 0;//分类出现次数
int i;
for(i = 0;i < K;i++)
knn[i].distance = MAXVALUE;
for(i = 0;i < curTSize;i++)
{
dd = Distance(trSet[i],v);
maxn = max(knn);//为新加数据更新训练集
if(dd < knn[maxn].distance)
{
knn[maxn].distance = dd;
knn[maxn].classlabel = trSet[i].classlabel;
}
}
for(i = 0;i < K;i++)//freq[i]显示knn[i].classlabel出现的次数
freq[i] = 1;
for(i = 0;i < K;i++)
for(int j = 0;j < K;j++)
if((i!=j)&&(knn[i].classlabel == knn[j].classlabel))
freq[i]+=1;
for(i=0;i<K;i++)
cout<<"freq:"<<freq[i]<<endl;
int mfreq = 1;
mfreqC = knn[0].classlabel;
for(i = 0;i < K;i++)
if(freq[i] > mfreq)
{
mfreq = freq[i];//分类出现最大次数
mfreqC = knn[i].classlabel;
}
return mfreqC;
}
int main(){
double classlabel;
double c;
double n;
struct vector trExmp;
int i;
ifstream filein("C:\\Users\\慰\\Documents\\大学\\大三上\\模式识别\\K近邻\\data.txt");
if(filein.fail()) { cout<<"Can't open data.txt"<<endl; //return;
}
while(!filein.eof())
{
filein>>c;
trExmp.classlabel = c;
cout<<"label:"<<trExmp.classlabel<<"|";
for(int i = 0;i < NATTRS;i++)
{
filein>>n;
trExmp.attributes[i] = n;
cout<<trExmp.attributes[i]<<" ";
}
cout<<endl;
if(!AddtoTSet(trExmp))
break;
}
filein.close();
struct vector testv={{1,18,11,11,0.5513196},17};
classlabel = Classify(testv);
cout<<"the classlable of the testv is:";
cout<<classlabel<<endl;
for(i = 0;i < K;i++)
cout<<knn[i].distance<<"\t"<<knn[i].classlabel<<endl;
}
截图

data.txt
0 1 1 1 1 1
0 2 2 2 2 2
0 3 3 3 3 3
1 4 4 4 4 4
1 5 5 5 5 5
1 6 6 6 6 6
2 7 7 7 7 7
2 8 8 8 8 8
2 9 9 9 9 9
3 10 10 10 10 10
3 11 11 11 11 11
3 12 12 12 12 12
4 13 13 13 13 13
4 14 14 14 14 14
4 15 15 15 15 15
6 16 16 16 16 16
6 17 17 17 17 17
6 18 18 18 18 18
7 19 19 19 19 19
7 20 20 20 20 20
7 21 21 21 21 21
8 22 22 22 22 22
8 23 23 23 23 23
8 24 24 24 24 24
9 25 25 25 25 25
9 26 26 26 26 26
9 27 27 27 27 27
10 28 28 28 28 28
10 29 29 29 29 29
10 30 30 30 30 30