Кластеризация изображений на основе тегов - PullRequest
1 голос
/ 21 октября 2019

Я пометил много изображений объектов, используя Google Vision API. Используя эти метки (список в pickle здесь ), я создал матрицу совместного использования меток (скачать в виде массива здесь ). Размер матрицы составляет 2195x2195.

Загрузка данных:

import pickle
import numpy as np
with open('labels.pkl', 'rb') as f:
    labels = pickle.load(f)

cooccurrence = np.load('cooccurrence.npy')

Я хотел бы использовать кластерный анализ для определения разумного количества кластеров (определенных как списки меток Vision), которые быпредставлять некоторые объекты (например, автомобили, обувь, книги, ....). Я не знаю, каково правильное количество кластеров.

Я попробовал алгоритм иерархической кластеризации, доступный в 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 и Модели гауссовой смеси , но я не придумал лучшего выхода.

1 Ответ

1 голос
/ 27 октября 2019

Методы кластеризации, такие как AgglomerativeClustering sklearn, требуют матрицу данных в качестве входных данных. С metric="precomputed" вы также можете использовать матрицу расстояний ( it для моделирования k-средних и гауссовой смеси, для этого нужны данные координат).

Однако вы, имеют происхождение или матрицу simarity . Эти значения имеют противоположное значение, поэтому вам нужно определить соответствующее преобразование (например, вхождения-случайности). Обработка матрицы совпадений как матрицы данных (а затем использование евклидова расстояния - это то, что вы делаете) работает в некоторой степени, но имеет очень странную семантику и не рекомендуется.

...