模式识别实习报告Word下载.docx
《模式识别实习报告Word下载.docx》由会员分享,可在线阅读,更多相关《模式识别实习报告Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
第八步:
计算聚类样本距离的标准差向量:
第九步:
求每一标准差向量{,σj=1,2,…,}中的最大分量,以{σj=1,2,…,}代表。
第十步:
在任一最大分量集{σj=1,2,…,}中,如有>
θS(该值给定),同时又满足以下二条件中之一:
(a),即Sj中样本总数超过规定值一倍以上,
(b)Nc≤K/2,
则将Zj分裂为两个新的聚类中心,且类别数加1。
中相当于的分量,可加上k*σjmax,其中k=0.5;
中相当于的分量,可减去k*σjmax。
如果本步完成了分裂运算,则跳回第二步;
否则,继续。
第十一步:
计算全部聚类中心的距离:
i=1,2,…,-1
j=i+1,…,
第十二步:
比较与θc值,将<
θc的值按最小距离次序递增排列,即
{,,…,}
式中,<
<
…<
。
第十三步:
如将距离为Di1j1的两个聚类中心zi1和zj1合并,得新中心为
l=1,2,…,L
式中,被合并的两个聚类中心向量,分别以其聚类域内的样本数加权,使为真正的平均向量。
第十四步:
如果是最后一次迭代运算(即第I次),算法结束。
否则GOTO第一步——如果需由操作者改变输入参数;
或GOTO第二步——如果输入参数不变。
实习程序
#include"
stdafx.h"
ISODATA.h"
Sort.h"
usingnamespacestd;
//classISODATA
externintN;
externintdim;
ISODATA:
:
ISODATA()
{
c=2;
//预期的类数;
Nc=1;
//初始聚类中心个数(可以不等于c);
theta_n=2;
//每一类中允许的最少模式数目(若少于此数,就不能单独成为一类);
theta_s=1;
//类内各分量分布的标准差上限(大于此数就分裂);
theta_D=4;
//两类中心间的最小距离下限(若小于此数,这两类应合并);
L=1;
//在每次迭代中可以合并的类的最多对数;
I=4;
//允许的最多迭代次数;
_d=100;
//总体平均距离
Ip=0;
//迭代次数
doubleD[MAXNUM][MAXNUM];
//各类对中心间的距离
for(inti=0;
i<
MAXNUM;
i++)
for(intj=0;
j<
j++)
D[i][j]=MAXDOUBLE;
}
~ISODATA()
//设置参数
intISODATA:
SetupPattern(Pattern*pattern)
N;
x[i]=pattern[i];
returnN;
//算法实现步骤
Process()
boolchanged=true;
//1.预置
//2)将待分类的模式特征矢量x1,x2,...,xn读入;
//SetupPattern();
//3)选定初始聚类中心,可从待分类的模式特征矢量集{xi}中任选Nc个模式特征矢量作为初始聚类中心zj(j=1,2,...,Nc).
InitCenter();
step1:
//1)设定聚类分析控制参数:
SetupParameter();
step2:
//2.按最小距离原则将模式集(xi)中每个模式分到某一类中
changed=false;
Clustering();
if(Ip==0)
cout<
<
endl<
"
-------------选取初始聚类中心---------------"
endl;
else
-------------第"
Ip<
次迭代-------------"
PrintSort();
step3:
//3.依据theta_n判断合并。
如果类wj中样本数nj<
theta_n,则取消该类的中心zj,Nc=Nc-1;
转至2.
if(CombinBytheta_n())
gotostep2;
step4:
//计算分类后的参数:
各类中心、类内平均距离及总体平均距离。
CalParameter();
step5:
//依据Ip,Nc判断停止\分裂或合并。
if(Ip==I)
{
theta_D=0;
gotostep9;
}
elseif(Nc<
=c/2)
gotostep6;
elseif(Nc>
=2*c)
elseif(Ip%2==1)//Nc>
c/2&
&
Nc<
2*c
step6:
//计算各类类内距离的标准差矢量
CalSigma();
step7:
//求出每一聚类类内距离标准差矢量sigma中的最大分量sigma_max
//CalMaxSigma();
//由于在Sort类中已进行计算,这里不做任何处理
step8:
//判断分裂
if(Split())
changed=true;
Ip++;
step9:
//计算各类对中心间的距离
CalCenterDis();
step10:
//依据theta_D判断合并
if(CombinBytheta_D())
step11:
//判断循环还是退出
if(Ip>
=I)
==========经过"
次迭代,达到迭代次数==========="
gotoover;
elseif(changed==false)
次迭代,算法收敛==========="
charch;
本次迭代完成,是否需要改变参数(Y/N)?
;
cin>
>
ch;
if(ch=='
y'
||ch=='
Y'
)
gotostep1;
else
gotostep2;
over:
returnIp;
//3)选定初始聚类中心
voidISODATA:
InitCenter()
srand((unsigned)time(NULL));
intnum=N;
intno[MAXNUM];
no[i]=i;
for(intj=0;
Nc;
{
intk=rand()%num;
w[j].z=x[no[k]];
w[j].z.n=0;
for(intl=k;
l<
num;
l++)
no[l]=no[l+1];
num--;
//step1:
设定聚类分析控制参数
SetupParameter()
cout<
设定聚类分析控制参数:
"
预期的类数c:
cin>
c;
初始聚类中心个数(可以不等于c)Nc:
Nc;
每一类中允许的最少模式数目(若少于此数,就不能单独成为一类)theta_n:
theta_n;
类内各分量分布的标准差上限(大于此数就分裂)theta_s:
theta_s;
两类中心间的最小距离下限(若小于此数,这两类应合并)theta_D:
theta_D;
在每次迭代中可以合并的类的最多对数L:
L;
允许的最多迭代次数I:
I;
//step2:
按最小距离原则将模式集(xi)中每个模式分到某一类中
Clustering()
doubletemp=0.0,min=MAXDOUBLE;
intl=0;
w[j].n=0;
min=MAXDOUBLE;
l=0;
{
temp=Pattern:
Distance(x[i],w[j].z);
if(min>
temp)
{
min=temp;
l=j;
}
}
w[l].Insert(x[i]);
//step3:
依据theta_n判断合并。
转至step2.
boolISODATA:
CombinBytheta_n()
intj=0;
do
if(w[j].n<
theta_n)
for(intk=j;
k<
k++)
//w[k]=w[k+1];
w[k].z=w[k+1].z;
Nc--;
//循环中跳出!
?
returntrue;
j++;
}while(j<
Nc);
returnfalse;
//step4:
计算分类后的参数:
CalParameter()
_d=0.0;
w[j].CalCenter();
_d+=w[j].n*w[j].Cal_D();
_d/=N;
//step6:
计算各类类内距离的标准差矢量
CalSigma()
w[j].CalSigma();
//step7:
求出每一聚类类内距离标准差矢量sigma中的最大分量sigma_max
CalMaxSigma()
//step8:
判断分裂
Split()
if(((w[j]._d>
_d)&
(w[j].n>
2*(theta_n+1)))||(Nc<
=c/2))
inti=w[j].max;
doublesigma=w[j].sigma_max;
for(intl=Nc;
l>
j;
l--)
w[l].z=w[l-1].z;
w[j].z.x[i]-=K*sigma;
w[j+1].z.x[i]+=K*sigma;
Nc++;
//step9:
计算各类对中心间的距离
CalCenterDis()
Nc-1;
for(intj=i+1;
D[i][j]=Pattern:
Distance(w[i].z,w[j].z);
//step10:
依据theta_D判断合并
CombinBytheta_D()
inti,j,k,l;
//循环变量
intnum=0;
boolb=false;
//较小的类对中心
struct
doubled;
inti;
intj;
}Dmin[MAXNUM];
for(i=0;
L;
Dmin[i].d=0.0;
Dmin[i].i=-1;
Dmin[i].j=-1;
//将D[i][j]与theta_D比较,并将小于theta_D的那些D[i][j]按递增次序排列,取前L个,Dmin[0]<
Dmin[1]<
Dmin[2]...
for(j=i+1;
if(D[i][j]<
theta_D)
for(k=0;
if(D[i][j]<
Dmin[k].d)
{
for(l=L-1;
k;
Dmin[l]=Dmin[l-1];
Dmin[k].d=D[i][j];
Dmin[k].i=i;
Dmin[k].j=j;
break;
}
//从最小的Dmin开始,将相应的两类合并。
if(Dmin[i].i>
-1&
Dmin[i].j>
-1)
//合并两类
if(w[Dmin[i].i].Combin(w[Dmin[i].j]))
b=true;
//去掉已取消的类心
for(j=0;
if(w[j].z.n==-2)
for(k=j;
returnb;
//step11:
判断循环还是退出
//输出当前模式分类情况
PrintSort()
{
共分为分为"
类。
第"
i+1<
类类心为:
\t("
dim-1;
cout<
setw(5)<
w[i].z.x[j]<
"
w[i].z.x[dim-1]<
)"
包含的模式为:
for(intk=0;
w[i].n;
//Xi(12,12,12);
\tX"
w[i].x[k].n<
("
for(intj=0;
cout<
w[i].x[k].x[j]<
w[i].x[k].x[dim-1]<
);
实习体会
经过这次实习,我感到自己还是学到了很多的东西,对于模式识别而言也有了更进一步的了解和加深。
知道自己该通过哪些步骤来达到自己的目的。
另外,通过实习我们也实习我们也熟悉了对VC软件的使用,为以后的工作打下了坚实的基础。
同时也通过编程,加深了对ISODATA算法的理解。