模式识别实验报告.docx

上传人:b****5 文档编号:7188988 上传时间:2023-01-21 格式:DOCX 页数:23 大小:137.74KB
下载 相关 举报
模式识别实验报告.docx_第1页
第1页 / 共23页
模式识别实验报告.docx_第2页
第2页 / 共23页
模式识别实验报告.docx_第3页
第3页 / 共23页
模式识别实验报告.docx_第4页
第4页 / 共23页
模式识别实验报告.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

模式识别实验报告.docx

《模式识别实验报告.docx》由会员分享,可在线阅读,更多相关《模式识别实验报告.docx(23页珍藏版)》请在冰豆网上搜索。

模式识别实验报告.docx

模式识别实验报告

武汉大学国际软件学院

实验报告

 

课程名称模式识别导论

专业年级2015级

姓名宁佳星

学号2015302580323

协作者

实验学期2017-2018学年上学期

课堂时数0课外时数12

填写时间2017年11月12日

 

实验概述

【实验项目名称】:

模式识别作业1

【实验目的】:

1、请编写程序实现混合类型属性差异性矩阵计算

2、请编写程序实现近邻聚类算法或者最大最小距离聚类算法

3、请编写程序实现层次聚类算法

4、请编写程序实现K-means或者K-中心点聚类算法

5、请编写程序实现ISODATA算法

6、使用统一的测试数据观察不同算法的聚类结果,并讨论为什么

【实验环境】(使用的软件):

●Windiws7

●VisualStudio2017

【参考资料】:

●《模式识别作业1》

●模式识别PPT

●网络索引

实验内容

【实验方案设计】:

1、编写程序实现混合类型属性差异性矩阵计算

//矩阵三元组之矩阵相加相乘

...

#defineMAXSIZE12500//最大非零元素

...

voidInputMatrix(TSMatrix&T)//输入t个非零元素

{

...

}

...

voidTransposeSMatrix(TSMatrixM,TSMatrix&T)//矩阵的转置

{

...

}

...

voidAddMastrix(TSMatrixM,TSMatrixT,TSMatrix&Q)//矩阵相加

{

...

}

...

//for循环复制剩余元素

...

voidMultiply(TSMatrixM,TSMatrixT,TSMatrix&Q)//矩阵相乘

