合并 N*N 矩阵中的相似元素,不重复

Combine similar elements in N*N matrix without duplicates

我有一个句子列表,我想找到所有与它相似的句子,并将它们放在一个list/tuple中。

我为它们形成了句子嵌入,然后为 N 个句子计算了一个 N*N 余弦相似度矩阵。然后我遍历元素,并选择高于阈值的元素。

如果sentences[x]类似于sentences[y]sentences[z],如果我结合sentences[x]sentences[y]sentences[x]不应该结合sentences[z] 随着循环进一步迭代

我的直觉是,既然我们在比较余弦相似度,如果 X 与 Y 相似,Y 与 Z 相似,那么 X 也将与 Z 相似,所以我不必担心.我的目标是不重复,但我卡住了。

有没有更好的方法/最好的方法是什么?

这是我的代码:

import pandas as pd
from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim, pytorch_cos_sim

embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
threshold = 0.75

def form_embeddings(sentences, embedding_model=embedding_model):

    if isinstance(sentences, str):
        sentences = [sentences]

    return embedding_model.encode(sentences, convert_to_tensor=True)

df = pd.read_csv('sample_file.csv')
sentences = df['sentences'].tolist()

#form embeddings
sentence_embeddings = form_embeddings(sentences=sentences)

#form similarity matrix
sim_matrix = pytorch_cos_sim(sentence_embeddings, sentence_embeddings)

#set similarity with itself as zero
sim_matrix.fill_diagonal_(0)

#iterate through and find pairs of similarity
pairs = []
for i in range(len(sentences)):
    for j in range(i, len(sentences)):
        if sim_matrix[i,j] >= threshold:
            pairs.append({'index':[i,j], 'score': sim_matrix[i,j], 'original_sentence':sentences[i], 'similar_sentence':sentences[j]})

我想出了一个更好的方法。

这由fast clustering implementation解决。

我的直觉是因为我们在比较余弦相似度,如果 X 与 Y 相似,Y 与 Z 相似,那么 X 也将与 Z 相似

Sentence embeddings通常维度很高(比如768),对我来说就像一个黑匣子,要找出不同维度的信息。因此,即使 sent[x] 与 sent[y] 相似,sent[y] 与 sent[z] 相似,我们也不能自信地推断 sent[x] 和 sent[z] 也应该合并,因为你不知道每个维度如何影响它们的相似性。

如果你想获得non-duplicate个句子对,你可以尝试itertools.combinations()