不同肘法实施方式的比较

时间:2018-05-25 01:38:06

标签: python scikit-learn cluster-analysis k-means

我很困惑,因为我看到了不同的方法来实现肘部方法来识别Kmean中正确数量的聚类,并且它们产生的结果略有不同。

此处介绍了一种方法Sklearn kmeans equivalent of elbow method 并且正在使用kmeans_inertia_其他方法在此处进行了描述https://pythonprogramminglanguage.com/kmeans-elbow-method/ 并使用以下命令。

distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])  我想知道Kmeans_inertia_做了什么?并且都是正确的实现?

4 个答案:

答案 0 :(得分:1)

没有"正确"对于那些根本没有明确定义的东西。

肘法是一种非常粗略的启发式方法,我不知道任何正式的定义,也没有参考。

两种方法通常都会产生相同的k ...

但是通过k-means的概念,"正确"使用它的方法是平方误差,与欧几里德距离。因为k均值最小化平方误差,所以它不会使欧几里德距离最小化(试图证明这一点!你可以因为有反例)。

答案 1 :(得分:0)

阅读KMeans的文档后,您会发现变形和惯性都是每个点到其中心的距离之和。

答案 2 :(得分:0)

scikit-Learn User Guide on KMeansAndrew Ng's CS229 Lecture notes on k-means均表示,弯头方法使聚类点及其聚类质心之间的平方距离最小。 sklearn文档将其称为“惯性”,并指出它存在高维空间中欧几里德距离膨胀的缺点。 Ng将此称为“失真函数”的最小化。但是,可以发现examples定义的失真是与“惯性”相比,“距各个群集的群集中心的平方距离的平均值”(强调最小值)是平方距离的总和。尽管混淆并确认了这些术语的定义不一致,但这对我来说都是可行的。

答案 3 :(得分:0)

我发现很多使用这个公式的例子,声称他们计算了失真。但是在我的理解中似乎是错误的:

class NestedLookupDict(dict):
    def __init__(self, *args, **kwargs):
        super(type(self), self).__init__(*args, **kwargs)
        self.insert_missing_keys = True

    def check_keys(self, keys):
        if not isinstance(keys, (list, tuple)):
            raise TypeError("keys must be of type list or tuple")

    def get(self, keys, default=None):
        self.check_keys(keys)
        try:
            return self.__getitem__(keys)
        except KeyError:
            return default

    def __contains__(self, keys):
        self.check_keys(keys)
        if not keys: return True # nested_dict contains the key [] = itself
        if len(keys) > 1:
            return self.__getitem__(keys[:-1]).__contains__(keys[-1])
        else:
            return dict.__contains__(self, keys[0])

    def __delitem__(self, keys):
        self.check_keys(keys)
        obj = self
        for i in keys[:-1]:
            obj = dict.__getitem__(obj, i)
        dict.__delitem__(obj, keys[-1])

    def __getitem__(self, keys):
        self.check_keys(keys)
        # Get the super dictionary for easy lookup
        obj = self
        for i in keys:
            obj = dict.__getitem__(obj, i)
        return obj
    
    def __setitem__(self, keys, value):
        self.check_keys(keys)
        if not keys: raise ValueError("keys cannot be empty")
        # Get the base dictionary
        obj = self
        # Drill down until the penultimate key
        for i in keys[:-1]:
            # Insert a new dict if a key is missing
            if self.insert_missing_keys and not dict.__contains__(obj, i):
                dict.__setitem__(obj, i, dict())
            obj = dict.__getitem__(obj, i)
        # Set the value at the final key
        dict.__setitem__(obj, keys[-1], value)

如果要计算距离的平方和,应该是:

distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])