如何基于句子相似度对句子进行聚类和绘制?

时间:2018-12-20 13:17:34

标签: python machine-learning scikit-learn artificial-intelligence dbscan

我正在尝试根据句子之间的相似性对句子进行聚类。我正在使用ELMo生成句子的嵌入(它为每个单词生成嵌入,然后将所有这些单词相加并除以单词数)。

我最初尝试使用tsne来拟合此数据,并使用ELMo(512维)生成的嵌入来形成簇,但是这里的问题是,在tsne中必须减小维的大小最多可容纳3个尺寸。因此,输出不是那么准确。 然后,我尝试使用DBSCAN,在该输入中,输入的尺寸没有任何限制(如果输入错误,请更正)。

现在,我对绘制DBSCAN所做的预测感到震惊。另外,当我尝试打印预测的标签时,所有标签均为“ -1”。 还有其他方法可以使句子聚类吗?如何在tsne或dbscan聚类句子时有效利用512维嵌入?

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)

1 个答案:

答案 0 :(得分:1)

选择DBSCAN的参数非常重要。

它提供默认值对 sklearn (以及此处反复出现的问题种子)很愚蠢,因为这些值仅适用于低维玩具数据。相反,它们应该要求用户指定值。

需要适当地选择特定的ε。但是很难为高维数据选择合适的位置。您会发现结果突然从所有-1(没有聚集)到所有0(所有连接),并且很难选择一个好的值。您需要探索文学中的一些启发式方法。

最后但并非最不重要的是,平均词向量往往会产生相当糟糕的结果。因为它们都朝着卑鄙的方向发展。较长的文档更接近均值,而较短的文档则更远离平均值。但这不是聚类所需要的……这种额外的失真可能足以破坏您以前拥有的任何信号。