Я выполняю иерархическую кластеризацию для модели Doc2Vec, насчитывающей около 15 000 документов с 90 измерениями.
Хотя использование функции SciPy fcluster для получения плоского кластера несколько полезно, в некоторых кластерах используется слишком мало членов (>1% документов) или слишком много (<45%) для информативности из-за значительного расхождения между размерами кластеров на одном и том же уровне расстояния. </p>
Вот пример того, как мои данные выглядят с усеченной дендрограммойсодержит первые 100 связей:
(обратите внимание на значительное расхождение между размерами кластеров на разных листьях на оси x)
Мой код для создания этой дендрограммы и получения плоских кластеров следующий:
dm = pdist(X, 'cosine') # X is the array containing doc vectors
method = 'average'
Z = linkage(dm, method=method, metric='cosine', optimal_ordering=False)
def fancy_dendrogram(*args, **kwargs):
max_d = kwargs.pop('max_d', None)
if max_d and 'color_threshold' not in kwargs:
kwargs['color_threshold'] = max_d
annotate_above = kwargs.pop('annotate_above', 0)
ddata = dendrogram(*args, **kwargs)
if not kwargs.get('no_plot', False):
plt.title('Truncated Hierarchical Clustering Dendrogram (method = %s)'%method)
plt.xlabel('sample index or (cluster size)')
plt.ylabel('distance')
for i, d, c in zip(ddata['icoord'], ddata['dcoord'], ddata['color_list']):
x = 0.5 * sum(i[1:3])
y = d[1]
if y > annotate_above:
plt.plot(x, y, 'o', c=c)
plt.annotate("%.3g" % y, (x, y), xytext=(0, -5),
textcoords='offset points',
va='top', ha='center')
if max_d:
plt.axhline(y=max_d, c='k')
return ddata
fancy_dendrogram(
Z,
color_threshold=0.94,
truncate_mode='lastp',
p=100,
leaf_rotation=90.,
leaf_font_size=12.,
show_contracted=True,
annotate_above=0, # useful in small plots so annotations don't overlap
max_d=None
)
plt.show()
print(colored("\n Choose your method for flat cluster retrieval.\n", "green"))
method = input(colored("Number or distance? "))
if method == "number":
k = input("Enter the number of clusters to retrieve: ")
cluster = fcluster(Z, k, criterion='maxclust')
if method == "distance":
max_d = input("Enter the distance cutoff: ")
cluster = fcluster(Z, max_d, criterion='distance')
Что я хотел бы сделать, так это пройтись по листьям дендрограммы и остановиться, чтобы получить кластеры, которые имеют менее n членов (например, 30% корпуса) и более m членов (например, 5% корпуса), так что каждыйкластер имеет размер, который лучше интерпретируется человеком.
Как я могу это сделать?Любые указатели будут с благодарностью.