Python 使用Word2Vec的文本相似性

Python 使用Word2Vec的文本相似性,python,pandas,word2vec,similarity,Python,Pandas,Word2vec,Similarity,我想用Word2Vec来检查文本的相似性 我目前正在使用另一种逻辑: from fuzzywuzzy import fuzz def sim(name, dataset): matches = dataset.apply(lambda row: ((fuzz.ratio(row['Text'], name) ) = 0.5), axis=1) return (名字是我的专栏) 要应用此功能,我需要执行以下操作: df['Sim']=df.apply(lambda row: s

我想用Word2Vec来检查文本的相似性

我目前正在使用另一种逻辑:

from fuzzywuzzy import fuzz

def sim(name, dataset):
    matches = dataset.apply(lambda row: ((fuzz.ratio(row['Text'], name) ) = 0.5), axis=1)
   return 
(名字是我的专栏)

要应用此功能,我需要执行以下操作:

df['Sim']=df.apply(lambda row: sim(row['Text'], df), axis=1)
您能告诉我如何用Word2Vec替换fuzzy.ratio以比较数据集中的文本吗

数据集示例:

Text
Hello, this is Peter, what would you need me to help you with today? 
I need you
Good Morning, John here, are you calling regarding your cell phone bill? 
Hi, this this is John. What can I do for you?
...
第一个文本和最后一个文本非常相似,尽管它们用不同的词来表达相似的概念。 我想创建一个新列,在其中为每一行放置相似的文本。
我希望你能帮助我。

TLDR跳到最后一节(第4部分)了解代码实现

1.模糊与单词嵌入 与模糊匹配不同,word2vec(以及fasttext和GloVe等其他模型)表示n维欧几里德空间中的每个单词,模糊匹配基本上是
编辑距离
levenshtein距离
。表示每个单词的向量称为单词向量或单词嵌入

这些单词嵌入是大量单词的n维向量表示。这些向量可以加起来表示句子的嵌入。语义相似的句子会有相似的向量,因此它们的句子嵌入也会相似。了解更多有关word2vec如何在内部工作的信息

假设我有一个有两个单词的句子。Word2Vec将这里的每个单词表示为欧几里德空间中的向量。将它们相加,就像标准向量相加一样,将在同一空间中产生另一个向量。对于使用单个单词嵌入来表示句子,这是一个很好的选择

注意:还有其他结合单词嵌入的方法,比如加权和和tf idf权重,或者直接使用句子嵌入和一种称为Doc2Vec的算法。请阅读更多关于此的信息

2.词向量/句子向量之间的相似性 “你应该从它的同伴那里知道一个词”

与单词(上下文)一起出现的单词通常在语义/意义上相似。word2vec的优点在于,在欧几里德空间中,具有相似上下文的单词向量彼此更接近。这可以让你做一些事情,比如聚类或者简单的距离计算

找到两个词向量的相似程度的好方法是
余弦相似性
。阅读更多

3.预先培训的word2vec模型(及其他) word2vec和此类模型最棒的一点是,在大多数情况下,您不需要对它们进行数据训练您可以使用预先训练的单词嵌入,它已在大量数据上训练过,并根据单词与句子中其他单词的共现情况对单词之间的上下文/语义相似性进行编码

您可以使用
cosine\u similarity

4.示例代码实现 我使用一个手套模型(类似于word2vec),它已经在维基百科上训练过了,每个单词都表示为一个50维向量。您可以选择其他型号,而不是我在这里使用的型号-


如果你想比较句子,你不应该使用Word2Vec或手套嵌入。他们把句子中的每个单词翻译成一个向量。从这两组向量中找出这些句子有多相似是相当麻烦的。您应该使用定制的工具将整个句子转换为单个向量。然后你只需要比较两个向量有多相似
通用句子编码器
是考虑到计算成本和准确性权衡的最佳编码器之一(DAN变体)。请参阅本文中的用法示例。我相信它描述了一个与您非常接近的用例。

您可以使用预先训练过的单词嵌入模型(word2vec、glove或fasttext)来实现单词嵌入。这些可以添加(向量加法)来表示句子。现在可以使用余弦相似性计算这些向量之间的相似性。请检查我的答案,详细说明了这一点,以及示例代码。还有其他的结合单词嵌入的方法。此外,您还可以直接使用doc2vec将句子表示为向量。为什么要使用Word2Vec来比较句子?Word2Vec是为单词嵌入而定制的,而不是为句子嵌入而定制的。为什么不使用Doc2Vec,或者更好:?嗨@Rjadriansen,我对word2vec之外的其他可能性持开放态度。由于我使用fuzzy得到了错误的结果,所以我考虑使用Word2Vec来获得更好的结果。我的目标是展示我在问题中提到的句子的相似性。感谢你们的评论和帮助,Akshay Sehgal和RG Adriaansenthan非常感谢你们的回答,Akshay Sehgal。我还没有考虑过手套,但我认为它也能起作用。在我的功能中实现手套模型时遇到一些困难。我的目标是展示比我用模糊逻辑得到的结果更好的结果。你也可以用word2vec模型代替手套。检查这里的模型@Math,让我知道你面临的困难是什么。我的困难是在这里替换word2vec:
dataset.apply(lambda行:((fuzz.ratio(row['Text'],name))=0.5)
以便将每个文本与另一个文本进行比较。我想我不能用word2vec“仅仅替换”fuzz.ratio,所以我正在尝试理解并将您提供的示例信息应用到我的代码中(不幸的是仍然没有成功)当你说不能直接使用word2vec而不是fuzz.ratio时,你是对的。这是两种不同的方法,提供了完全不同的方法来测量两个句子之间的相似性/距离。您好,感谢您提供的详细信息,不过,请注意一点。word2vec和Glove是一种很好的方法,可以在句子之间创建相似性这是基本的线性代数,它可以让你创建一个句子的语义表示
from scipy import spatial
import gensim.downloader as api

model = api.load("glove-wiki-gigaword-50") #choose from multiple models https://github.com/RaRe-Technologies/gensim-data

s0 = 'Mark zuckerberg owns the facebook company'
s1 = 'Facebook company ceo is mark zuckerberg'
s2 = 'Microsoft is owned by Bill gates'
s3 = 'How to learn japanese'

def preprocess(s):
    return [i.lower() for i in s.split()]

def get_vector(s):
    return np.sum(np.array([model[i] for i in preprocess(s)]), axis=0)


print('s0 vs s1 ->',1 - spatial.distance.cosine(get_vector(s0), get_vector(s1)))
print('s0 vs s2 ->', 1 - spatial.distance.cosine(get_vector(s0), get_vector(s2)))
print('s0 vs s3 ->', 1 - spatial.distance.cosine(get_vector(s0), get_vector(s3)))
#Semantic similarity between sentence pairs
s0 vs s1 -> 0.965923011302948
s0 vs s2 -> 0.8659112453460693
s0 vs s3 -> 0.5877998471260071