0

http://www.nltk.org/book-にあるpythonの正規表現とNLTKでさまざまなテキストを処理しようとしています。ランダム テキスト ジェネレーターを作成しようとしていますが、少し問題があります。まず、私のコードフローは次のとおりです。

  1. 入力として文を入力 - これはトリガー文字列と呼ばれ、変数に割り当てられます -

  2. トリガー文字列で最も長い単語を取得する

  3. Project Gutenberg データベースで、この単語 -regardless of uppercase Lowercase- を含む文を検索します。

  4. ステップ 3 で話した単語を含む最も長い文を返します

  5. ステップ 1 とステップ 4 の文を一緒に追加します。

  6. ステップ 4 のセンテンスを新しい「トリガー」センテンスとして割り当て、プロセスを繰り返します。2番目の文で最も長い単語を取得し、そのように続ける必要があることに注意してください-

これまでのところ、これを行うことができたのは一度だけです。これを続けようとすると、プログラムは検索結果の最初の文だけを出力し続けます。実際には、この新しい文で最も長い単語を探し、上記のコード フローを適用し続ける必要があります。

以下は私のコードとサンプルの入力/出力です:

サンプル入力

「コードの番人」

サンプル出力

「暗号の領主ノルウェー自身、恐ろしい数で、その最も不誠実な裏切り者、コーダーの領主に助けられて、小さな紛争を始めた.反抗的なアルメはアルメを獲得し、彼の怠惰な精神を抑制し、結論として、勝利者は対に陥った」

これで、実際には「Norway hime....」で始まる文を取得し、その中で最も長い単語を探し、上記の手順を実行する必要がありますが、そうではありません。助言がありますか?ありがとう。

import nltk

from nltk.corpus import gutenberg

triggerSentence = raw_input("Please enter the trigger sentence: ")#get input str

split_str = triggerSentence.split()#split the sentence into words

longestLength = 0

longestString = ""

montyPython = 1

while montyPython:

    #code to find the longest word in the trigger sentence input
    for piece in split_str:
        if len(piece) > longestLength:
            longestString = piece
            longestLength = len(piece)


    listOfSents = gutenberg.sents() #all sentences of gutenberg are assigned -list of list format-

    listOfWords = gutenberg.words()# all words in gutenberg books -list format-
    # I tip my hat to Mr.Alex Martelli for this part, which helps me find the longest sentence
    lt = longestString.lower() #this line tells you whether word list has the longest word in a case-insensitive way. 

    longestSentence = max((listOfWords for listOfWords in listOfSents if any(lt == word.lower() for word in listOfWords)), key = len)
    #get longest sentence -list format with every word of sentence being an actual element-

    longestSent=[longestSentence]

    for word in longestSent:#convert the list longestSentence to an actual string
        sstr = " ".join(word)
    print triggerSentence + " "+ sstr
    triggerSentence = sstr
4

4 に答える 4

1

毎回コーパス全体を検索するよりも、単語からその単語を含む最長の文への単一のマップを作成する方が速い場合があります。これが私の(テストされていない)これを行う試みです。

import collections
from nltk.corpus import gutenberg

def words_in(sentence):
    """Generate all words in the sentence (lower-cased)"""
    for word in sentence.split():
        word = word.strip('.,"\'-:;')
        if word:
            yield word.lower()

def make_sentence_map(books):
    """Construct a map from words to the longest sentence containing the word."""
    result = collections.defaultdict(str)
    for book in books:
        for sentence in book:
            for word in words_in(sentence):
                if len(sentence) > len(result[word]):
                    result[word] = sent
    return result

def generate_random_text(sentence, sentence_map):
    while True:
        yield sentence
        longest_word = max(words_in(sentence), key=len)
        sentence = sentence_map[longest_word]

sentence_map = make_sentence_map(gutenberg.sents())
for sentence in generate_random_text('Thane of code.', sentence_map): 
    print sentence
于 2010-08-26T05:33:03.633 に答える
1

これはどう?

  1. トリガーで最長の単語を見つけます
  2. 1で見つかった単語を含む最長の文で最長の単語を見つけます。
  3. 1.の単語は、2の文の中で最も長い単語です。

何が起こるのですか?ヒント:答えは「無限」で始まります。問題を修正するには、小文字の単語のセットが役立つことがわかります。

ところで、MontyPythonがFalseになり、プログラムが終了すると思うときは?

