NLTK - статистика очень медленная с большим корпусом - PullRequest
0 голосов
/ 02 декабря 2018

Я хотел бы видеть основную статистику о моем корпусе, такую ​​как счетчики слов / предложений, распределения и т. Д. У меня есть tokens_corpus_reader_ready.txt, который содержит 137 000 строк отмеченных примеров предложений в этом формате:

Zur / APPRART Zeit / NN kostenlos / ADJD aber / KON auch / ADV nur / ADV 11 / CARD кВт. / NN Zur / APPRART Zeit / NN anscheinend / ADJD kostenlos / ADJD ./$.
...

У меня также есть TaggedCorpusReader (), для которого у меня есть метод description ():

class CSCorpusReader(TaggedCorpusReader):
  def __init__(self):
    TaggedCorpusReader.__init__(self, raw_corpus_path, 'tokens_corpus_reader_ready.txt')

    def describe(self):
    """
    Performs a single pass of the corpus and
    returns a dictionary with a variety of metrics
    concerning the state of the corpus.

    modified method from https://github.com/foxbook/atap/blob/master/snippets/ch03/reader.py
    """
    started = time.time()

    # Structures to perform counting.
    counts = nltk.FreqDist()
    tokens = nltk.FreqDist()

    # Perform single pass over paragraphs, tokenize and count
    for sent in self.sents():
        print(time.time())
        counts['sents'] += 1

        for word in self.words():
            counts['words'] += 1
            tokens[word] += 1

    return {
        'sents':  counts['sents'],
        'words':  counts['words'],
        'vocab':  len(tokens),
        'lexdiv': float(counts['words']) / float(len(tokens)),
        'secs':   time.time() - started,
    }

Если я запускаю метод description в IPython следующим образом:

>> corpus = CSCorpusReader()
>> print(corpus.describe())

Между предложениями имеется примерно 7 секундная задержка:

1543770777.502544
1543770784.383989
1543770792.2057862
1543770798.992075
1543770805.819034
154437 *1022* 154437 *1022* 154437 *1022* 154437 *1022* 154437 *1022* 154437 *1022* 154437 *1022* 154437
1541024 *

Если я запускаю одно и то же с несколькими предложениями в tokens_corpus_reader_ready.txt, время вывода вполне разумно:

1543771884.739753
1543771884.74035
1543771884.7408729
1543771884.7413561
{sents ': 4,' words ': 212,' vocab ': 42,' lexdiv ': 5.0476190476190474,' secs ': 0.002869129180908203}

Откуда происходит это поведение и как его исправить?

Редактировать 1

Не каждый раз, когда получал доступ к самому корпусу, а работал со списками, время сокращалось примерно до 3 секунд на предложение, что все еще очень долго, хотя:

    sents = list(self.sents())
    words = list(self.words())

    # Perform single pass over paragraphs, tokenize and count
    for sent in sents:
        print(time.time())
        counts['sents'] += 1

        for word in words:
            counts['words'] += 1
            tokens[word] += 1

1 Ответ

0 голосов
/ 02 декабря 2018

Вот ваша проблема: для каждого предложения вы читаете весь корпус с помощью метода words().Неудивительно, что это занимает много времени.

for sent in self.sents():
    print(time.time())
    counts['sents'] += 1

    for word in self.words():
        counts['words'] += 1
        tokens[word] += 1

На самом деле предложение уже разбито на слова, так что вы имели в виду:

for sent in self.sents():
    print(time.time())
    counts['sents'] += 1

    for word in sent:
        counts['words'] += 1
        tokens[word] += 1
...