`
fufeng
  • 浏览: 75514 次
社区版块
存档分类
最新评论

聚类分析(四)层次聚类算法

阅读更多

层次聚类算法:

前面介绍的 K-means 算法和 K 中心点算法都属于划分式( partitional )聚类算法。层次聚类算法是将所有的样本点自底向上合并组成一棵树或者自顶向下分裂成一棵树的过程,这两种方式分别称为凝聚和分裂。

凝聚层次算法 :

初始阶段,将每个样本点分别当做其类簇,然后合并这些原子类簇直至达到预期的类簇数或者其他终止条件。

分裂层次算法 :

初始阶段,将所有的样本点当做同一类簇,然后分裂这个大类簇直至达到预期的类簇数或者其他终止条件。

两种算法的代表:

传统的凝聚层次聚类算法有 AGENES ,初始时, AGENES 将每个样本点自为一簇,然后这些簇根据某种准则逐渐合并,例如,如果簇 C1 中的一个样本点和簇 C2 中的一个样本点之间的距离是所有不同类簇的样本点间欧几里得距离最近的,则认为簇 C1 和簇 C2 是相似可合并的。

传统的分裂层次聚类算法有 DIANA ,初始时 DIANA 将所有样本点归为同一类簇,然后根据某种准则进行逐渐分裂,例如类簇 C 中两个样本点 A B 之间的距离是类簇 C 中所有样本点间距离最远的一对,那么样本点 A B 将分裂成两个簇 C1 C2 ,并且先前类簇 C 中其他样本点根据与 A B 之间的距离,分别纳入到簇 C1 C2 , 例如,类簇 C 中样本点 O 与样本点 A 的欧几里得距离为 2 ,与样本点 B 的欧几里得距离为 4 ,因为 Distance(A O)<Distance(B,O) 那么 O 将纳入到类簇 C1 中。

如图所示:

聚类分析(四)层次聚类算法

算法: AGENES 。传统凝聚层次聚类算法

输入: K :目标类簇数 D :样本点集合

输出: K 个类簇集合

方法: 1) D 中每个样本点当做其类簇;

      2) repeat

      3)    找到分属两个不同类簇,且距离最近的样本点对;

      4)    将两个类簇合并;

      5) util 类簇数 =K

 

算法: DIANA 。传统分裂层次聚类算法

输入: K :目标类簇数 D :样本点集合

输出: K 个类簇集合

方法: 1) D 中所有样本点归并成类簇;

      2) repeat

      3)    在同类簇中找到距离最远的样本点对;

      4)    以该样本点对为代表,将原类簇中的样本点重新分属到新类簇

      5) util 类簇数 =K

缺点:

传统的层次聚类算法的效率比较低 O(tn2 ) t: 迭代次数 n: 样本点数,最明显的一个缺点是不具有再分配能力,即如果样本点 A 在某次迭代过程中已经划分给类簇 C1 ,那么在后面的迭代过程中 A 将永远属于类簇 C1 ,这将影响聚类结果的准确性。

改进:

一般情况下,层次聚类通常和划分式聚类算法组合,这样既可以解决算法效率的问题,又能解决样本点再分配的问题,在后面将介绍 BIRCH 算法。首先把邻近样本点划分到微簇 (microcluseters) 中,然后对这些微簇使用 K-means 算法。

----------------贴上本人实现的AGENES算法,大家有兴趣可以把DIANA算法自己实现下-------------- -

package com.agenes;

public class DataPoint {
    String dataPointName; // 样本点名
    Cluster cluster; // 样本点所属类簇
    private double dimensioin[]; // 样本点的维度

    public DataPoint(){

    }

    public DataPoint(double[] dimensioin,String dataPointName){
         this.dataPointName=dataPointName;
         this.dimensioin=dimensioin;
    }

    public double[] getDimensioin() {
        return dimensioin;
    }

    public void setDimensioin(double[] dimensioin) {
        this.dimensioin = dimensioin;
    }

    public Cluster getCluster() {
        return cluster;
    }

    public void setCluster(Cluster cluster) {
        this.cluster = cluster;
    }

    public String getDataPointName() {
        return dataPointName;
    }

    public void setDataPointName(String dataPointName) {
        this.dataPointName = dataPointName;
    }
}

package com.agenes;

import java.util.ArrayList;
import java.util.List;


public class Cluster {
    private List<DataPoint> dataPoints = new ArrayList<DataPoint>(); // 类簇中的样本点
    private String clusterName;

    public List<DataPoint> getDataPoints() {
        return dataPoints;
    }

    public void setDataPoints(List<DataPoint> dataPoints) {
        this.dataPoints = dataPoints;
    }

    public String getClusterName() {
        return clusterName;
    }

    public void setClusterName(String clusterName) {
        this.clusterName = clusterName;
    }

}

package com.agenes;

import java.util.ArrayList;
import java.util.List;


public class ClusterAnalysis {

 

  public List<Cluster> startAnalysis(List<DataPoint> dataPoints,int ClusterNum){
      List<Cluster> finalClusters=new ArrayList<Cluster>();
     
      List<Cluster> originalClusters=initialCluster(dataPoints);
      finalClusters=originalClusters;
      while(finalClusters.size()>ClusterNum){
          double min=Double.MAX_VALUE;
          int mergeIndexA=0;
          int mergeIndexB=0;
          for(int i=0;i<finalClusters.size();i++){
              for(int j=0;j<finalClusters.size();j++){
                  if(i!=j){
                      Cluster clusterA=finalClusters.get(i);
                      Cluster clusterB=finalClusters.get(j);

                      List<DataPoint> dataPointsA=clusterA.getDataPoints();
                      List<DataPoint> dataPointsB=clusterB.getDataPoints();

                      for(int m=0;m<dataPointsA.size();m++){
                          for(int n=0;n<dataPointsB.size();n++){
                              double tempDis=getDistance(dataPointsA.get(m),dataPointsB.get(n));
                              if(tempDis<min){
                                  min=tempDis;
                                  mergeIndexA=i;
                                  mergeIndexB=j;
                              }
                          }
                      }
                  }
              } //end for j
          }// end for i
          //合并cluster[mergeIndexA]和cluster[mergeIndexB]
          finalClusters=mergeCluster(finalClusters,mergeIndexA,mergeIndexB);
      }//end while

      return finalClusters;
   }

   private List<Cluster> mergeCluster(List<Cluster> clusters,int mergeIndexA,int mergeIndexB){
        if (mergeIndexA != mergeIndexB) {
            // 将cluster[mergeIndexB]中的DataPoint加入到 cluster[mergeIndexA]
            Cluster clusterA = clusters.get(mergeIndexA);
            Cluster clusterB = clusters.get(mergeIndexB);

            List<DataPoint> dpA = clusterA.getDataPoints();
            List<DataPoint> dpB = clusterB.getDataPoints();

            for (DataPoint dp : dpB) {
                DataPoint tempDp = new DataPoint();
                tempDp.setDataPointName(dp.getDataPointName());
                tempDp.setDimensioin(dp.getDimensioin());
                tempDp.setCluster(clusterA);
                dpA.add(tempDp);
            }

            clusterA.setDataPoints(dpA);

            // List<Cluster> clusters中移除cluster[mergeIndexB]
            clusters.remove(mergeIndexB);
        }

        return clusters;
   }

   // 初始化类簇
   private List<Cluster> initialCluster(List<DataPoint> dataPoints){
       List<Cluster> originalClusters=new ArrayList<Cluster>();
       for(int i=0;i<dataPoints.size();i++){
           DataPoint tempDataPoint=dataPoints.get(i);
           List<DataPoint> tempDataPoints=new ArrayList<DataPoint>();
           tempDataPoints.add(tempDataPoint);

           Cluster tempCluster=new Cluster();
           tempCluster.setClusterName("Cluster "+String.valueOf(i));
           tempCluster.setDataPoints(tempDataPoints);

           tempDataPoint.setCluster(tempCluster);
           originalClusters.add(tempCluster);
       }

       return originalClusters;
   }

   //计算两个样本点之间的欧几里得距离
   private double getDistance(DataPoint dpA,DataPoint dpB){
        double distance=0;
        double[] dimA = dpA.getDimensioin();
        double[] dimB = dpB.getDimensioin();

        if (dimA.length == dimB.length) {
            for (int i = 0; i < dimA.length; i++) {
                 double temp=Math.pow((dimA[i]-dimB[i]),2);
                 distance=distance+temp;
            }
            distance=Math.pow(distance, 0.5);
        }

       return distance;
   }

   public static void main(String[] args){
       ArrayList<DataPoint> dpoints = new ArrayList<DataPoint>();
      
       double[] a={2,3};
       double[] b={2,4};
       double[] c={1,4};
       double[] d={1,3};
       double[] e={2,2};
       double[] f={3,2};

       double[] g={8,7};
       double[] h={8,6};
       double[] i={7,7};
       double[] j={7,6};
       double[] k={8,5};

//       double[] l={100,2};//孤立点


       double[] m={8,20};
       double[] n={8,19};
       double[] o={7,18};
       double[] p={7,17};
       double[] q={8,20};

       dpoints.add(new DataPoint(a,"a"));
       dpoints.add(new DataPoint(b,"b"));
       dpoints.add(new DataPoint(c,"c"));
       dpoints.add(new DataPoint(d,"d"));
       dpoints.add(new DataPoint(e,"e"));
       dpoints.add(new DataPoint(f,"f"));

       dpoints.add(new DataPoint(g,"g"));
       dpoints.add(new DataPoint(h,"h"));
       dpoints.add(new DataPoint(i,"i"));
       dpoints.add(new DataPoint(j,"j"));
       dpoints.add(new DataPoint(k,"k"));

//       dataPoints.add(new DataPoint(l,"l"));

       dpoints.add(new DataPoint(m,"m"));
       dpoints.add(new DataPoint(n,"n"));
       dpoints.add(new DataPoint(o,"o"));
       dpoints.add(new DataPoint(p,"p"));
       dpoints.add(new DataPoint(q,"q"));

       int clusterNum=3; //类簇数

       ClusterAnalysis ca=new ClusterAnalysis();
       List<Cluster> clusters=ca.startAnalysis(dpoints, clusterNum);

       for(Cluster cl:clusters){
           System.out.println("------"+cl.getClusterName()+"------");
           List<DataPoint> tempDps=cl.getDataPoints();
           for(DataPoint tempdp:tempDps){
               System.out.println(tempdp.getDataPointName());
           }
       }

   }
}

分享到:
评论

相关推荐

    基于python实现的聚类分析,包含K均值聚类算法、层次聚类算法+源码(毕业设计&课程设计&项目开发)

    基于python实现的聚类分析,包含K均值聚类算法、层次聚类算法+源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于python实现的聚类分析,包含K均值聚类算法...

    层次聚类算法C++

    层次聚类算法是一种数据挖掘中的无监督学习方法,主要用于对数据进行分类或分组,而无需预先知道数据的标签或类别。在C++中实现层次聚类,通常涉及到多个步骤和核心概念,如距离计算、聚类合并和树状结构...

    层次聚类分析,层次聚类分析热图解读,matlab

    通过MATLAB提供的强大工具和算法,我们可以轻松地执行和解释层次聚类分析,为决策提供依据。 综上所述,层次聚类分析是一个多层次、多维度的数据分析方法,涉及多种距离计算策略。在MATLAB中,我们可以方便地实现...

    凝聚层次聚类的matlab代码.zip_层次聚类_层次聚类 MATLAB_层次聚类MATLAB_层次聚类算法_聚类

    本资源提供的是基于MATLAB实现的层次聚类算法,这是一套强大的工具,用于理解数据的内在结构。下面将详细阐述层次聚类的基本概念、MATLAB实现以及提供的文件内容。 层次聚类是一种自底向上的或自顶向下的方法,它...

    聚类分析算法常用数据集

    常见的聚类算法有K-means、层次聚类(包括凝聚型和分裂型)、DBSCAN(基于密度的聚类)、谱聚类以及模糊C均值(Fuzzy C-Means)等。这些算法各有优缺点,适用于不同的数据分布和应用场景。 1. K-means算法是最简单...

    层次聚类分析算法研究.docx

    本文围绕层次聚类分析算法展开研究,主要探讨了基于ART2神经网络的改进层次聚类算法的提出和应用。该算法首先采用基于ART2的改进神经网络聚类算法得到一个初始的聚类结果,在此基础上利用层次聚类算法实现分层聚类,...

    蚁群算法聚类分析

    在聚类分析中,蚁群算法可以用于寻找数据的最佳分组,从而实现数据的有效分类。 聚类分析是数据挖掘的一个重要领域,旨在根据数据的相似性或相异性将数据分组到不同的簇中。常见的聚类方法有层次聚类、K均值聚类等...

    实验二 聚类算法,聚类分析的算法,matlab源码.zip

    本实验主题为“实验二 聚类算法”,主要探讨聚类分析的算法,并提供了MATLAB实现的源码。MATLAB作为一种强大的科学计算环境,非常适合进行这种复杂的数据处理任务。 聚类算法可以分为层次聚类和非层次聚类两大类。...

    spass聚类分析与判别分析

    在SPSS中,常见的聚类算法包括系统聚类(如层次聚类)和分区聚类(如K-means聚类)。在进行聚类分析时,我们需要选择合适的距离度量(如欧氏距离、曼哈顿距离等)和凝聚方式(如单连接、全连接、平均连接等)。 1. ...

    聚类算法对同一个二维坐标数据集进行聚类分析

    本项目聚焦于四种常见的聚类算法:BIRCH(层次增量聚类)、K-Means、K-Means++以及K-Nearest Neighbors(KNN),对同一二维坐标数据集进行聚类分析。 首先,BIRCH(Balanced Iterative Reducing and Clustering ...

    聚类分析matlab_matlab聚类分析代码_分类_

    此外,除了K-means,MATLAB还支持其他聚类算法,如层次聚类(`linkage`函数)、DBSCAN(密度基聚类)等,它们各有优缺点,适用于不同的数据特性和应用场景。 总之,MATLAB的聚类分析功能强大且灵活,可以有效地处理...

    聚类分析常用数据集

    常见的聚类算法有K-means、层次聚类、DBSCAN等。在实际应用中,选择合适的聚类算法,优化参数设置,以及对结果的解释和验证,都是聚类分析的关键步骤。同时,对于高维数据,我们还需要考虑特征选择、降维等预处理...

    层次聚类_层次聚类MATLAB实现_

    层次聚类(Hierarchical Clustering)是一种数据挖掘技术,用于将数据集中的对象根据相似性或距离进行分组,形成一个层次结构。这种算法可以分为两种类型:凝聚型(Agglomerative)和分裂型(Divisive)。在这个...

    聚类算法聚类算法.docx聚类分析又称群分析,是研究(样品或指标)分类问题的一种统计分析方法

    一、聚类算法的基本概念 聚类分析又称群分析,是研究(样品或指标)分类问题的一种统计分析方法,同时也是数据挖掘的一个重要算法。聚类分析以相似性为基础,在一个聚类中的模式之间比不在同一聚类中的模式之间具有...

    面板数据的聚类分析及其应用_朱建平

    #### 四、面板数据的聚类分析方法 聚类分析的目标是将相似的对象聚集在一起,形成不同的群体。针对面板数据的特点,常用的聚类分析方法包括但不限于: 1. **层次聚类(Hierarchical Clustering)**:这是一种自底...

    聚类算法分析综述.

    聚类算法是数据挖掘中的重要技术之一,主要用于分析无类标的数据,将其按照某种相似性或相异性度量标准分成多个组(簇),从而发现数据的分布情况。该技术广泛应用于文本分析、数据分析、图像处理、市场预测等领域。...

    动态聚类数据分析算法(ISODATA)_动态聚类算法_聚类算法_动态聚类_动态聚类数据分析算法(ISODATA)_数据聚类_

    - **与层次聚类对比**:层次聚类通常需要生成树形结构,ISODATA则通过迭代实现类别调整,更适用于大数据集。 6. **实现与优化** 实现ISODATA算法时,可以采用不同的优化策略,如使用更高效的聚类中心更新方法、...

    聚类分析算法 聚类分析算法对高校学生成绩分析的应用研究.docx

    常见的聚类分析算法包括K-means、DBSCAN(密度基空间分割)和层次聚类。K-means算法是一种迭代方法,通过分配样本到最近的簇中心来不断调整簇的定义,直至簇不再变化。DBSCAN则侧重于发现基于密度的聚类,它可以识别...

Global site tag (gtag.js) - Google Analytics