Kmeans实验报告.docx

上传人:b****6 文档编号:5172211 上传时间:2022-12-13 格式:DOCX 页数:18 大小:24.63KB
下载 相关 举报
Kmeans实验报告.docx_第1页
第1页 / 共18页
Kmeans实验报告.docx_第2页
第2页 / 共18页
Kmeans实验报告.docx_第3页
第3页 / 共18页
Kmeans实验报告.docx_第4页
第4页 / 共18页
Kmeans实验报告.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Kmeans实验报告.docx

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

Kmeans实验报告.docx

Kmeans实验报告

目录

1.问题描述2

2.设计要求2

3.需求分析3

4.详细设计3

5.测试及运行结果4

6.程序源码及注释5

7.课程设计心得体会15

 

1.问题描述

k-means算法是根据聚类中的均值进行聚类划分的聚类算法。

输入:

聚类个数k,以及包含n个数据对象的数据。

输出:

满足方差最小标准的k个聚类。

处理流程:

Step1.从n个数据对象任意选择k个对象作为初始聚类中心;

Step2.循环Step3到Step4直到每个聚类不再发生变化为止;

Step3.根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离,并根据最小距离重新对相应对象进行划分;

Step4.重新计算每个(有变化)聚类的均值(中心对象)

k-means算法的工作过程说明如下:

首先从n个数据对象任意选择k个对象作为初始聚类中心,而对于所剩下的其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类。

然后,再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值),不断重复这一过程直到标准测度函数开始收敛为止。

一般都采用均方差作为标准测度函数,具体定义如下:

(1)

其中E为数据库中所有对象的均方差之和,p为代表对象的空间中的一个点,mi为聚类Ci的均值(p和mi均是多维的)。

公式

(1)所示的聚类标准,旨在使所获得的k个聚类具有以下特点:

各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

2.设计要求

首先从n个数据对象任意选择k个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。

输入:

聚类个数k,以及包含n个数据对象的数据库。

输出:

满足方差最小标准的k个聚类

3.需求分析

K-Mean是一种分割式分群方法,其主要目标是要在大量高纬的资料点中找出具有代表性的资料点;这些资料点可以称为群中心,代表点;然后再根据这些群中心,进行后续的处理,这些处理可以包含

1)资料压缩:

以少数的资料点来代表大量的资料,达到资料压缩的功能;

2)资料分类:

以少数代表点来代表特点类别的资料,可以降低资料量及计算量;

分割式分群法的目的是希望尽量減小每个群聚中,每一点与群中心的距离平方差(squareerror)。

假設我们現在有一組包含c个群聚的資料,其中第k个群聚可以用集合Gk來表示,假设Gk包含nk个資料{x1,x2,…,xnk),此群聚中心为yk,则该群聚的平方差ek可以定义为:

ek=Si|xi-yk|2,其中xi是属于第k群的资料点。

而这c个群聚的总和平方差E便是每个群聚的平方差总和:

E=Sk=1~cek

我们分群的方法,就改成是一个最佳化的問題,換句话說,我們要如何选取c个群聚以及相关的群中心,使得E的值为最小。

4.详细设计

k-means算法是一种基于样本间相似性度量的间接聚类方法,属于非监督学习方法。

此算法以k为参数,把n个对象分为k个簇,以使簇内具有较高的相似度,而且簇间的相似度较低。

相似度的计算根据一个簇中对象的平均值(被看作簇的重心)来进行。

此算法首先随机选择k个对象,每个对象代表一个聚类的质心。

对于其余的每一个对象,根据该对象与各聚类质心之间的距离,把它分配到与之最相似的聚类中。

然后,计算每个聚类的新质心。

重复上述过程,直到准则函数会聚。

k-means算法是一种较典型的逐点修改迭代的动态聚类算法,其要点是以误差平方和为准则函数。

逐点修改类中心:

一个象元样本按某一原则,归属于某一组类后,就要重新计算这个组类的均值,并且以新的均值作为凝聚中心点进行下一次象元素聚类;逐批修改类中心:

在全部象元样本按某一组的类中心分类之后,再计算修改各类的均值,作为下一次分类的凝聚中心点。

k-means算法接受输入量k;然后将n个数据对象划分为k个聚类以便使得所获得的聚类满足:

同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。

聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。

k-means算法把N个点聚集成K个组合的算法,要求任意输入K各对象作为初始中心点,这个的最大疑问就是怎么能够通过这随便选择的K个点来达到满足要求的K个组合呢。

K-means算法其实每次迭代都会改变中心,也就是初始的K各对象作为中心点在每一次迭代后都会更新。

首先以这K各顶点作为初始K个聚类的中心顶点,第一轮计算所有的其他顶点与这个K个顶点的相似度,取相似度最大的或者说与这K个顶点中某个顶点距离最近的顶点加入这个顶点所代表的cluster中,注意在第一轮检测所有顶点的距离并判断其属于哪个簇的过程中,这K各簇的中心仍然是以这K个顶点作为代表的。

