我正在尝试根据句子之间的相似性对句子进行聚类。我使用 ELMo 生成句子的嵌入(它为每个单词生成嵌入,然后我将所有这些求和除以单词数)。
我最初尝试将这些数据与 tsne 相匹配,使用 ELMo 生成的嵌入(512 维),我能够形成簇,但这里的问题是,在 tsne 中,必须减小维数,以使其最多可容纳 3 个维。因此输出并不那么准确。 然后我尝试使用 DBSCAN ,我没有看到输入的尺寸有任何限制(如果我错了,请纠正我)。
现在,我对绘制 DBSCAN 所做的预测感到震惊。另外,当我尝试打印预测的标签时,所有标签都是“-1”。 有没有其他方法可以对句子进行聚类,或者如何有效地利用 512 维嵌入来使用 tsne 或 dbscan 对句子进行聚类?
def tsnescatterplot(sentences):
arr = np.empty((0, 512), dtype='f')
word_labels = []
for sentence in sentences:
wrd_vector = get_elmo_embeddings(sentence)
print(sentence)
word_labels.append(sentence)
arr = np.append(arr, np.array([wrd_vector]), axis=0)
print('Printing array')
print(arr)
# find tsne coords for 2 dimensions
tsne = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
Y = tsne.fit_transform(arr)
x_coords = Y[:, 0]
y_coords = Y[:, 1]
# display scatter plot
plt.scatter(x_coords, y_coords)
for label, x, y in zip(word_labels, x_coords, y_coords):
plt.annotate(label, xy=(x, y), xytext=(0, 0), textcoords='offset points')
plt.xlim(x_coords.min() + 0.5, x_coords.max() + 0.5)
plt.ylim(y_coords.min() + 0.5, y_coords.max() + 0.5)
plt.show()
def dbscan_scatterplot(sentences):
arr = np.empty((0, 512), dtype='f')
for sentence in sentences:
wrd_vector = get_elmo_embeddings(sentence)
arr = np.append(arr, np.array([wrd_vector]), axis=0)
dbscan = DBSCAN()
np.set_printoptions(suppress=True)
Y = dbscan.fit(arr)
最佳答案
为 DBSCAN 选择参数非常重要。
sklearn 提供默认值(这里反复出现问题种子)是愚蠢的 - 因为这些默认值除了低维玩具数据之外不起作用。相反,他们应该要求用户指定该值。
您将需要适当选择特定的epsilon。但对于高维数据来说,选择这个好点会很困难。你会发现结果突然从全-1(没有聚类)变成全0(所有都相连),并且选择一个好的值很困难。您需要探索文献中的一些启发式方法。
最后但并非最不重要的一点是,平均词向量往往会产生糟糕的结果。因为它们都朝着均值的方向发展。较长的文档更接近均值,较短的文档则更远离均值。但这并不是您想要的聚类结果...这种额外的失真可能足以破坏您之前拥有的任何信号。
关于python - 如何根据句子相似度对句子进行聚类和绘图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53869535/