k最近邻算法实验报告Word格式.docx
《k最近邻算法实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《k最近邻算法实验报告Word格式.docx(10页珍藏版)》请在冰豆网上搜索。
另外,由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
该方法的不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。
目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。
该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
1、算法思路
K-最临近分类方法存放所有的训练样本,在接受待分类的新样本之前不需构造模型,并且直到新的(未标记的)样本需要分类时才建立分类。
K-最临近分类基于类比学习,其训练样本由N维数值属性描述,每个样本代表N维空间的一个点。
这样,所有训练样本都存放在N维模式空间中。
给定一个未知样本,k-最临近分类法搜索模式空间,找出最接近未知样本的K个训练样本。
这K个训练样本是未知样本的K个“近邻”。
“临近性”又称为相异度(Dissimilarity),由欧几里德距离定义,其中两个点X(x1,x2,…,xn)和Y(y1,y2,…,yn)的欧几里德距离是:
未知样本被分配到K个最临近者中最公共的类。
在最简单的情况下,也就是当K=1时,未知样本被指定到模式空间中与之最临近的训练样本的类。
2、算法步骤
step.1---初始化距离为最大值;
step.2---计算未知样本和每个训练样本的距离dist;
step.3---得到目前K个最临近样本中的最大距离maxdist;
step.4---如果dist小于maxdist,则将该训练样本作为K-最近邻样本;
step.5---重复步骤2、3、4,直到未知样本和所有训练样本的距离都算完;
step.6---统计K-最近邻样本中每个类标号出现的次数;
step.7---选择出现频率最大的类标号作为未知样本的类标号。
3、算法伪代码
搜索k个近邻的算法:
kNN(A[n],k)
输入:
A[n]为N个训练样本在空间中的坐标(通过文件输入),k为近邻数
输出:
x所属的类别
取A[1]~A[k]作为x的初始近邻,计算与测试样本x间的欧式距离d(x,A[i]),i=1,2,.....,k;
按d(x,A[i])升序排序,计算最远样本与x间的距离D<
-----max{d(x,a[j])|j=1,2,.....,k};
for(i=k+1;
i<
=n;
i++)
计算a[i]与x间的距离d(x,A[i]);
if(d(x,A[i]))<
D
then用A[i]代替最远样本
按照d(x,A[i])升序排序,计算最远样本与x间的距离D<
---max{d(x,A[j])|j=1,...,i};
计算前k个样本A[i]),i=1,2,...,k所属类别的概率,具有最大概率的类别即为样本x的类。
五、数据结构
代码结构如图所示,方法描述如下:
KNN:
KNN类构造函数,用于读取数据集;
get_all_distance:
KNN类公有函数,计算要分类的点到所有点的距离;
get_distance:
KNN类私有函数,计算两点间的距离;
get_max_freq_label:
KNN类公有函数,在k个数据里,获取最近k个数据的分类最多的标签,将测试数据归位该类。
类图如上图所示,KNN类的成员变量描述如下:
dataSet:
tData型二维数组,用于训练的数据集;
k:
int型,从k个最近的元素中,找类标号对应的数目的最大值,归类;
labels:
tLable型一维数组,类标签;
map_index_dist:
map<
int,double>
型,记录测试点到各点的距离;
map_label_freq:
tLable,int>
型,记录k个邻居类,各类的个数。
六、程序截图
七、实验总结
八、附件
1.程序源码kNN1.cpp
#include<
iostream>
map>
vector>
algorithm>
fstream>
usingnamespacestd;
typedefchartLabel;
typedefdoubletData;
typedefpair<
PAIR;
constintcolLen=2;
constintrowLen=10;
ifstreamfin;
classKNN
{
private:
tDatadataSet[rowLen][colLen];
tLabellabels[rowLen];
intk;
map<
map_index_dis;
tLabel,int>
map_label_freq;
doubleget_distance(tData*d1,tData*d2);
public:
KNN(intk);
voidget_all_distance(tData*testData);
voidget_max_freq_label();
structCmpByValue
{
booloperator()(constPAIR&
lhs,constPAIR&
rhs)
{
returnlhs.second<
rhs.second;
}
};
};
KNN:
:
KNN(intk)
this->
k=k;
fin.open("
data.txt"
);
if(!
fin)
{
cout<
<
"
cannotopenthefiledata.txt"
endl;
exit
(1);
}
/*inputthedataSet*/
for(inti=0;
rowLen;
for(intj=0;
j<
colLen;
j++)
fin>
>
dataSet[i][j];
}
fin>
labels[i];
}
}
/*
*calculatethedistancebetweentestdataanddataSet[i]
*/
doubleKNN:
get_distance(tData*d1,tData*d2)
doublesum=0;
sum+=pow((d1[i]-d2[i]),2);
//cout<
thesumis="
sum<
returnsqrt(sum);
*calculateallthedistancebetweentestdataandeachtrainingdata
voidKNN:
get_all_distance(tData*testData)
doubledistance;
inti;
for(i=0;
distance=get_distance(dataSet[i],testData);
//<
key,value>
=>
<
i,distance>
map_index_dis[i]=distance;
//traversethemaptoprinttheindexanddistance
map<
const_iteratorit=map_index_dis.begin();
while(it!
=map_index_dis.end())
index="
it->
first<
distance="
second<
it++;
*checkwhichlabelthetestdatabelongstotoclassifythetestdata
get_max_freq_label()
//transformthemap_index_distovec_index_dis
vector<
PAIR>
vec_index_dis(map_index_dis.begin(),map_index_dis.end());
//sortthevec_index_disbydistancefromlowtohightogetthenearestdata
sort(vec_index_dis.begin(),vec_index_dis.end(),CmpByValue());
k;
theindex="
vec_index_dis[i].first<
thedistance="
vec_index_dis[i].second<
thelabel="
labels[vec_index_dis[i].first]<
thecoordinate("
dataSet[vec_index_dis[i].first][0]<
"
dataSet[vec_index_dis[i].first][1]<
)"
//calculatethecountofeachlabel
map_label_freq[labels[vec_index_dis[i].first]]++;
const_iteratormap_it=map_label_freq.begin();
tLabellabel;
intmax_freq=0;
//findthemostfrequentlabel
while(map_it!
=map_label_freq.end())
if(map_it->
second>
max_freq)
max_freq=map_it->
second;
label=map_it->
first;
map_it++;
cout<
Thetestdatabelongstothe"
label<
label"
intmain()
tDatatestData[colLen];
intk;
pleaseinputthekvalue:
"
cin>
KNNknn(k);
pleaseinputthetestdata:
cin>
testData[i];
knn.get_all_distance(testData);
knn.get_max_freq_label();
system("
pause"
return0;
2.数据集data.txt