用于在 KMeans 聚类中选择适当数量的聚类的轮廓索引

Posted

技术标签:

【中文标题】用于在 KMeans 聚类中选择适当数量的聚类的轮廓索引【英文标题】:Silhouette Index for selecting a proper number of clusters in KMeans clustering 【发布时间】:2014-02-02 07:11:32 【问题描述】:

我正在使用轮廓索引在 KMeans 聚类中选择适当数量的聚类。剪影索引的代码为here。 基于此代码,我创建了自己的代码(见下文)。问题在于,对于任何数据集,首选的聚类数始终等于最大值,即在本例中为 15。 我的代码有错误吗?

private double getSilhouetteIndex(double[][] distanceMatrix,ClusterEvaluation ceval)

    double si_index = 0;
    double[] ca = ceval.getClusterAssignments();
    double[] d_arr = new double[ca.length];
    List<Double> si_indexes = new ArrayList<Double>();

    for (int i=0; i<ca.length; i++)
    
        // STEP 1. Compute the average distance between the i-th point and all other points of a given cluster
        double a = averageDist(distanceMatrix,ca,i,1);

        // STEP 2. Compute the average distance between the i-th point and all points of other clusters
        for (int j=0; j<ca.length; j++)
        
            double d = averageDist(distanceMatrix,ca,j,2);
            d_arr[j] = d;
        

        // STEP 3. Compute the the distance from the i-th point to the nearest cluster to which it does not belong
        double b = d_arr[0];
        for (Double _d : d_arr)
        
            if (_d < b)
                b = _d;
        

        // STEP 4. Compute the Silhouette index for the i-th point
        double si = (b - a)/Math.max(a,b);

        si_indexes.add(si);
    

    // STEP 5. Compute the average index over all observations
    double sum = 0;
    for(Double _si : si_indexes)
    
         sum += _si;
    
    si_index = sum/si_indexes.size();

    return si_index;


private double averageDist(double[][] distanceMatrix, double[] ca, int id, int calc)
       
    double avgDist = 0;
    double sum = 0;
    int len = 0;

    // Distances inside the cluster
    if (calc == 1)
    
        for (int i = 0; i<ca.length; i++)
        
            if (ca[i] == ca[id] && i != id)
            
                sum += distanceMatrix[id][i];
                len++;
            
        
    
    // Distances outside the cluster
    else
    
        for (int i = 0; i<ca.length; i++)
        
            if (ca[i] != ca[id] && i != id)
            
                sum += distanceMatrix[id][i];
                len++;
            
        
    

    avgDist = sum/len;

    return avgDist;

【问题讨论】:

【参考方案1】:

对于剪影指数,据我所知,当您计算集群外点的平均距离时,它实际上应该是the points from the nearest neighbor cluster,而不是集群外的所有点。

【讨论】:

什么定义了“最近邻集群”?它是最接近质心、最接近质心的数据向量还是两个最近的边界向量? ORIGINAL 代码在所有集群中搜索最近的边界向量,因此逻辑似乎是正确的。

以上是关于用于在 KMeans 聚类中选择适当数量的聚类的轮廓索引的主要内容,如果未能解决你的问题,请参考以下文章

Kmeans聚类算法简介(有点枯燥)

聚类算法 - kmeans

Kmeans聚类算法简介

kmeans聚类结果不稳定咋办

如何使用 KMEANS 计算每个记录的聚类距离?

spark机器学习-聚类