决策支持系统与商务智能.docx
《决策支持系统与商务智能.docx》由会员分享,可在线阅读,更多相关《决策支持系统与商务智能.docx(9页珍藏版)》请在冰豆网上搜索。
决策支持系统与商务智能
决策支持系统与商务智能算法的实现
[Java]K-Means聚类算法的实现
算法思路:
首先从n个数据对象任意选择k个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。
一般都采用均方差作为标准测度函数.k个聚类具有以下特点:
各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
主要实验过程:
1)从N个文档随机选取K个文档作为质心
2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类
3)重新计算已经得到的各个类的质心
4)迭代2~3步直至新的质心与原质心相等或小于指定阀值,算法结束
具体如下:
输入:
k,data[n];
(1)选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
(2)对于data[0]….data[n],分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;
(3)对于所有标记为i点,重新计算c[i]={所有标记为i的data[j]之和}/标记为i的个数;
(4)重复
(2)(3),直到所有c[i]值的变化小于给定阈值。
关键问题的解决方法:
1、在K-means算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。
这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果,这也成为K-means算法的一个主要问题。
对于该问题的解决,许多算法采用遗传算法(GA),例如文献中采用遗传算法(GA)进行初始化,以内部聚类准则作为评价指标。
2、在K-means算法中K是事先给定的,这个K值的选定是非常难以估计的。
很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。
这也是K-means算法的一个不足。
有的算法是通过类的自动合并和分裂,得到较为合理的类型数目K,例如ISODATA算法。
关于K-means算法中聚类数目K值的确定在文献中,是根据方差分析理论,应用混合F统计量来确定最佳分类数,并应用了模糊划分熵来验证最佳分类数的正确性。
在文献中,使用了一种结合全协方差矩阵的RPCL算法,并逐步删除那些只包含少量训练数据的类。
而文献中使用的是一种称为次胜者受罚的竞争学习规则,来自动决定类的适当数目。
它的思想是:
对每个输入而言,不仅竞争获胜单元的权值被修正以适应输入值,而且对次胜单元采用惩罚的方法使之远离输入值。
程序的实现截图:
心得体会:
通过决策这么课程的学习使我们更加了解了数据挖掘对现代的数据处理的重要性,紧迫性和使用性。
在对其中的聚类分析进行研究时,了解了它的基本原理,特别是K-means算法的一些原理。
还懂得了这些算法各有各的特点和缺点,也不是我们想的那样一种算法的出现后就代替了另外的算法,再先出现的算法都有自己优越的一面。
正因为这样才使得我们的编程更加的方便和快捷。
算法源代码:
packagefd;
publicclassBasicKMeans{
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
double[]p={1,2,3,5,6,7,9,10,11,100,150,200,1000};
intk=5;
double[][]g;
g=cluster(p,k);
for(inti=0;ifor(intj=0;jSystem.out.print(g[i][j]);
System.out.print("\t");
}
System.out.println();
}
}
/*
*聚类函数主体。
*针对一维double数组。
指定聚类数目k。
*将数据聚成k类。
*/
publicstaticdouble[][]cluster(double[]p,intk){
//存放聚类旧的聚类中心
double[]c=newdouble[k];
//存放新计算的聚类中心
double[]nc=newdouble[k];
//存放放回结果
double[][]g;
//初始化聚类中心
//经典方法是随机选取k个
//本例中采用前k个作为聚类中心
//聚类中心的选取不影响最终结果
for(inti=0;ic[i]=p[i];
//循环聚类,更新聚类中心
//到聚类中心不变为止
while(true){
//根据聚类中心将元素分类
g=group(p,c);
//计算分类后的聚类中心
for(inti=0;inc[i]=center(g[i]);
}
//如果聚类中心不同
if(!
equal(nc,c)){
//为下一次聚类准备
c=nc;
nc=newdouble[k];
}else//聚类结束
break;
}
//返回聚类结果
returng;
}
/*
*聚类中心函数
*简单的一维聚类返回其算数平均值
*可扩展
*/
publicstaticdoublecenter(double[]p){
returnsum(p)/p.length;
}
/*
*给定double型数组p和聚类中心c。
*根据c将p中元素聚类。
返回二维数组。
*存放各组元素。
*/
publicstaticdouble[][]group(double[]p,double[]c){
//中间变量,用来分组标记
int[]gi=newint[p.length];
//考察每一个元素pi同聚类中心cj的距离
//pi与cj的距离最小则归为j类
for(inti=0;i
//存放距离
double[]d=newdouble[c.length];
//计算到每个聚类中心的距离
for(intj=0;jd[j]=distance(p[i],c[j]);
}
//找出最小距离
intci=min(d);
//标记属于哪一组
gi[i]=ci;
}
//存放分组结果
double[][]g=newdouble[c.length][];
//遍历每个聚类中心,分组
for(inti=0;i//中间变量,记录聚类后每一组的大小
ints=0;
//计算每一组的长度
for(intj=0;jif(gi[j]==i)
s++;
//存储每一组的成员
g[i]=newdouble[s];
s=0;
//根据分组标记将各元素归位
for(intj=0;jif(gi[j]==i){
g[i][s]=p[j];
s++;
}
}
//返回分组结果
returng;
}
/*
*计算两个点之间的距离,这里采用最简单得一维欧氏距离,可扩展。
*/
publicstaticdoubledistance(doublex,doubley){
returnMath.abs(x-y);
}
/*
*返回给定double数组各元素之和。
*/
publicstaticdoublesum(double[]p){
doublesum=0.0;
for(inti=0;i
sum+=p[i];
returnsum;
}
/*
*给定double类型数组,返回最小值得下标。
*/
publicstaticintmin(double[]p){
inti=0;
doublem=p[0];
for(intj=1;j
if(p[j]i=j;
m=p[j];
}
}
returni;
}
/*
*判断两个double数组是否相等。
长度一样且对应位置值相同返回真。
*/
publicstaticbooleanequal(double[]a,double[]b){
if(a.length!
=b.length)
returnfalse;
else{
for(inti=0;iif(a[i]!
=b[i])
returnfalse;
}
}
returntrue;
}
}