Python NLTK:Bigrams、Trigrams和Fourgrams

25
我有一个示例,想知道如何得到这个结果。我有一段文本,对其进行分词,然后收集二元组、三元组和四元组等。
import nltk
from nltk import word_tokenize
from nltk.util import ngrams
text = "Hi How are you? i am fine and you"
token=nltk.word_tokenize(text)
bigrams=ngrams(token,2)

二元组:[('Hi', 'How'), ('How', 'are'), ('are', 'you'), ('you', '?'), ('?', 'i'), ('i', 'am'), ('am', 'fine'), ('fine', 'and'), ('and', 'you')]

trigrams=ngrams(token,3)

三元组:[('Hi', 'How', 'are'), ('How', 'are', 'you'), ('are', 'you', '?'), ('you', '?', 'i'), ('?', 'i', 'am'), ('i', 'am', 'fine'), ('am', 'fine', 'and'), ('fine', 'and', 'you')]

bigram [(a,b) (b,c) (c,d)]
trigram [(a,b,c) (b,c,d) (c,d,f)]
i want the new trigram should be [(c,d,f)]
which mean 
newtrigram = [('are', 'you', '?'),('?', 'i','am'),...etc

任何想法都会有所帮助。

我不明白,看起来你已经生成了ngrams? - Emre
@Emre,我的问题是如何获取新三元组。我正在寻找一个函数,它可以在二元组的元素中搜索并将其与三元组的元素进行比较,并仅取不同的部分。 - M.A.Hassan
1
现在有一个 everygrams 的实现了 =) - alvas
4个回答

10
如果您应用一些集合论(如果我正确解释了您的问题),您将看到您想要的三元组仅是token列表的[2:5]、[4:7]、[6:8]等元素。
您可以这样生成它们:
>>> new_trigrams = []
>>> c = 2
>>> while c < len(token) - 2:
...     new_trigrams.append((token[c], token[c+1], token[c+2]))
...     c += 2
>>> print new_trigrams
[('are', 'you', '?'), ('?', 'i', 'am'), ('am', 'fine', 'and')]

其实我的问题与另一个问题有关,如果您能看一下这个问题,也许您就能理解整个想法。http://stackoverflow.com/questions/24289553/python-nltk-ngrams-filtering-and-excluding?noredirect=1#comment37580272_24289553 - M.A.Hassan

8
尝试使用everygrams:
from nltk import everygrams
list(everygrams('hello', 1, 5))

[out]:

[('h',),
 ('e',),
 ('l',),
 ('l',),
 ('o',),
 ('h', 'e'),
 ('e', 'l'),
 ('l', 'l'),
 ('l', 'o'),
 ('h', 'e', 'l'),
 ('e', 'l', 'l'),
 ('l', 'l', 'o'),
 ('h', 'e', 'l', 'l'),
 ('e', 'l', 'l', 'o'),
 ('h', 'e', 'l', 'l', 'o')]

单词标记:

from nltk import everygrams

list(everygrams('hello word is a fun program'.split(), 1, 5))

[输出]:

[('hello',),
 ('word',),
 ('is',),
 ('a',),
 ('fun',),
 ('program',),
 ('hello', 'word'),
 ('word', 'is'),
 ('is', 'a'),
 ('a', 'fun'),
 ('fun', 'program'),
 ('hello', 'word', 'is'),
 ('word', 'is', 'a'),
 ('is', 'a', 'fun'),
 ('a', 'fun', 'program'),
 ('hello', 'word', 'is', 'a'),
 ('word', 'is', 'a', 'fun'),
 ('is', 'a', 'fun', 'program'),
 ('hello', 'word', 'is', 'a', 'fun'),
 ('word', 'is', 'a', 'fun', 'program')]

3
我是这样做的:

我是这样做的:

def words_to_ngrams(words, n, sep=" "):
    return [sep.join(words[i:i+n]) for i in range(len(words)-n+1)]

这个函数以单词列表为输入,返回由n个单词组成的ngrams列表(通过给定的n),并用sep(在本例中是一个空格)分隔。


3
from nltk.util import ngrams

text = "Hi How are you? i am fine and you"

n = int(input("ngram value = "))

n_grams = ngrams(text.split(), n)

for grams in n_grams :

   print(grams)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接