第一次发布海报 - 我是一名新的Python用户,编程技巧有限。最后,我试图在同一目录中找到的众多文本文档中识别和比较n-gram。我的分析有点类似于抄袭检测 - 我想计算可以找到特定n-gram的文本文档的百分比。现在,我正在尝试更大问题的更简单版本,尝试比较两个文本文档中的n-gram。我没有问题确定n-gram,但我正在努力比较这两个文件。有没有办法将n-gram存储在列表中,以便有效地比较两个文档中存在的n-gram?这是我到目前为止所做的(原谅天真的编码)。作为参考,我提供下面的基本句子,而不是我在代码中实际阅读的文本文档。
import nltk
from nltk.util import ngrams
text1 = 'Hello my name is Jason'
text2 = 'My name is not Mike'
n = 3
trigrams1 = ngrams(text1.split(), n)
trigrams2 = ngrams(text2.split(), n)
print(trigrams1)
for grams in trigrams1:
print(grams)
def compare(trigrams1, trigrams2):
for grams1 in trigrams1:
if each_gram in trigrams2:
print (each_gram)
return False
感谢大家的帮助!
答案 0 :(得分:0)
在common
功能中使用列表compare
。将每个ngram附加到这两个三元组共有的列表中,最后将列表返回为:
>>> trigrams1 = ngrams(text1.lower().split(), n) # use text1.lower() to ignore sentence case.
>>> trigrams2 = ngrams(text2.lower().split(), n) # use text2.lower() to ignore sentence case.
>>> trigrams1
[('hello', 'my', 'name'), ('my', 'name', 'is'), ('name', 'is', 'jason')]
>>> trigrams2
[('my', 'name', 'is'), ('name', 'is', 'not'), ('is', 'not', 'mike')]
>>> def compare(trigrams1, trigrams2):
... common=[]
... for grams1 in trigrams1:
... if grams1 in trigrams2:
... common.append(grams1)
... return common
...
>>> compare(trigrams1, trigrams2)
[('my', 'name', 'is')]
答案 1 :(得分:0)
我认为连接ngrams中的元素并创建字符串列表然后进行比较可能更容易。
让我们用你提供的例子来讨论这个过程。
text1 = 'Hello my name is Jason'
text2 = 'My name is not Mike'
在应用nltk中的ngrams
函数后,您将获得以下两个类似我的名称text1
和text2
的列表:
text1 = [('Hello', 'my', 'name'), ('my', 'name', 'is'), ('name', 'is', 'Jason')]
text2 = [('My', 'name', 'is'), ('name', 'is', 'not'), ('is', 'not', 'Mike')]
如果你想比较ngrams,你应该小写所有元素,以免它被'my'
和'My'
计算为单独的标记,这是我们显然不想要的。
以下功能就是这样。
def append_elements(n_gram):
for element in range(len(n_gram)):
phrase = ''
for sub_element in n_gram[element]:
phrase += sub_element+' '
n_gram[element] = phrase.strip().lower()
return n_gram
因此,如果我们提供text1
,我们会得到['hello my name', 'my name is', 'name is jason']
,这样更容易处理。
接下来我们制作compare
函数。你是对的,我们可以假设我们可以使用一个列表来存储共性。我在这里命名为common
:
def compare(n_gram1, n_gram2):
n_gram1 = append_elements(n_gram1)
n_gram2 = append_elements(n_gram2)
common = []
for phrase in n_gram1:
if phrase in n_gram2:
common.append(phrase)
if not common:
return False
# or you could print a message saying no commonality was found
else:
for i in common:
print(i)
if not common
表示common
列表为空,在这种情况下,它会打印一条消息或返回False
现在,在您的示例中,当我们运行compare(text1, text2)
时,唯一的共性是:
>>>
my name is
>>>
这是正确的答案。
答案 2 :(得分:0)
当我遇到这个旧线程时,我正在执行与您非常相似的任务,该任务似乎工作得很好,但有一个错误。如果有人偶然发现此问题,我将在此处添加此答案。 ngrams
中的nltk.util
返回一个生成器对象,而不是一个列表。需要使用您编写的compare
函数将其转换为列表。使用lower()
进行不区分大小写的匹配。
完整示例:
import nltk
from nltk.util import ngrams
text1 = 'Hello my name is Jason'
text2 = 'My name is not Mike'
n = 3
trigrams1 = ngrams(text1.lower().split(), n)
trigrams2 = ngrams(text2.lower().split(), n)
def compare_ngrams(trigrams1, trigrams2):
trigrams1 = list(trigrams1)
trigrams2 = list(trigrams2)
common=[]
for gram in trigrams1:
if gram in trigrams2:
common.append(gram)
return common
common = compare_ngrams(trigrams1, trigrams2)
print(common)
输出:
[('my', 'name', 'is')]