我的目标是确定两个句子是否重复。
我正在尝试比较两个句子的解析器树。 我已经按照以下格式从解析器树中提取了标签
['ROOT', 'SBARQ', 'WHADVP', 'WRB', 'SQ', 'VP', 'VBP', 'ADJP', 'RB', 'JJ', 'NP', 'NNP', 'NP', 'NP', 'NNS', 'VP', 'VBG', 'NP', 'NP', 'NNS', 'SBAR', 'WHNP', 'WDT', 'S', 'VP', 'VBP', 'ADVP', 'RB', 'VP', 'VBN', 'PP', 'IN', 'NP', 'NNP', '.']
['ROOT', 'SBARQ', 'WHADVP', 'WRB', 'SQ', 'VBP', 'NP', 'NNS', 'VP', 'VB', 'NP', 'NP', 'NNP', 'NNS', 'SBAR', 'WHNP', 'WDT', 'S', 'VP', 'MD', 'VP', 'VB', 'VP', 'VBN', 'ADVP', 'RB', 'PP', 'IN', 'NP', 'NNP', '.']
我想获取两个列表的公共子列表的长度。在上述情况下,结果将为4('ROOT','SBARQ','WHADVP','WRB')+ 5('SBAR','WHNP','WDT','S','VP') +2('ADVP','RB')+ 5('PP','IN','NP','NNP','。')。
或者您还有其他解决方案可以利用语法分析树来实现两个句子的相似性。 另一个问题是,获取解析树的最快方法是什么?由于我要比较的句子对超过300,000 ...
谢谢!
答案 0 :(得分:0)
我建议您阅读有关Longest common subsequence problem
,这里有两个使用递归和动态编程的示例,都使用python编写
https://rosettacode.org/wiki/Longest_common_subsequence#Python
答案 1 :(得分:0)
python stdlib包含用于进行差异的difflib
模块,如下所示(尽管结果与您期望的有所不同):
pos1 = ['ROOT', 'SBARQ', 'WHADVP', 'WRB', 'SQ', 'VP', 'VBP', 'ADJP', 'RB', 'JJ', 'NP', 'NNP', 'NP', 'NP', 'NNS', 'VP', 'VBG', 'NP', 'NP', 'NNS', 'SBAR', 'WHNP', 'WDT', 'S', 'VP', 'VBP', 'ADVP', 'RB', 'VP', 'VBN', 'PP', 'IN', 'NP', 'NNP', '.']
pos2 = ['ROOT', 'SBARQ', 'WHADVP', 'WRB', 'SQ', 'VBP', 'NP', 'NNS', 'VP', 'VB', 'NP', 'NP', 'NNP', 'NNS', 'SBAR', 'WHNP', 'WDT', 'S', 'VP', 'MD', 'VP', 'VB', 'VP', 'VBN', 'ADVP', 'RB', 'PP', 'IN', 'NP', 'NNP', '.']
from difflib import SequenceMatcher
sm = SequenceMatcher(a=pos1, b=pos2)
for diff in sm.get_opcodes():
# uncomment this to see all the diffs
# print(diff)
op, f1_from, f1_to, f2_from, f2_to = diff
if op == 'equal':
print("{}{}".format(f1_to-f1_from, tuple(pos1[f1_from:f1_to])))
给予:
5('ROOT', 'SBARQ', 'WHADVP', 'WRB', 'SQ')
1('VBP',)
3('NP', 'NNS', 'VP')
2('NP', 'NP')
6('NNS', 'SBAR', 'WHNP', 'WDT', 'S', 'VP')
2('ADVP', 'RB')
5('PP', 'IN', 'NP', 'NNP', '.')
答案 2 :(得分:0)
我想我可能和您一样有类似的问题。
您的目标是计算两棵树的公共节点之和,然后获得两个句子的相似性吗?