繁体   English   中英

如何计算两个词之间的相似度以检测它们是否重复?

[英]How do I calculate similarity between two words to detect if they are duplicates?

我有两个词,我想计算它们之间的相似度,以便在它们是否重复时对它们进行排名。

我如何使用深度学习/NLP 方法实现这一目标?

这里有一些解决文本相似性的方法

基于字符串的方法

基于神经的方法

基于机器翻译的方法


但是在考虑使用哪个库来衡量相似度之前,您应该尝试定义在相似度方面要衡量什么,

您是否试图找到具有句法差异的语义相似性?

  • The dog ate the biscuit vs
  • The biscuit was eaten by the dog

您是否试图找到词汇语义相似性?

  • This problem is driving me mad! 对比
  • This problem is making me angry!

您是否试图找到蕴涵而不是相似性?

  • I ate Chinese food for dinner vs
  • I ate kungpao chicken for dinner

当在没有上下文的情况下比较单个单词时,“相似性”的歧义变得更加复杂,例如

  • plantfactory

    • 如果plant指的是工业工厂,它们可以是相似的
    • 但是如果plant指的是生物植物,它们是不相似的
  • bank VS financial institute

    • 如果bank指的是我们存入或提取现金的地方,它们可能是相似的
    • 但是如果bank指的是河岸,它们就不一样了。

根据您想要使用相似度分数执行的最终任务,可以定义相似度的许多其他方面。

这是根据 Alva 链接的官方文档中的代码副本 - https://www.sbert.net/docs/usage/semantic_textual_similarity.html

这是位于此处的 google colab 中的代码 - https://colab.research.google.com/drive/1Ak0xrn3zWf4Rh2YtVo1avGH-EerLhEDe?usp=sharing

from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer('all-MiniLM-L6-v2')
    
# Two lists of words
word1 = ['cat',
         'man',
         'movie',
         'friend']
    
word2 = ['kitten',
          'boy',
          'film',
          'love']
    
#Compute embedding for both lists
embeddings1 = model.encode(word1, convert_to_tensor=True)
embeddings2 = model.encode(word2, convert_to_tensor=True)
  
#Compute cosine-similarities
cosine_scores = util.cos_sim(embeddings1, embeddings2)
    
 #Output the pairs with their score
for i in range(len(word1)):
        print("{} \t\t {} \t\t Score: {:.4f}".format(word1[i], word2[i], cosine_scores[i][i]))

在colab中使用上面的代码,我得到了以下output

cat          kitten      Score: 0.7882
man          boy         Score: 0.5843
movie        film        Score: 0.8426
friend       love        Score: 0.4168

我的结论是,对于与上下文无关的单词的相似性,高于 75% 的阈值分数效果很好; 如果你提供一些上下文,这个 model 会表现得更好。

如果它像根据单词的相似度获得分数一样简单,那么我建议使用模糊匹配。 此处参考链接: https://towardsdatascience.com/fuzzy-string-matching-in-python-68f240d910fe

确保安装:

  • 模糊的
  • 蟒蛇-Levenshtein
from fuzzywuzzy import fuzz

print(fuzz.ratio("hello world!", "Hello worlds"))

>>> 83

如果你想要不同的计算匹配,你可以遵循这个文档: https://rawgit.com/ztane/python-Levenshtein/master/docs/Levenshtein.html

from Levenshtein import jaro

print(jaro("hello world!", "Hello worlds"))

>>> 0.888888888888889

有两种很好的方法可以计算两个词之间的相似度。

  1. 您可以简单地使用word2vecglovefasttext (我的推荐)等嵌入模型,这些模型都很有名且有用。 嵌入模型的主要目标是将 map 一个词转换为一个向量。 词汇表中的单词表示是一个单热向量。 例如,如果您的词汇表中有 4 个单词,例如["I", "love", "the", "NLP"] ,您可以用像这样的向量表示"NLP" [0, 0, 0, 1] . 因此,通过嵌入 model,您可以将 map 单词从离散空间(一个热向量)转换为具有不同维度(如 100 或 300)的具体空间中的向量。 这些新向量本身就具有单词的语义知识。 意思是意思相近的词向量相近,意思不同的词向量相距较远。 这三个模型是预先训练的,你需要得到你的词的向量并使用诸如余弦相似度之类的东西来确定它们的语义彼此之间的接近程度(如果你有一个特定的数据集,最好先微调你的 model )。
  2. 您可以使用更复杂的网络来查找两个或多个句子之间的相似性。 这个任务被称为句子相似度,它们在无监督方法和聚类中很有帮助。 这些模型更复杂,更适合将句子用作输入,因此 model 可以看到上下文并做得更好(上下文很重要,因为它们是转换器并且基于自我注意,这是神经网络中的复杂主题) . 您可以 在此处找到这些模型,并且您需要使用单词作为输入而不是句子。

如果你只想找到单词之间的相似度,我推荐第一种解决方案。

n Python,使用深度学习和 NLP 方法计算两个词之间相似度的一种方法是使用预训练的词嵌入。 例如,您可以使用 gensim 库加载预训练的词嵌入,例如 word2vec 或 GloVe。 加载嵌入后,您可以通过使用单词索引 model 来访问每个单词的嵌入。

下面是一个示例,说明如何使用 gensim 库使用 word2vec 嵌入来计算两个单词之间的余弦相似度:

from gensim.models import Word2Vec

# Load pre-trained word2vec embeddings
model = Word2Vec.load("path/to/word2vec.bin")

# Get embeddings for two words
word1 = model["word1"]
word2 = model["word2"]

# Calculate cosine similarity
from numpy import dot
from numpy.linalg import norm
cos_sim = dot(word1, word2)/(norm(word1)*norm(word2))
print(cos_sim)

您可以使用相同的方法加载其他预训练的嵌入,如 GloVe,或者您可以使用预训练的模型,如 BERT、RoBERTa 来获取嵌入,然后使用余弦相似度来计算单词之间的相似度

或者,您可以使用针对特定 NLP 任务进行微调的预训练模型,例如 BERT 或 RoBERTa 等语义文本相似性,并使用最后一层的 output 作为输入文本的特征表示。 然后你可以使用这个特征表示来训练一个分类器来预测两个句子是否重复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM