【问题标题】:Estimation of number of Clusters via gap statistics and prediction strength通过间隙统计和预测强度估计集群数量
【发布时间】:2014-01-26 23:18:15
【问题描述】:

我正在尝试将差距统计和预测强度http://edchedch.wordpress.com/2011/03/19/counting-clusters/ 的 R 实现转换为 python 脚本,以估计具有 3 个集群的 iris 数据中的集群数量。我没有得到 3 个集群,而是在不同的运行中得到了不同的结果,几乎没有估计 3 个(实际集群数)。 Graph 显示估计数字是 10 而不是 3。我错过了什么吗?谁能帮我定位问题?

import random
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans


def dispersion (data, k):
    if k == 1:
        cluster_mean = np.mean(data, axis=0)
        distances_from_mean = np.sum((data - cluster_mean)**2,axis=1)
        dispersion_val = np.log(sum(distances_from_mean))
    else:
        k_means_model_ = KMeans(n_clusters=k, max_iter=50, n_init=5).fit(data)
        distances_from_mean = range(k)
        for i in range(k):
            distances_from_mean[i] = int()
            for idx, label in enumerate(k_means_model_.labels_):
                if i == label:
                    distances_from_mean[i] += sum((data[idx] - k_means_model_.cluster_centers_[i])**2)
        dispersion_val = np.log(sum(distances_from_mean))

    return dispersion_val

def reference_dispersion(data, num_clusters, num_reference_bootstraps):
    dispersions = [dispersion(generate_uniform_points(data), num_clusters) for i in range(num_reference_bootstraps)]
    mean_dispersion = np.mean(dispersions)
    stddev_dispersion = float(np.std(dispersions)) / np.sqrt(1. + 1. / num_reference_bootstraps) 
    return mean_dispersion

def generate_uniform_points(data):
    mins = np.argmin(data, axis=0)
    maxs = np.argmax(data, axis=0)

    num_dimensions = data.shape[1]
    num_datapoints = data.shape[0]

    reference_data_set = np.zeros((num_datapoints,num_dimensions))
    for i in range(num_datapoints):
        for j in range(num_dimensions):
            reference_data_set[i][j] = random.uniform(data[mins[j]][j],data[maxs[j]][j])

    return reference_data_set   

def gap_statistic (data, nthCluster, referenceDatasets):
    actual_dispersion = dispersion(data, nthCluster)
    ref_dispersion = reference_dispersion(data, nthCluster, num_reference_bootstraps)
    return actual_dispersion, ref_dispersion

if __name__ == "__main__":

    data=np.loadtxt('iris.mat', delimiter=',', dtype=float)

    maxClusters = 10
    num_reference_bootstraps = 10
    dispersion_values = np.zeros((maxClusters,2))

    for cluster in range(1, maxClusters+1):
        dispersion_values_actual,dispersion_values_reference = gap_statistic(data, cluster, num_reference_bootstraps)
        dispersion_values[cluster-1][0] = dispersion_values_actual
        dispersion_values[cluster-1][1] = dispersion_values_reference

    gaps = dispersion_values[:,1] - dispersion_values[:,0]

    print gaps
    print "The estimated number of clusters is ", range(maxClusters)[np.argmax(gaps)]+1

    plt.plot(range(len(gaps)), gaps)
    plt.show()

【问题讨论】:

  • 我什至对我的数据进行了差距统计的 r 实现。随着我增加最大聚类数,估计的聚类数也会增加。
  • 您是如何获得 0 个集群的结果的?此外,不幸的是,鸢尾花数据是真实数据,许多此类“研究”仅在合成数据集上得到验证;所以我并不惊讶它实际上不起作用。
  • 0 只是一个数组索引,代表 k=1。我也翻译了预测强度。这在虹膜数据上给出了很好的结果。我想 r 实现中存在一些我无法计算的错误。估计的 k 如何取决于最大簇数。当我尝试 max cluster = 20 时,它估计 k=19。
  • 你可以参考这个:datasciencelab.wordpress.com/2013/12/27/…。此外,您的stddev_dispersion 没有在任何地方使用。
  • 你整理好了吗?每次不同的预测是由于random_state 参数为 None (这导致使用 np.random)。如果您想获得持久的结果,您应该执行KMeans(n_clusters=k, max_iter=50, n_init=5, random_state=1234) 之类的操作

标签: python r cluster-analysis k-means


【解决方案1】:

您的图表显示正确的值 3。让我解释一下

  • 随着集群数量的增加,距离指标肯定会降低。因此,您假设正确的值为 10。如果将其增加到 10 以上,距离度量将进一步减小。但这不应该是我们的决策标准
  • 我们需要找到拐点(这里用红色标记)。这是斜率平滑的点。你可能想看看elbow curves
  • 基于以上2点,拐点为3(这也是正确解)

希望对你有帮助

【讨论】:

    【解决方案2】:

    你可以看看这段代码,你可以改变你的输出绘图格式

    [![# coding: utf-8
    
    # Implémentation de K-means clustering python
    
    
    #Chargement des bibliothèques
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    from sklearn import datasets
    
    
    #chargement de jeu des données Iris
    iris = datasets.load_iris()
    
    #importer le jeu de données Iris dataset à l'aide du module pandas
    x = pd.DataFrame(iris.data)
    
    x.columns = \['Sepal_Length','Sepal_width','Petal_Length','Petal_width'\]
    
    
    y = pd.DataFrame(iris.target)
    
    
    y.columns = \['Targets'\]
    
    
    #Création d'un objet K-Means avec un regroupement en 3 clusters (groupes)
    model=KMeans(n_clusters=3)
    
    
    
    #application du modèle sur notre jeu de données Iris
    model.fit(x)
    
    
    
    #Visualisation des clusters
    plt.scatter(x.Petal_Length, x.Petal_width)
    plt.show()
    
    
    
    
    colormap=np.array(\['Red','green','blue'\])
    
    
    
    #Visualisation du jeu de données sans altération de ce dernier (affichage des fleurs selon leur étiquettes)
    plt.scatter(x.Petal_Length, x.Petal_width,c=colormap\[y.Targets\],s=40)
    plt.title('Classification réelle')
    plt.show()
    
    #Visualisation des clusters formés par K-Means
    plt.scatter(x.Petal_Length, x.Petal_width,c=colormap\[model.labels_\],s=40)
    plt.title('Classification K-means ')
    plt.show()][1]][1]
    

    Output 1

    【讨论】:

      猜你喜欢
      • 2018-08-29
      • 2017-06-07
      • 2010-12-25
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      相关资源
      最近更新 更多