1.什么是 SentenceTransformer?
SentenceTransformer 是一个 Python 框架,用于将句子、文本或图像编码为嵌入向量(Embedding)。这些嵌入向量可以用于文本相似度计算、语义搜索等 NLP 任务,并支持 100 多种语言。
这个框架基于 PyTorch 和 Transformer,并提供大量预训练模型。你也可以微调自己的模型,实现定制化。
使用 SentenceTransformer 处理中文文本,编码句子并计算语义相似度的流程会在下文中详细解读。
首先,在讨论表示完整句子之前,我们先讨论将单个实体表示为向量的概念。下图中,有五个实体:国王、王后、王子、公主和狗。这些实体具有相似的含义,因此在向量空间中彼此靠近。国王与王后和王子的距离比与公主的距离更近,同样,王后与公主和国王的距离比与王子的距离更近。狗这个词与其他四个词几乎没有共同之处,因此它与其他四个词的距离很远。
这一概念可以进一步应用于完整句子甚至文本主体,这是 SentenceTransformers 的作者在他们的论文“ Sentence-BERT:使用 Siamese BERT-Networks 进行句子嵌入”中以有效的方式实现的。我们将使用的模型可以计算包含最多 256 个标记的文本主体的向量表示,其中每个标记通常是一个单词、子单词或特殊符号。因此,这使我们能够计算包含大约 1-2 个段落的文本主体之间的语义相似度。
2.环境设置
2.1.pip安装
transformers
2.2.conda安装(虚拟环境)
conda install -c conda-forge sentence-transformers
3.余弦相似度计算
余弦相似度常用于计算两个向量之间的相似度。两个向量的夹角越小,相似度越高。计算公式如下:
余弦值越接近 1,表示两个句子的语义越相似;值接近 0,则表示两者不相似。
而a,b,c 是三个边的长度
在NLP计算中,常用来计算词语的相似度,因为词,或者文本表示成分布式向量之后,可以很方便的计算他们的余弦相似度来评估他们的语义相似性。可以表示为
4.简单代码实现
使用 SciPy 和 sklearn 计算向量相似度
# 在scipy库中计算
from scipy.spatial.distance import cosine
import numpy as np
a=np.array([1,2,3])
b=np.array([2,2,3])
print(1-cosine(a,b))#cosin() 中参数可以直接是 list
# 在sklearn库中计算矩阵
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
a=np.array([1,2,3]).reshape(1,3)#[[1 2 3]]
b=np.array([2,2,3]).reshape(1,3)#[[2 2 3]]
c=cosine_similarity(a,b)
print('相似度结果为 : ',c)
a=np.arange(15).reshape(3,5)
b=np.arange(20).reshape(4,5)
print(a)
print(b)
c=cosine_similarity(a,b) #第一行的值是a中的每第一个行向量与b中每一个行向量之间的余弦相似度
d=cosine_similarity(a)# a 中的行向量之间的两两余弦相似度
print('c : ',c,'d : ',d)
结果如下
5.句子向量化英文示例
from sentence_transformers import SentenceTransformer
# Download model
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
# The sentences we'd like to encode
sentences = ['Python is an interpreted high-level general-purpose programming language.',
'Python is dynamically-typed and garbage-collected.',
'The quick brown fox jumps over the lazy dog.']
# Get embeddings of sentences
embeddings = model.encode(sentences)
# Print the embeddings
for sentence, embedding in zip(sentences, embeddings):
print("Sentence:", sentence)
print("Embedding:", embedding)
print("")
对句子进行编码,结果如下
也可更改为以下预训练模型
6.中文语义相似度示例
下面是一个完整的示例代码,包括加载适合中文的预训练模型、对句子进行编码,并计算语义相似度
#pip install -U sentence-transformers
from sentence_transformers import SentenceTransformer, util
# 1. 加载适用于中文的模型
model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
# 2. 准备要比较的句子
sentence1 = "我喜欢看电影"
sentence2 = "我热爱看电影"
# 3. 对句子进行编码
embedding1 = model.encode(sentence1, convert_to_tensor=True)
embedding2 = model.encode(sentence2, convert_to_tensor=True)
# 4. 计算语义相似度(使用余弦相似度)
similarity = util.cos_sim(embedding1, embedding2)
# 5. 输出结果
print(f"句子1: {sentence1}")
print(f"句子2: {sentence2}")
print(f"语义相似度: {similarity.item():.4f}")
结果如下
7.计算语义相似度
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer('all-MiniLM-L6-v2')
# 文本列表
sentences = ['The cat sits outside',
'A man is playing guitar',
'I love pasta',
'The new movie is awesome',
'The cat plays in the garden']
# 计算embeddings
embeddings = model.encode(sentences, convert_to_tensor=True)
# 计算不同文本之间的相似度
cosine_scores = util.cos_sim(embeddings, embeddings)
# 保存结果
pairs = []
for i in range(len(cosine_scores)-1):
for j in range(i+1, len(cosine_scores)):
pairs.append({'index': [i, j], 'score': cosine_scores[i][j]})
# 按照相似度分数进行排序打印
pairs = sorted(pairs, key=lambda x: x['score'], reverse=True)
for pair in pairs:
i, j = pair['index']
print("{:<30} \t\t {:<30} \t\t Score: {:.4f}".format(sentences[i], sentences[j], pair['score']))
结果如下
8.总结
SentenceTransformer 可以快速实现句子或文本的嵌入,并轻松计算语义相似度。
支持多语言,并提供大量预训练模型,可以根据需求选择或微调。
余弦相似度是常用的衡量向量相似度的方法,特别适用于 NLP 任务。
想了解更多内容? 在小程序搜索🔍 AI Pulse,
获取最新的 AI 资讯和教程。