于 2010-08-26T04:31:22.767 に答える
0

ハンキン氏の答えはよりエレガントですが、以下はあなたが始めたアプローチに沿ったものです:

import sys
import string
import nltk
from nltk.corpus import gutenberg

def longest_element(p):
    """return the first element of p which has the greatest len()"""
    max_len = 0
    elem = None
    for e in p:
        if len(e) > max_len:
            elem = e
            max_len = len(e)
    return elem

def downcase(p):
    """returns a list of words in p shifted to lower case"""
    return map(string.lower, p)


def unique_words():
    """it turns out unique_words was never referenced so this is here
       for pedagogy"""
    # there are 2.6 million words in the gutenburg corpus but only ~42k unique
    # ignoring case, let's pare that down a bit
    for word in gutenberg.words():
        words.add(word.lower())
    print 'gutenberg.words() has', len(words), 'unique caseless words'
    return words

print 'loading gutenburg corpus...'
sentences = []
for sentence in gutenberg.sents():
    sentences.append(downcase(sentence))

trigger = sys.argv[1:]
target = longest_element(trigger).lower()
last_target = None

while target != last_target:
    matched_sentences = []
    for sentence in sentences:
        if target in sentence:
            matched_sentences.append(sentence)

    print '===', target, 'matched', len(matched_sentences), 'sentences'
    longestSentence = longest_element(matched_sentences)
    print ' '.join(longestSentence)

    trigger = longestSentence
    last_target = target
    target = longest_element(trigger).lower()

ただし、サンプル文を考えると、2サイクルで固定に達します。

$ python nltkgut.py コードのセイン
ローディング グーテンブルク コーパス...
=== ターゲットのセインは 24 の文に一致した
ノルウェー自身、ひどい数で、その最も不誠実な裏切り者、コーダーのセインに助けられて、そのベローナまで、小さな紛争を始めました '
s花婿 , 証明 の ラップ , 自己 比較 で 彼 に 対峙 し , 点 対 点 , 反抗 的 な 軍隊 は 軍隊 を 獲得 し , 彼 の 甘い 精神 を 抑制 し た .
ノルウェー 自身 , 恐るべき 人数 で , その 最も 不誠実 な 裏切り 者 で ある コーダー の 領主 に 助け られ て , 悲惨 な 争い を 始め た . arme , 彼の lauish 精神 を 抑制 : そして 結論 と し て , 勝利 は vs に 落ち た .

最後の問題への応答の問題の一部は、それがあなたが尋ねたことを実行したが、あなたが答えを望んでいたよりも具体的な質問をしたことです. したがって、応答は、あなたが理解しているかどうかわからない、かなり複雑なリスト式で行き詰まりました。print ステートメントをもっと自由に使用し、それが何をするかわからない場合はコードをインポートしないことをお勧めします。リスト式をアンラップしているときに、(前述のように) コーパスの単語リストを使用したことがないことがわかりました。関数も役立ちます。

于 2010-08-26T05:49:44.297 に答える
0

ループの外側で「split_str」を割り当てているため、元の値を取得して保持します。while ループの最初に割り当てる必要があるため、毎回変更されます。

import nltk

from nltk.corpus import gutenberg

triggerSentence = raw_input("Please enter the trigger sentence: ")#get input str

longestLength = 0

longestString = ""

montyPython = 1

while montyPython:
    #so this is run every time through the loop
    split_str = triggerSentence.split()#split the sentence into words

    #code to find the longest word in the trigger sentence input
    for piece in split_str:
        if len(piece) > longestLength:
            longestString = piece
            longestLength = len(piece)


    listOfSents = gutenberg.sents() #all sentences of gutenberg are assigned -list of list format-

    listOfWords = gutenberg.words()# all words in gutenberg books -list format-
    # I tip my hat to Mr.Alex Martelli for this part, which helps me find the longest sentence
    lt = longestString.lower() #this line tells you whether word list has the longest word in a case-insensitive way. 

    longestSentence = max((listOfWords for listOfWords in listOfSents if any(lt == word.lower() for word in listOfWords)), key = len)
    #get longest sentence -list format with every word of sentence being an actual element-

    longestSent=[longestSentence]

    for word in longestSent:#convert the list longestSentence to an actual string
        sstr = " ".join(word)
    print triggerSentence + " "+ sstr
    triggerSentence = sstr
于 2010-08-26T04:07:11.470 に答える