{

...

int*rowSize=newint[T.mu+1];//存放每行非零元素的个数

int*rowStart=newint[T.mu+2];//矩阵每行在三元组开始位置

int*temp=newint[T.nu+1];//存放结果矩阵中每行的计算结果

...

while(Current<=M.tu)

{

ROWM=M.data[Current].row;//当前三元组数据中元素的行号

...

while(Current<=M.tu&&ROWM==M.data[Current].row)

{

COLM=M.data[Current].col;//当前元素的列号,方便与T矩阵的行号相乘

for(i=rowStart[COLM];i

...

}

}

...

2、编写程序实现近邻聚类算法或者最大最小距离聚类算法

//最大最小距离聚类算法

...

constintN=15;//设置样本点个数

...

voidmain(void)

{

...

floats[2][N]={{0,1,0,-1,0,10,11,9,10,10,-10,-11,-9,-10,-10},

{0,0,1,0,-1,0,0,0,1,-1,0,0,0,1,-1}};//输入样本点

...

center[0]=0;//firstcenter

...

center[1]=index;//secondcenter

...

//求出所有中心,finalarraymin[]isstilluseful

while(theshold>theta*D12)

{

...

//min-operate

for(j=0;j

{

...

}

...

if(max>theta*D12){k++;center[k]=index;}//addacenter

theshold=max;//preparetoloopnexttime

}

...

}

3、编写程序实现层次聚类算法

//实现层次聚类算法

...

//计算两个样本点之间的欧几里得距离

doubleCAgeneCluster:

:

getDistance(sDataPointdpA,sDataPointdpB)

{

...

}

list*CAgeneCluster:

:

initialCluster(list*dataPoints)

{

...

{

sDataPointtempDataPoint=*iter;//取出数据,

...

tempCluster.clusterLabel=i;//初始类簇号为各原数据顺序号

tempCluster.datapointList->push_back(tempDataPoint);

//每一个数据为一类

originalClusters->push_back(tempCluster);//originalClusters为类簇序列

...

}

...

}

list*CAgeneCluster:

:

mergeCluster(list*clusters,intmergeIndexA,intmergeIndexB)//mergeIndexA,B是类簇标号

{

...

intnBreak=0;//计算找到的次数,以提前退出循环,节省时间

if(mergeIndexA!

=mergeIndexB)//分属于不同的类簇,则合并.

{//将cluster[mergeIndexB]中的DataPoint加入到cluster[mergeIndexA]

for(list:

:

iteratoriter=clusters->begin();iter!

=clusters->end();iter++)

{//把mergeIndexA所在类簇提取出来。

tempCluster=*iter;//以下程序找出mergeIndexAandB所在类簇,并从链表中删除B类簇。

if(tempCluster.clusterLabel==mergeIndexA)

{

nBreak++;//计算找到的次数,以提前退出循环,节省时间

tempClusterA=*iter;

}//endforif(tempCluster.clusterLabel==mergeIndexA)

if(tempCluster.clusterLabel==mergeIndexB)

{//并从链表中删除B类簇。

tempClusterB=*iter;

nBreak++;//计算找到的次数,以提前退出循环,节省时间

...

if(nBreak==2)

{//找到两个类簇,则提前退出循环,节省时间。

nBreak=0;

break;

}

}

...

dpA=tempClusterA.datapointList;//把clusterA中的数据集提取出来。

...

for(list:

:

iteratoriter=dpB->begin();iter!

=dpB->end();iter++)

{//取出数据

dpA->push_back(*iter);//把B中数据存入到A.

}

...

}

...

}

list*CAgeneCluster:

:

startAnalysis(list*dataPoints,unsignedintClusterNum)

{

...

originalClusters=initialCluster(dataPoints);//数据集初始化;//originalClusters为类簇序列

...printCluster(originalClusters);//打印聚类情况

...

while(finalClusters->size()>ClusterNum)//聚类数为ClusterNum

{

doubleminDist=9999999.9999;//maxvalue

...

{

...

if(iIter!

=jIter)

{

...

dataPointsA=ClusterA.datapointList;//类簇中的数据集

clusterLabelA=ClusterA.clusterLabel;//类簇标号

dataPointsB=ClusterB.datapointList;//类簇中的数据集

clusterLabelB=ClusterB.clusterLabel;//类簇标号

for(list:

:

iteratoriterdpA=dataPointsA->begin();iterdpA!

=dataPointsA->end();iterdpA++)

{

...

if(tempDis

{

minDist=tempDis;//每次都是距离最小的两个合并。

...

}

...

}

cout<<"mergeIndexA="<

finalClusters=mergeCluster(finalClusters,mergeIndexA,mergeIndexB);//mergeIndexA,B是类簇标号

printCluster(originalClusters);//打印聚类情况

}

...

}

...

4、编写程序实现K-means或者K-中心点聚类算法

//K-means聚类算法

...

constintNUM=3;//定义划分簇的数目

//数据向量表示

...

//计算距离的平方

doublegetDist(VectA,VectB)

{

...

}

//计算每个簇的中心,平均距离表示

VectgetMeansC(vectort)

{

...

for(inti=0;i

{

...

}

Vectc;

...

}

//获取算法的准则函数值,当准则函数收敛时算法停止

doublegetE(vectorclasses[],Vectmeans[])

{

...

for(inti=0;i

{

...

}

...}

intsearchMinC(Vectt,Vectmeans[],intn,double*D)

{

...

for(inti=1;i

{

...

}

...

}

//找最优的种子点

voidFind(vectorinit,Vectmeans[])

{

...

for(inti=1;i

{

...

for(intj=0;j

{

...

}

...

for(intj=0;j

{

...

}

}

...}

voidkMeans(vectorinit)

{

...

newE=getE(classes,means);//计算当前准则函数值

for(inti=0;i

...

while(fabs(newE-oldE)>=1)

{

for(inti=0;i

{

...

}

...

}

//输出最终结果

for(inti=0;i

{

...

}

//每个类的中心点坐标

for(inti=0;i

...

}

...

5、编写程序实现ISODATA算法

//ISODATA算法

...

#defineiniClusters5//初始类聚的个数

...//定义6个使用的参数

structArgs

{

intexpClusters;//期望得到的聚类数

intthetaN;//聚类中最少样本数

intmaxIts;//最大迭代次数

intcombL;//每次迭代允许合并的最大聚类对数

doublethetaS;//标准偏差参数

doublethetaC;//合并参数

}args;

//定义二维点,这里假设是二维的特征,当然可以推广到多维

structPoint

{

doublex,y;

};

//需要合并的两个类聚的信息,包括两个类聚的id和距离

structMergeInfo

{

intu,v;

doubled;//类聚u中心与类聚v中心的距离

};

//定义比较函数

boolcmp(MergeInfoa,MergeInfob)

{

returna.d

}

//计算两点之间距离

doubledist(PointA,PointB)

{

returnsqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));

}

structCluster

{

intnSamples;//样本点的个数

doubleavgDist;//样本点到样本中心的平均距离

Pointcenter;//样本中心

Pointsigma;//样本与中心的标准差

vectordata;//聚类的数据

//计算该聚类的中心,即该类的均值

voidcalMean()

{

...

}

//计算该类样本点到该聚类中心得平均距离

voidcalDist()

{

...

}

//计算样本与中心的标准差

voidcalStErr()

{

...

}

};

//获取数据

voidgetData(Pointp[],intn)

{

...

}

//设置参数的值

voidsetArgs()

{

...

}

//寻找点t距离最近的类的中心对应的id

intFindIdx(vector&c,Point&t)

{

...

}

//二分法寻找距离刚好小于thetaC的两个类聚的index

intFindPos(MergeInfo*info,intn,doublethetaC)

{

...

}

...

voidISOData(Pointp[],intn)

{

...

intnClusters=iniClusters;//初始化类聚个数

//初始化nClusters个类,设置相关数据

...

boolisLess=false;//标志是否有类的数目低于thetaN

while

(1)

{

//先清空每一个聚类

for(inti=0;i

{

...

}

//将所有样本划分到距离类聚中心最近的类中

...

intk=0;//记录样本数目低于thetaN的类的index

for(inti=0;i

{

if(c.at(i).data.size()

{

isLess=true;//说明样本数过少,该类应该删除

...

}

}

//如果有类的样本数目小于thetaN

if(isLess)

{

...

}

//重新计算均值和样本到类聚中心的平均距离

for(inti=0;i

{

...

}

//计算总的平均距离

...

//分裂操作

if(nClusters<=args.expClusters/2)

{

...

for(inti=0;i

{

//计算该类的标准偏差

c.at(i).calStErr();

//计算该类标准差的最大分量

doublemt=c.at(i).sigma.x>c.at(i).sigma.y?

c.at(i).sigma.x:

c.at(i).sigma.y;

maxsigma.push_back(mt);

}

...

{

nClusters++;

ClusternewCtr;//新的聚类中心

//获取新的中心

...

//改变老的中心

...

}

...

}

//合并操作

if(nClusters>=2*args.expClusters||(iter&1)==0)

{

intsize=nClusters*(nClusters-1);

//需要合并的聚类个数

...

//进行排序

sort(info,info+cnt,cmp);

//找出info数组中距离刚好小于thetaC的index,那么index更小的更应该合并

intiPos=FindPos(info,cnt,args.thetaC);

//用于指示该位置的样本点是否已经合并

bool*flag=newbool[nClusters];

memset(flag,false,sizeof(bool)*nClusters);

//用于标记该位置的样本点是否已经合并删除

bool*del=newbool[nClusters];

memset(del,false,sizeof(bool)*nClusters);

//记录合并的次数

intnTimes=0;

for(inti=0;i<=iPos;i++)

{

...

//确保同一个类聚只合并一次

if(!

flag[u]&&!

flag[v])

{

nTimes++;

//如果一次迭代中合并对数多于combL,则停止合并

if(nTimes>bL)break;

//将数目少的样本合并到数目多的样本中

if(c.at(u).nSamples

...

}

//删除合并后的聚类

vector:

:

iteratorid=c.begin();

...

//合并多少次就删除多少个

...

}

...

}

intmain()

...

6、用统一的测试数据观察不同算法的聚类结果,并讨论为什么

1中矩阵运算的试验数据见下图(结果)

2-5中使用同同样的样本点数据测试,详情见下图,分析见小结

相关数据:

 

【结论】(结果):

1、编写程序实现混合类型属性差异性矩阵计算

2、编写程序实现近邻聚类算法或者最大最小距离聚类算法

3、编写程序实现层次聚类算法

4、编写程序实现K-means或者K-中心点聚类算法

5、编写程序实现ISODATA算法

【小结】:

●实验要求算法基本实现,经完善后可正常运行计算

●关于2-5中不同算法对相同数据的运算得到了略有有差别的结果

●聚类的目标是使同一类对象的相似度尽可能地大;不同类对象之间的相似度尽可能地小

●不同算法的根本思想具有一定的差异,因此导致了计算结果的差异

●例如层次聚类

●优点:

适用于任意形状和任意属性的数据集;灵活控制不同层次的聚类粒度,强聚类能力

●缺点:

大大延长了算法的执行时间,不能回溯处理

●例如K-means算法

●优点:

应用广泛;收敛速度快;能扩展以用于大规模的数据集

●缺点:

倾向于识别凸形分布、大小相近、密度相近的聚类;中心选择和噪声聚类对结果影响大

●ISODATA算法是一种常用的聚类分析方法,是一种非监督学习方法。

ISODATA算法通过设置初始参数而引入人机对话环节,并使用归并和分裂等机制,当两类聚中心小于某个阀值时,将它们合并为一类。

当某类的标准差大于某一阀值时或其样本数目超过某一阀值时,将其分裂为两类,在某类样本数目小于某一阀值时,将其取消。

这样根据初始类聚中心和设定的类别数目等参数迭代,最终得到一个比较理想的分类结果。

指导教师评语及成绩

【评语】:

 

 

 

 

成绩:

          指导教师签名:

                                              批阅日期:

附件:

实验报告说明

1.实验项目名称:

要用最简练的语言反映实验的内容。

要求与实验指导书中相一致。

2.实验目的:

目的要明确,要抓住重点,符合实验任务书中的要求。

3.实验环境:

实验用的软硬件环境(配置)。

4.实验方案设计(思路、步骤和方法等):

这是实验报告极其重要的内容。

包括概要设计、详细设计和核心算法说明及分析,系统开发工具等。

应同时提交程序或设计电子版。

对于设计型和综合型实验,在上述内容基础上还应该画出流程图、设计思路和设计方法,再配以相应的文字

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 兵器核科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1