我有2个句子可以根据他们使用NLP的语法进行比较。我是NLP的新手,想知道是否有算法来确定这一点。我知道如何使用单词相似度和情感进行比较。
答案 0 :(得分:0)
您可以使用nltk wordnet的同义词来衡量两个句子之间的相似性
这里是如何在不必指定语法的情况下生成所有可能的同义词集合,您可以稍后根据特定标准选择要使用的同义词集合
import pandas as pd
import nltk
from nltk.stem.porter import PorterStemmer
from nltk.corpus import wordnet as wn
import itertools
#use stemmer
stm = PorterStemmer()
sent1 = "I like hot dogs"
sent2 = "My father's favourite food is hot dog"
#Convert the tag given by nltk.pos_tag to the tag used by wordnet.synsets
tag_dict = {'N': 'n', 'J': 'a', 'R': 'r', 'V': 'v'}
s1 = nltk.pos_tag(nltk.word_tokenize(sent1))
s1 = dict(filter(lambda x: len(x[1])>0,
map(lambda row: (row[0],wn.synsets(
stm.stem(row[0]),
tag_dict[row[1][0]])) if row[1][0] in tag_dict.keys()
else (row[0],[]),s1)))
s2 = nltk.pos_tag(nltk.word_tokenize(sent2))
s2 = dict(filter(lambda x: len(x[1])>0,
map(lambda row: (row[0],wn.synsets(
stm.stem(row[0]),
tag_dict[row[1][0]])) if row[1][0] in tag_dict.keys()
else (row[0],[]),s2)))
以下是字典s1
中值的示例dogs [Synset('dog.n.01'), Synset('frump.n.01'), Synset('dog.n.03'), Synset('cad.n...
hot [Synset('hot.a.01'), Synset('hot.s.02'), Synset('hot.a.03'), Synset('hot.s.0...
like [Synset('wish.v.02'), Synset('like.v.02'), Synset('like.v.03'), Synset('like...
这是一种方法。在这里,我测量两个单词的所有可能的同义词之间的相似性,然后取最大值。
res = {}
for w2,gr2 in s2.items():
for w1,gr1 in s1.items():
tmp = pd.Series(list(map(lambda row: row[1].path_similarity(row[0]),
itertools.product(gr1,gr2)))).dropna()
if len(tmp)>0:
res[(w1,w2)] = tmp.max()
print(res)
输出
{('dogs', 'dog'): 1.0,
('dogs', 'father'): 0.16666666666666666,
('dogs', 'food'): 0.25,
('dogs', 'is'): 0.10000000000000001,
('hot', 'hot'): 1.0,
('hot', 'is'): 0.33333333333333331,
('like', 'is'): 0.33333333333333331}
现在我们发现句子中每个单词达到的最大相似度。然后取平均值
similarity = pd.Series(res).groupby(level=0).max().mean()
print(similarity)
输出为.778
以上是测量文档相似度时的常用方法。如果你想要比较语法,你可能想要在两个句子上使用像pos_tag这样的词性标注器(或使用像nltk.corpus.brown.tagged_words()
这样的标记语料库),然后找到标签之间的Jaccard距离