聚类分析的主要步骤
1.数据预处理,
2.为衡量数据点间的相似度定义一个友盯距离函数,
3.聚类或分组,
4.评估输出。
数据预处理包括选择数量,类型和特征的标度,它依靠特征选择和特征抽取,特征选择选择重要的特征,特征抽取把输入的特征转化为一个新的显著特征,它们经常被用来获取一个合适的特征集来为避免“维数灾”进行聚类,数据预处理还包括将孤立点移出数据,孤立点是不依附于一般数据行为或模型的数据,因此孤立点经常会导致有偏差的聚类结果,因此为了得到正确的聚类,我们必须将它们剔除。
既然相类似性是定义一个类的基础,那么不同数据之间在同一个特征空间相似度的衡量对于聚类步骤是很重要的,由于特征类型和特征标度的多样性,距离度量必须谨慎,它经常依赖于应用,例如,通常通过定义在特征空间的距离度量来评估不同对象的相异性,很多距离度都应用在一些不同的领域,一个简单的距离度量,如Euclidean距离,经常被用作反映不同数据间的相异性,一些有关相似性的度量,例如PMC和SMC,能够被用来特征化不同数据的概念相似性,在图像聚类上,子图图像的误差更正能够被用来衡量两个图形的相似性。
将数据对象分到不同的类中是一个很重要的步骤,数据基于不同的方法被分到不同的类中,划分方法和层次方法是聚类分析的两个主要方法,划分方法一般从初始划分和最优化一个聚类标准开始。CrispClustering,它的每一个数据都属于单独的类;FuzzyClustering,它的每个数据可能在任何一个类中,CrispClustering和FuzzyClusterin是划分方法的两个主要技术,划分方法聚类是基于某个标准产生一个嵌套的划分系列,它可以度量不同类之间的相似性或一个类的可分离性用来合并和分裂类,其他的聚类方法还包括基 于密度的聚类,基于模型的聚类,基于网格的聚类。
评估聚类结果的质量是另一个重要的阶段,聚类是一个无管理的程序,也没有客观的标准来评价聚类结果,它是通过一个类有效索引来评价,一般来说,几何性质,包括类间的分离和类内部的耦合,一般都用来评价聚类结果的质量,类有效索引在决定类的数目时经常扮演了一个重要角色,类有效索引的最佳值被期望从真实的类数目中获取,一个通常的决定类数目的方法是选择一个特定的类有效索引的最佳值,这个索引能否真实的轿闹得出类的数目是判断该索引是否有效的标准,很多已经存在的标准对于相互分离的类数据集合都能得出很好的结果,但好帆和是对于复杂的数据集,却通常行不通,例如,对于交叠类的集合。
你这是四维数据,我这是一维数据kmeans,你试试吧#include<iostream>此肢此
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std
int N //数据个数
int K //集合个数
int *CenterIndex//质心索引集合,即属于第几个参考点
double *Center //质心集合
double *CenterCopy
double *DataSet
double **Cluster
int *Top
/*算法描饥氏述:
C-Fuzzy均值聚类算法采用的是给定类的个数K,将N个元素(对象)分配到K个类中去使得类内对象之间的相似性最大,而类之间的相似性最小 */
//函数声明部分
void InitData()
void InitCenter()
void CreateRandomArray(int n,int k,int *centerIndex)
void CopyCenter()
void UpdateCluster()
void UpdateCenter()
int GetIndex(double value,double *centerIndex)
void AddtoCluster(int index,double value)
void print()
bool IsEqual(double *center,double *centercopy)
int main()
{
int Flag=1
InitData()
while(Flag)//无限次循环
{
UpdateCluster()
UpdateCenter()
if(IsEqual(Center,CenterCopy))
{
Flag=0
}
else
{
CopyCenter()
}
}
print()
getchar()
system("pause")
}
void InitData()
{
int i=0
int a
cout<<"请输入数据元素的个数: "
cin>>N
cout<<"请输入分类数: "
cin>>K
if(K>N)
{
return
}
CenterIndex =new int [sizeof(int)]
Center =new double [sizeof(double)*K]
CenterCopy =new double [sizeof(double)*K]
DataSet =new double [sizeof(double)*N]
Cluster =new double* [sizeof(double*)*K]
Top =new int [sizeof(int)*K]
//初始化K个类的集合
for(i=0i<Ki++)
{
Cluster[i]=new double [sizeof(double)*N]
Top[i]=0
}
cout<<"请输入数据"<<endl
for(i=0i<Ni++)
{
cin>>a
DataSet[i]=a
}
//初始化质心集合
InitCenter()
UpdateCluster()
}
void InitCenter()//初始化中心点(参照点)
{
int i=0
//产生随即的K个<N的不同的序列
CreateRandomArray(N,K,CenterIndex)
for(i=0i<Ki++)
{
Center[i]=DataSet[CenterIndex[i]]
}
CopyCenter()
}
void CreateRandomArray(int n,int k,int *centerIndex)//产生可以随输出控制的 k与n (可舍弃)
{
int i=0,j=0
for(i=0i<Ki++)
{
int a=rand()%n
for(j=0j<ij++)
{
if(centerIndex[j]==a)
break
}
if(j>=i)
{
centerIndex[i]=a
}
else
{
i--
}
}
}
void CopyCenter()//将旧的中心点保留以作森迅比较
{
int i=0
for(i=0i<Ki++)
{
CenterCopy[i]=Center[i]
}
}
void UpdateCluster()//
{
int i=0
int tindex
for(i<Ki++)
{
Top[i]=0
}
for(i=0i<Ni++)
{
tindex=GetIndex(DataSet[i],Center)
AddtoCluster(tindex,DataSet[i])
}
}
int GetIndex(double value,double *center)//判断属于哪个参照点
{
int i=0
int index=i
double min=fabs(value-center[i])
for(i=0i<Ki++)
{
if(fabs(value-center[i])<min)
{
index=i
min=fabs(value-center[i])
}
}
return index
}
void AddtoCluster(int index,double value)//统计每组个数(用于均值法求新的参照点)
{
Cluster[index][Top[index]]=value
Top[index]++
}
void UpdateCenter()//更新参照点
{
int i=0,j=0
double sum
for(i=0i<Ki++)
{
sum=0.0
for(j=0j<Top[i]j++)
{
sum+=Cluster[i][j]
}
if(Top[i]>0)
{
Center[i]=sum/Top[i]
}
}
}
bool IsEqual(double *center,double*centercopy)//
{
int i
for(i=0i<Ki++)
{
if(fabs(center[i]!=centercopy[i]))
return 0
}
return 1
}
void print()//
{
int i,j
cout<<"===================================="<<endl
for(i=0i<Ki++)
{
cout<<"第"<<i<<"组:质心为:"<<Center[i]<<endl
cout<<"数据元素为:\n"
for(j=0j<Top[i]j++)
{
cout<<Cluster[i][j]<<'\t'
}
cout<<endl
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)