跳转至

如何使用 BERT 和 Word2Vec 计算句子相似性

我们经常需要将文本数据,包括单词、句子或文档编码成高维向量。句子嵌入是各种NLP任务的重要步骤,如情感分析和提取式总结。需要一个灵活的句子嵌入库来快速原型化,并针对各种语境进行调整。 过去,我们大多使用one-hot、词频或TF-IDF(又称归一化术语频率)等编码器。然而,这些技术并没有捕捉到词的语义和句法信息。最近的进展使我们能够以更有意义的形式对句子或单词进行编码。word2vec技术和BERT语言模型是两个重要的技术。注意,在这里,我们交替使用嵌入、编码或矢量。

开源的 sent2vec Python 库允许你对句子进行高度灵活的编码。目前您可以使用库中的标准编码器。更多的高级技术将在以后的版本中加入。在本文中,我想介绍这个库,并分享我在这方面的经验教训。 如果你不熟悉Word2Vec模型,我建议你先阅读下面的文章。你会发现为什么Word2Vec模型在机器学习中是简单而又革命性的。

Word2Vec模型简单而又具有革命性的特点

Gensim or spaCy? It doesn’t matter if you don’t know the fundamentals of Word2Vec models.

-如何使用"Sent2Vec"Python包

如何安装

由于 sent2vec 是一个高级库,它有依赖 spaCy(用于文本清洗)Gensim(word2vec模型)和 Transformers (用于各种形式的BERT模型)。因此,在使用下面的代码安装 sent2vec 之前,请务必安装这些库。

pip3 install sent2vec

如何使用 BERT 方法

如果你想使用 BERT 语言模型(更具体地说 distilbert-base-uncased )来编码下游应用程序的句子,你必须使用下面的代码。目前, sent2vec 库仅支持 DistilBERT 模型。今后将支持更多的模型。由于这是一个开源项目,您还可以深入到源代码中,并找到更多实施详细信息。

from scipy import spatial
from sent2vec.vectorizer import Vectorizer

sentences = [
    "This is an awesome book to learn NLP.",
    "DistilBERT is an amazing NLP model.",
    "We can interchangeably use embedding, encoding, or vectorizing.",
]

vectorizer = Vectorizer()
vectorizer.bert(sentences)
vectors_bert = vectorizer.vectors

dist_1 = spatial.distance.cosine(vectors_bert[0], vectors_bert[1])
dist_2 = spatial.distance.cosine(vectors_bert[0], vectors_bert[2])
print('dist_1: {0}, dist_2: {1}'.format(dist_1, dist_2))
# dist_1: 0.043, dist_2: 0.192

sent2vec 如何使用BERT计算句子嵌入的方法

您可以使用它们的载体计算句子之间的距离。在示例中,如预期的那样, vectors[0]vectors[1]的距离小于 vectors[0]vectors[2]

如何使用 Word2Vec 方法

如果你想使用word2vec方法代替,你必须首先将句子分成单词列表,使用Splitter 这个类的方法sent2words。您可以通过修改(添加或删除)默认的停词列表来自定义停词列表。 在进行任何计算之前,研究停词列表至关重要,最终结果很容易与此步骤中的微小变化发生偏斜。

当您提取句子中最重要的单词时,您可以使用Vectorizer类中的word2vec方法计算句子嵌入。此方法使用下面的代码计算 与剩余(即最重要的)单词对应的向量平均值

from scipy import spatial
from sent2vec.vectorizer import Vectorizer

sentences = [
    "Alice is in the Wonderland.",
    "Alice is not in the Wonderland.",
]

splitter = Splitter()
splitter.sent2words(sentences=sentences, remove_stop_words=['not'], add_stop_words=[])
print(splitter.words)
# [['alice', 'wonderland'], ['alice', 'not', 'wonderland']]

vectorizer = Vectorizer()
vectorizer.word2vec(splitter.words, pretrained_vectors_path=PRETRAINED_VECTORS_PATH)
vectors_w2v = vectorizer.vectors
dist_w2v = spatial.distance.cosine(vectors_w2v[0], vectors_w2v[1])
print('dist_w2v: {}'.format(dist_w2v))
# dist_w2v: 0.11

sent2vec 如何使用word2vec计算句子嵌入

如上所述,您可以通过向word2vec方法发送其路径(即PRETRAINED_VECTORS_PATH)来使用不同的word2vec模型。您可以使用预训练的模型或定制的模型。这种配置对于获得有意义的结果至关重要。你需要一个上下文化的矢量化,而word2vec模型就可以解决这个问题。

—什么是最好的句子编码器

句子编码或嵌入技术的最终结果植根于各种因素,如相关的停词列表或上下文预培训模型。您可以在下面找到更多解释。

  • 文本清洗- 比方说,你使用spaCy进行文本清洗步骤,因为我在sent2vec库中也使用了它。如果你误将 "Not "从默认的停止词列表中删除,那么句子嵌入结果就会完全误导。一个简单的单词 "Not "就可以彻底改变一个句子的情感。每个环境下,默认的停止词列表都不一样。所以,在进行任何计算之前,你必须根据自己的需求来策划这个列表。
  • 上下文化模型(Contextualized Models)- 你必须使用上下文化的模型。例如,如果目标数据是金融领域,你必须使用在金融语料库上训练的模型。否则,句子嵌入的结果可能是不准确的。所以,如果你使用word2vec方法,想要使用通用英语模型,句子嵌入的结果可能会不准确。
  • 聚合策略(Aggregation Strategy)— 当你使用word2vec方法计算句子嵌入时,你可能需要使用更高级的技术来聚合词向量,而不是取其平均值。目前,sent2vec库只支持 "平均 "技术。使用加权平均数来计算句子嵌入,是一个简单的增强,可以改善最终的结果。在未来的版本中,将支持更多高级技术。

为了强调word2vec模型的意义,我使用两种不同的word2vec模型(即glove-wiki-gigaword-300fasttext-wiki-news-subwords-300)对一个句子进行编码。然后,我计算两个向量之间的余弦相似度: 0.005 可能会被解释为 "两个独特的句子非常不同"。错了! 通过这个例子,我想证明如果我们使用两个不同的word2vec模型,一个句子的向量表示甚至可以是垂直的。换句话说,如果你盲目地用一个随机的word2vec模型来计算句子嵌入,你可能会在这个过程中感到惊讶。

-Sent2Vec是一个开放源码的库,所以...

Sent2Vec是一个开源库。这个项目的主要目标是加快构建NLP项目中的概念证明。大量的NLP任务需要句子矢量化,包括总结和情感分析。所以,请大家考虑贡献力量,推动这个项目的发展。也希望你能在你精彩的NLP项目中使用这个库。

如果您发现此包有用, 请考虑捐赠给这个项目。这有助于我继续开发此包。谢谢!

《人工智能: 非正统的教训》是科技行业中追求人工智能工程师、人工智能架构师、人工智能咨询或人工智能战略角色的人的必读之作。希望你喜欢读这本书。请点赞 人工智能: 非正统的教训

凡本网注明"来源:XXX "的文/图/视频等稿件,本网转载出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如涉及作品内容、版权和其它问题,请与本网联系,我们将在第一时间删除内容!
作者: Pedram Ataee
来源: https://towardsdatascience.com/how-to-compute-sentence-similarity-using-bert-and-word2vec-ab0663a5d64