合并 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]})
我想出了一个更好的方法。
我的直觉是因为我们在比较余弦相似度,如果 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()
我有一个句子列表,我想找到所有与它相似的句子,并将它们放在一个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]})
我想出了一个更好的方法。
我的直觉是因为我们在比较余弦相似度,如果 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()