第一轮计算完毕之后,相当于形成了以这K个顶点为中心的K个聚类,此时计算这K个聚类的聚集度,即各个顶点与其中心顶点的距离和作为考察条件,在进行下一轮的迭代的时候,中心顶点就变了,此时就变成第一轮生成的K个聚类的中心顶点作为新的中心顶点并按照第一轮迭代的方法进行重新聚类,并计算各个聚类的聚合度,当聚合度不变的时候或者定义了最大迭代次数的时候,算法表示运算完毕。

5.测试及运行结果

0.49,0.29,0.48,0.5,0.56,0.24,0.35

0.07,0.4,0.48,0.5,0.54,0.35,0.44

0.56,0.4,0.48,0.5,0.49,0.37,0.46

0.59,0.49,0.48,0.5,0.52,0.45,0.36

0.23,0.32,0.48,0.5,0.55,0.25,0.35

0.67,0.39,0.48,0.5,0.36,0.38,0.46

0.29,0.28,0.48,0.5,0.44,0.23,0.34

0.21,0.34,0.48,0.5,0.51,0.28,0.39

重复聚类次数:

10

分类正确率:

78.27381%

选择的下标如下:

19180213220230236266329

分类结果列表:

2

2

2

6

2

6

2

2

6.程序源码及注释

/**

*K-Means聚类的主程序类

**/

