首页 > 解决方案 > 无法找到有效的 ngram 文档

问题描述

我正在尝试在 python 中使用 ngram 函数,但无法正确实现我正在处理的问题

我试过插入 ngram 和 ngrams

import nltk
from nltk.util import ngrams

def n_grams(words, min=2, max=3):
    s = []
    for n in range(min, max):
        for ngram in ngrams(words, n):
            s.append(' '.join(str(i) for i in ngram))
    return s

t = 'hippopotomonstrosesquippedaliophobia'
t_split = re.split(r'\W*', t)
print(n_grams(t_split))

我正在尝试返回以下内容:

#{'tr', 'ho', 'hi', 'to', 'om', 'io', 'ob', 'mo', 'ed', 'ip', 'al', 'bi', 'pe', 
#'da', 'po', 'ns', 'qu', 'st', 'ia', 'ot', 'se', 'op', 'ro', 'ui', 'li', 'pp', 
#'es', 'sq', 'ph', 'on', 'os'} 

but instead returning this:
#[' h', 'h i', 'i p', 'p p', 'p o', 'o p', 'p o', 'o t', 't o', 'o m', #'m o', 'o n', 'n s', 's t', 't r', 'r o', 'o s', 's e', 'e s', 's q', #'q u', 'u i', 'i p', 'p p', 'p e', 'e d', 'd a', 'a l', 'l i', 'i o', #'o p', 'p h', 'h o', 'o b', 'b i', 'i a', 'a ']

标签: pythonn-gram

解决方案


真的,这里唯一的问题是多余的正则表达式和连接语法。您在匹配零到无限非单词字符([^a-zA-Z0-9_])的模式上调用 re.split(),但实际上没有任何与该模式匹配的字符串。没有什么可以拆分的,因此正则表达式返回整个单词不变(并在 Python 3.6+ 中引发错误)。在一些 Python 解释器中对其进行测试,看起来它也可能在字符串的开头和结尾拆分,但这可能是您正在使用的版本或 join 语句的工件(见下文) - - 我不能从这个片段中看出。

如果我n_grams按照您编写的那样使用该函数,但在连接中没有空格而不是使用连接来调用它,并完全删除您的正则表达式,我认为它会得到您想要的(双图集):

print(set(n_grams(t)))

这是:

{'es', 'op', 'bi', 'hi', 'ot', 'ro', 'ph', 'al', 
 'ns', 'sq', 'ho', 'ed', 'ob', 'ip', 'to', 'io', 
 'on', 'da', 'pe', 'om', 'mo', 'ia', 'st', 'po', 
 'tr', 'qu', 'se', 'ui', 'pp', 'li', 'os'}

如果你选择from collections import Counter,那么你也可以得到这个:

print(Counter(n_grams(t)))

产生一个计数字典,本质上是:

Counter({'ip': 2, 'pp': 2, 'po': 2, 'op': 2, 'hi': 1, 'ot': 1, 'to': 1, 'om': 
  1, 'mo': 1, 'on': 1, 'ns': 1, 'st': 1, 'tr': 1, 'ro': 1, 'os': 1, 'se': 1, 
  'es': 1, 'sq': 1, 'qu': 1, 'ui': 1, 'pe': 1, 'ed': 1, 'da': 1, 'al': 1, 'li': 
  1, 'io': 1, 'ph': 1, 'ho': 1, 'ob': 1, 'bi': 1, 'ia': 1})

要处理边缘字符,您可以告诉 NLTK 的 ngram 函数使用左右填充,并指定字符(通常为"<s>""</s>"),但在此示例中似乎没有必要。


推荐阅读