【发布时间】:2020-02-17 16:28:30
【问题描述】:
我使用 Google Vision API 标记了许多对象图像。使用这些标签(pickle here 中的列表),我创建了一个标签共现矩阵(下载为 numpy 数组 here)。矩阵大小为 2195x2195。
加载数据:
import pickle
import numpy as np
with open('labels.pkl', 'rb') as f:
labels = pickle.load(f)
cooccurrence = np.load('cooccurrence.npy')
我想使用聚类分析来定义合理数量的聚类(定义为视觉标签列表),这些聚类代表一些对象(例如汽车、鞋子、书籍……)。我不知道什么是正确的集群数量。
我尝试了 scikit-learn 中可用的层次聚类算法:
import pandas as pd
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_colwidth', 1000)
#creating non-symetrical "similarity" matrix:
occurrences = cooccurrence.diagonal().copy()
similarities = cooccurrence / occurrences[:,None]
#clustering:
from sklearn.cluster import AgglomerativeClustering
clusters = AgglomerativeClustering(n_clusters=200, affinity='euclidean', linkage='ward').fit_predict(similarities)
#results in pandas:
df_clusters = pd.DataFrame({'cluster': clusters.tolist(), 'label': labels})
df_clusters_grouped = df_clusters.groupby(['cluster']).agg({'label': [len, list]})
df_clusters_grouped.columns = [' '.join(col).strip() for col in df_clusters_grouped.columns.values]
df_clusters_grouped.rename(columns = {'label len': 'cluster_size', 'label list': 'cluster_labels'}, inplace=True)
df_clusters_grouped.sort_values(by=['cluster_size'], ascending=False)
像这样,我能够创建 200 个集群,其中一个看起来像:
["Racket", "Racquet sport", "Tennis racket", "Rackets", "Tennis", "Racketlon", "Tennis racket accessory", "Strings"]
这在某种程度上可行,但我宁愿使用一些能够将一个标签分配给多个集群的软聚类方法(例如,“皮革”可能对鞋子和钱包有意义)。此外,我必须定义集群的数量(在我的示例代码中为 200),这是我宁愿得到的结果(如果可能的话)。
我也在玩hdbscan、k-clique 和Gaussian mixture models,但我没有想出更好的输出。
【问题讨论】:
标签: python graph cluster-analysis similarity google-vision