publicclassK_Means{

publicK_Means(){

//TODO自动生成构造函数存根

clusterList=newClusterSet();

dataSet=newMatrix();

classData=newArrayList();

}

staticdoublesquareDistance(PointNDp1,PointNDp2)

{

if(p1.dimension==p2.dimension)

{

doubledistance=0.0;

for(inti=0;i

{

doublep1p=p1.pointND.get(i);

doublep2p=p2.pointND.get(i);

distance+=Math.pow((p1p-p2p),2);

}

returndistance;

}

return-1.0;

}

/**

*从外部数据文件中构造Matrix数据集

*@paramdataFile外部数据文件,文件中的每一行中数据间使用逗号分隔

*@returnMatrix对象数据集

*@throwsIOException

*/

privateMatrixbuildMatrix(FiledataFile)throwsIOException

{

Matrixmatrix=newMatrix();

ArrayListrows=matrix.rows;

FileInputStreamfin=newFileInputStream(dataFile);

BufferedReaderreader=newBufferedReader(newInputStreamReader(fin));

Stringline=reader.readLine();

String[]items=line.split("");

matrix.setWidth(items.length);

//读取文件中的每一行

while(line!

=null)

{

items=line.split(",");

DataItemrow=newDataItem();

PointNDp=row.rowdata;//每一行为一个N维坐标点

ArrayListpoints=p.pointND;

//将每个数据转为浮点型

for(inti=0;i

points.add(Double.parseDouble(items[i]));

rows.add(row);

line=reader.readLine();

}

matrix.setHeight();

reader.close();

returnmatrix;

}

/**

*由Matrix数据集对象初始化簇类列表

*使用随机选择的方法

*@paramtheDataSetMatrix数据集

*@paramnum簇类数目

*@return

*/

privateClusterSetinitClusterSet(MatrixtheDataSet,intnum)

{

returnrandomInit(theDataSet,num);

//returnthis.bestInit(dataSet,num);

}

/**

*随机选择k个数据项,作为k个簇类的中心

*@paramtheDataSetMatrix数据集对象

*@paramnum簇类个数

*@return簇类列表

*/

privateClusterSetrandomInit(MatrixtheDataSet,intnum)

{

//哈希集,记录生成的下标

HashSetht=newHashSet();

ClusterSetnewClusterList=newClusterSet();

intrange=theDataSet.height;

ArrayListrows=theDataSet.rows;

//System.out.println("随机选择"+num+"个数据项构造簇集...");

//随机选择法

intindex=(int)(range*Math.random());

ht.add(index);

//生成num个簇类

for(inti=0;i

{

index=(int)(range*Math.random());

//保证不会生成两个相同的下标

while(ht.contains(index))

index=(int)(range*Math.random());

goodIndexes[i]=index;

ht.add(index);

//intindex=i;

//System.out.print(index+"");

DataItemrow=rows.get(index);

PointNDcenter=row.rowdata;

Clusterclus=newCluster(center);

newClusterList.clusterList.add(clus);

}

newClusterList.setCount();

returnnewClusterList;

}

/**

*对数组进行简单的插入排序

*@paramarray

*@return

*/

privateint[]sortArray(int[]array)

{

for(inti=1;i

{

inttmp=array[i];

intj=i;

for(;j>0&&tmp

array[j]=array[j-1];

array[j]=tmp;

}

returnarray;

}

/**

*聚类过程

*@paramclusterList簇集列表

*@paramtheDataSet数据集

*/

privatevoidclustering(ClusterSetclusterList,MatrixtheDataSet)

{

ArrayListrows=theDataSet.rows;//数据集的数据行列表

//对于每一个数据行,找出最接近它的簇类,增加此簇类的成员数目,

//同时减少上一次聚类时最接近这个数据行的簇类的成员数目

for(inti=0;i

{

DataItemrow=rows.get(i);

ClusteroldNeighbor=row.mostNearestCluster;//上一次聚类最接近的簇类

row.setNeighbors(clusterList);

Clustercluster=row.findMostNearestNeighbor();//新的最接近的簇类

PointNDrowdata=row.rowdata;

//将数据添加到最接近的簇集中

ArrayListmemList=cluster.memberList;

memList.add(rowdata);

cluster.counts++;

//从上次最接近的簇类中删除数据

//oldNeighbor为空时表示第一次聚类

if(oldNeighbor!

=null)

{

ArrayListoldmemList=oldNeighbor.memberList;

oldmemList.remove(rowdata);

oldNeighbor.counts--;

//intc=oldNeighbor.counts;

}

}

}

/**

*K-Means聚类的接口

*调用聚类过程方法,当所有簇类的平均值不再改变时停止

*@paramclusterList簇类列表

*@paramdataSet数据集

*/

privatevoidkMeansClustering(ClusterSetclusterList,MatrixtheDataSet)

{

//首先进行第一次聚类

this.clustering(clusterList,theDataSet);

K_Means.repeatCounts++;//记录聚类次数

ArrayListcluList=clusterList.clusterList;

intsize=cluList.size();

intnoChangeCounts=0;

for(inti=0;i

{

ClusteratomClu=cluList.get(i);

//更新簇的中心,如果中心不改变,则计数增1

if(atomClu.noChange())

noChangeCounts++;

}

//所有簇类的平均值不再改变时结束

while(noChangeCounts!

=size)

{

noChangeCounts=0;

this.clustering(clusterList,theDataSet);

cluList=clusterList.clusterList;

for(inti=0;i

{

ClusteratomClu=cluList.get(i);

//更新簇的平均值

if(atomClu.noChange())

noChangeCounts++;

}

size=cluList.size();

//累计重复聚类次数

K_Means.repeatCounts++;

}

}

/**

*根据聚类结果对数据集分类

*@paramdataSet数据集

*/

privatevoidclassify(MatrixtheDataSet)

{

ArrayListrows=theDataSet.rows;

for(inti=0;i

{

DataItemrowdata=rows.get(i);

ClusterSetneighbors=rowdata.neighborClusters;

Clustercluster=rowdata.mostNearestCluster;

//最接近簇类在簇集列表中的下标

intlabelIndex=neighbors.clusterList.indexOf(cluster);

labelIndex++;

//标记类标识

rowdata.setLabel(""+labelIndex);

}

}

/**

*计算分类准确度

*@paramdataSet要测试的数据集

*@throwsIOException

*/

privatevoidcheckClassification(MatrixtheDataSet)throwsIOException

{

//System.out.println("重复聚类次数:

"+K_Means.repeatCounts);

ArrayListrows=theDataSet.rows;

//计算分类正确率

intorigin=0;//起始下标

intcorrectCount=0;//正确分类的数据行数

intgroupCount;//组的成员数

int[]tmp;//存储类包含的成员数目

for(inti=0;i

{

groupCount=classData.get(i);

tmp=newint[classData.size()];

//判别每一个组中的正确分类的元素个数

for(intj=origin;j

{

DataItemitem=rows.get(j);

intlabel=Integer.parseInt(item.cLabel);

tmp[label-1]++;//相应的类计数增1

}

//找出数组中的最大元素,以这个元素作为这个组的类计数

intmaxValue=0;

for(intk=0;k

{

if(tmp[k]>maxValue)

{

maxValue=tmp[k];

}

}

correctCount+=maxValue;

origin+=groupCount;

}

this.correctPercent=(float)correctCount/rows.size();

//保存分类说明及结果

if(this.correctPercent>border)

{

System.out.println("重复聚类次数:

"+K_Means.repeatCounts);

System.out.println("分类正确率:

"+this.correctPercent*100+"%");

this.saveFile();

}

//floatcorrectPercent=(float)correctCount/rows.size();

//System.out.println("分类正确率:

"+this.correctPercent*100+"%");

}

/**

*计算分类准确度的公用接口

*@throwsIOException

*/

publicvoidcheckClassification()throwsIOException

{

this.checkClassification(this.dataSet);

}

/**

*保存分类文件

*@throwsIOException

*/

privatevoidsaveFile()throwsIOException

{

System.out.println("保存分类文件...");

FileclassFile=newFile("class.txt");

if(classFile.exists())

classFile.delete();

FileOutputStreamfout=newFileOutputStream(classFile);

PrintWriterpWriter=newPrintWriter(fout);

ArrayListrows=this.dataSet.rows;

pWriter.println("重复聚类次数:

"+K_Means.repeatCounts);

pWriter.println("分类正确率:

"+this.correctPercent*100+"%");

p

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

当前位置:首页 > 高等教育 > 艺术

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

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