2009-07-19 130 views
7

我在Python下的NLTK,尤其是.generate()方法有問題。在Python的NLTK中從自定義文本生成隨機句子?

生成(個體,長度= 100)

打印隨機文本,使用三元語言模型生成。

參數:

* length (int) - The length of text to generate (default=100) 

這裏是我在嘗試的簡化版本。

import nltk 

words = 'The quick brown fox jumps over the lazy dog' 
tokens = nltk.word_tokenize(words) 
text = nltk.Text(tokens) 
print text.generate(3) 

這將總是產生

Building ngram index... 
The quick brown 
None 

至於反對建立一個隨機短語出來的話。

這裏是我的輸出,當我做

print text.generate() 

Building ngram index... 
The quick brown fox jumps over the lazy dog fox jumps over the lazy 
dog dog The quick brown fox jumps over the lazy dog dog brown fox 
jumps over the lazy dog over the lazy dog The quick brown fox jumps 
over the lazy dog fox jumps over the lazy dog lazy dog The quick brown 
fox jumps over the lazy dog the lazy dog The quick brown fox jumps 
over the lazy dog jumps over the lazy dog over the lazy dog brown fox 
jumps over the lazy dog quick brown fox jumps over the lazy dog The 
None 

再次開始接觸相同的文字,但後來改變它。我也嘗試使用Orwell's 1984的第一章。再次,總是開始於前3個標記(其中一個是這種情況下的空間)並且然後繼續隨機生成文本。

我在這裏做錯了什麼?

回答

-1

也許你可以在生成一個句子之前對令牌數組隨機排序。

+1

NLTK使用單詞的上下文來確定它們的使用。舉例來說,他們在NLTK中有「Moby Dick」的全部文本。使用generate生成Meville聲音句子。所以,除非你知道我沒有的東西,否則我認爲你不想訴諸文字,因爲最初的語境很重要。 – 2009-07-19 15:56:49

+1

你是對的。如果你打亂了你所說的話,你就會失去卦三圍的信息。 – Mastermind 2009-07-20 17:07:50

-1

您確定使用word_tokenize是正確的嗎?

This Google groups page有例如:

>>> import nltk 
>>> text = nltk.Text(nltk.corpus.brown.words()) # Get text from brown 
>>> text.generate() 

但我從來沒有用過NLTK,所以我不能說這是否運作的,你想要的方式。

+1

nltk.corpus.brown.words()只是NLTK附帶的單詞集合。我試圖用我自己的話語給發電機播種。 – 2009-07-19 20:34:47

1

您的樣本語料庫最可能太小。我不知道nltk如何構建它的三元模型,但通常的做法是句子的開始和結束都是以某種方式處理的。由於您的語料庫中只有一個句子的開頭,這可能就是每個句子都有相同開頭的原因。

9

生成隨機文本,U需要使用Markov Chains

代碼做到這一點:from here

import random 

class Markov(object): 

    def __init__(self, open_file): 
    self.cache = {} 
    self.open_file = open_file 
    self.words = self.file_to_words() 
    self.word_size = len(self.words) 
    self.database() 


    def file_to_words(self): 
    self.open_file.seek(0) 
    data = self.open_file.read() 
    words = data.split() 
    return words 


    def triples(self): 
    """ Generates triples from the given data string. So if our string were 
    "What a lovely day", we'd generate (What, a, lovely) and then 
    (a, lovely, day). 
    """ 

    if len(self.words) < 3: 
     return 

    for i in range(len(self.words) - 2): 
     yield (self.words[i], self.words[i+1], self.words[i+2]) 

    def database(self): 
    for w1, w2, w3 in self.triples(): 
     key = (w1, w2) 
     if key in self.cache: 
    self.cache[key].append(w3) 
     else: 
    self.cache[key] = [w3] 

    def generate_markov_text(self, size=25): 
    seed = random.randint(0, self.word_size-3) 
    seed_word, next_word = self.words[seed], self.words[seed+1] 
    w1, w2 = seed_word, next_word 
    gen_words = [] 
    for i in xrange(size): 
     gen_words.append(w1) 
     w1, w2 = w2, random.choice(self.cache[(w1, w2)]) 
    gen_words.append(w2) 
    return ' '.join(gen_words) 

釋: Generating pseudo random text with Markov chains using Python

7

你應該是 「訓練」 馬氏與多個序列模型,以便您準確地對起始狀態概率進行採樣(在馬爾可夫語中稱爲「pi」)。如果您使用單個序列,那麼您將始終以相同的狀態開始。

對於Orwell's 1984的例子,您首先要使用句子標記(NLTK非常擅長),然後是詞語標記(產生一個標記列表列表,而不僅僅是一個標記列表),然後提供每個句子分別對應於馬爾可夫模型。這將允許它正確地建模序列開始,而不是以單一方式停止開始每個序列。