8

PythonでのNLTK、特に.generate()メソッドに問題があります。

generate(self、length = 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

再び同じテキストから始めますが、それからそれを変えます。また、オーウェルの1984年の最初の章を使用してみました。これも、常に最初の3つのトークン(この場合はスペースの1つ)から始まり、ランダムにテキストを生成します。

私はここで何が間違っているのですか?

4

5 に答える 5

12

ランダムなテキストを生成するには、マルコフ連鎖を使用する必要があります

それを行うコード:ここから

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)

説明: Python を使用したマルコフ連鎖による疑似乱数テキストの生成

于 2009-07-20T18:48:31.653 に答える
7

複数のシーケンスでマルコフモデルを「トレーニング」して、開始状態の確率も正確にサンプリングする必要があります(マルコフ語では「pi」と呼ばれます)。単一のシーケンスを使用すると、常に同じ状態で開始されます。

Orwell の 1984 年の場合、最初に文のトークン化 (NLTK は非常に優れています) を使用し、次に単語のトークン化 (単一のトークンのリストではなく、トークンのリストのリストを生成) を使用してから、各文を個別にフィードして、マルコフモデル。これにより、すべてのシーケンスを開始する単一の方法に固執するのではなく、シーケンスの開始を適切にモデル化できます。

于 2009-09-26T15:50:57.493 に答える
1

サンプル コーパスが小さすぎる可能性があります。nltk がトライグラム モデルを正確にどのように構築しているかはわかりませんが、文の開始と終了を何らかの方法で処理するのが一般的です。コーパスには文頭が 1 つしかないため、これがすべての文の頭が同じである理由である可能性があります。

于 2009-07-19T16:35:15.670 に答える
0

word_tokenize使用することが正しいアプローチである と確信していますか?

この Google グループ ページに例があります。

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

しかし、私は nltk を使用したことがないので、それがあなたの望むように機能するかどうかはわかりません。

于 2009-07-19T16:07:12.310 に答える
-1

文を生成する前に、トークン配列をランダムに並べ替えることができるかもしれません。

于 2009-07-19T15:47:09.747 に答える