【问题标题】:Number of distinct clusters in KMeans is less than n_clusters?KMeans 中不同簇的数量小于 n_clusters?
【发布时间】:2020-06-17 15:15:57
【问题描述】:

我有一些食物图像存储在一个文件夹中。所有图像都没有标记,也没有存储在单独的文件夹中,例如“pasta”或“meat”。我目前的目标是将图像归类为多个类别,以便我以后可以评估同一类图像中描绘的食物的味道是否相似。

为此,我加载图像并以可输入 VGG16 进行特征提取的格式处理它们,然后将特征传递给我的 KMeans 以对图像进行聚类。我使用的代码是:

path = r'C:\Users\Hi\Documents\folder'
train_dir = os.path.join(path)
model = VGG16(weights='imagenet', include_top=False)
vgg16_feature_list = []
files = glob.glob(r'C:\Users\Hi\Documents\folder\*.jpg')
for i in enumerate(files):
    img = image.load_img(img_path,target_size=(224,224))
    img_data=image.img_to_array(img)
    img_data=np.expand_dims(img_data,axis=0)
    img_data=preprocess_input(img_data)

    vgg16_feature = model.predict(img_data)
    vgg16_feature_np = np.array(vgg16_feature)
    vgg16_feature_list.append(vgg16_feature_np.flatten())
vgg16_feature_list_np=np.array(vgg16_feature_list)
print(vgg16_feature_list_np.shape)
print(vgg16_feature_np.shape)

kmeans = KMeans(n_clusters=3, random_state=0).fit(vgg16_feature_list_np)
print(kmeans.labels_)

问题是我收到以下警告:

ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (3). Possibly due to duplicate points in X. 

我该如何解决这个问题?

【问题讨论】:

  • 这能回答你的问题吗? SKLearn KMeans Convergence Warning
  • @xiawi 我在回答之前在我的搜索中看到了这个,但答案来自纯粹的编码方面(如何抑制警告本身),并且没有提供任何实际的补救措施,所以这就是为什么我继续自己提供一个(不同的)答案。
  • 什么是“我的 KMeans”?你写了那个代码?它在某个标准库中吗?请相应地查看minimal reproducible exampleedit 您的问题。我希望 Python 代码以一些 import 语句开头。

标签: python machine-learning computer-vision k-means vgg-net


【解决方案1】:

这是其中一种情况,尽管从编程的角度来看您的代码很好,但由于与 ML 相关的问题,它不会产生令人满意的结果(数据、模型或两者兼有),因此“调试”相当困难(我引用这个词,因为这不是典型的调试过程,因为代码本身运行良好)。

首先,这种情况似乎意味着您的特征没有足够的多样性来证明 3 个不同的集群是合理的。而且,如果我们仍然处于 K-means 环境中,那么您无能为力;在几个可用的选项中(有关各个参数的详细信息,请参阅documentation):

  • 增加迭代次数max_iter(默认300)
  • 增加不同质心初始化的数量n_init(默认10)
  • init 参数更改为random(默认为k-means++),或者更好的是,提供一个包含来自每个目标集群的样本的三元素数组(如果您已经知道这些集群实际上可能在您的数据中)
  • 使用不同的random_state 值运行模型
  • 结合以上内容

如果上述方法均无效,则很可能意味着 K-means 实际上不适用于此处,您可能需要寻找替代方法(这些方法超出了本主题的范围)。事实是,正如下面评论中正确指出的那样,K-means 通常不适用于如此高维的数据。

【讨论】:

  • 这是一个很好的答案。捎带,KMeans不喜欢这么高维的数据,你应该先用UMAP做降维
  • @SamH。谢谢,你确实是正确的(更新答案以反映这一点)
【解决方案2】:
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    cluster_data(data_arr)

您可以使用此功能删除警告。 由于 sklearn 使用警告模块来删除警告。

【讨论】:

    猜你喜欢
    • 2014-05-09
    • 2019-11-06
    • 1970-01-01
    • 2017-03-25
    • 2020-01-20
    • 2014-02-20
    • 2015-03-29
    • 2014-01-01
    • 2020-10-29
    相关资源
    最近更新 更多