Python KMeans中的不同群集数小于n_群集数?

Python KMeans中的不同群集数小于n_群集数?,python,machine-learning,computer-vision,k-means,vgg-net,Python,Machine Learning,Computer Vision,K Means,Vgg Net,我有一些食物图像存储在一个文件夹中。所有图像均未标记,也未存储在单独的文件夹中,如“意大利面”或“肉”。我目前的目标是将图像分为多个类别,以便稍后我可以评估同一组图像中描述的食物味道是否相似 为此,我加载图像并以一种可以输入VGG16进行特征提取的格式对其进行处理,然后将特征传递给我的KMeans以对图像进行聚类。我使用的代码是: path = r'C:\Users\Hi\Documents\folder' train_dir = os.path.join(path) model = VGG16

我有一些食物图像存储在一个文件夹中。所有图像均未标记,也未存储在单独的文件夹中,如“意大利面”或“肉”。我目前的目标是将图像分为多个类别,以便稍后我可以评估同一组图像中描述的食物味道是否相似

为此,我加载图像并以一种可以输入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. 

如何解决这一问题?

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

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

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

如果上述任何一项都不起作用,那么很可能意味着K-means在这里实际上不适用,您可能需要寻找替代方法(不在本线程的范围内)。事实是,正如下面评论中正确指出的,K-means通常不能很好地处理如此高维的数据。

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

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    cluster_data(data_arr)
首先,这种情况似乎意味着你的特征没有足够的多样性来证明3个不同的聚类是合理的。而且,如果我们仍然处于K-means的环境中,你也没有什么可以做的;在几个可用的选项中(有关各自参数的详细信息,请参阅):

  • 增加迭代次数
    max\u iter
    (默认值300)
  • 增加不同质心初始化的数量
    n_init
    (默认值10)
  • init
    参数更改为
    random
    (默认值为
    k-means++
    ),或者,更好的是,提供一个3元素数组,其中包含每个目标集群中的一个样本(如果您已经知道这些集群实际上可能在您的数据中)
  • 使用不同的
    random_state
    值运行模型
  • 结合以上内容
如果上述任何一项都不起作用,那么很可能意味着K-means实际上不适用于这里,您可能需要寻找替代方法(不在本线程的范围内)。事实是,正如下面评论中正确指出的那样,K-means通常不能很好地处理如此高维的数据

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    cluster_data(data_arr)
您可以使用此功能删除警告。 Assklearn使用警告模块删除警告

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

这是否回答了您的问题?@xiawi我在回答之前的搜索中看到了这一点,但答案是从纯编码的角度(如何抑制警告本身)得出的,并且没有提供任何实际的补救措施,因此我开始自己提供(不同的)答案。答案是什么“我的KMeans”?你写了那段代码吗?它是在某个标准库中吗?请查看并回答相应的问题。我希望Python代码以一些
import
语句开始。这是否回答了你的问题?@xiawi我在回答之前的搜索中看到了这一点,但答案来自纯粹的编码方面(如何抑制警告本身),而不提供任何实际的补救措施,这就是为什么我开始自己给出一个(不同的)答案。“我的KMeans”是什么?您编写了该代码吗?它是否存在于某个标准库中?请参阅并回答相应的问题。我希望Python代码以一些
import
语句开始。这是一个很好的答案。要实现这一点,KMeans不喜欢如此高维的数据,您应该首先使用UMAP并进行维化reduction@SamH.谢谢你确实正确(更新的答案反映了这一点)这是一个很好的答案。要附带说明,KMeans不喜欢这样高维的数据,您应该首先使用UMAP并进行维化reduction@SamH.谢谢,你确实是对的(更新的答案反映了这一点)