Как обучить NLTK PunktSentenceTokenizer периодически? - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь разбить финансовые документы на предложения. У меня есть ~ 50.000 документов, содержащих простой текст на английском языке. Общий размер файла составляет ~ 2,6 ГБ.

Я использую NLTK PunktSentenceTokenizer со стандартным английским файлом рассола. Я дополнительно подправил его, предоставив дополнительные сокращения, но результаты все еще недостаточно точны.

Поскольку NLTK PunktSentenceTokenizer основывается на алгоритме без присмотра, разработанном Kiss & Strunk (2006), я пытаюсь обучить токенайзеру предложений на основе моих документов на основе формата данных обучения для nltk punkt .

import nltk.tokenize.punkt
import pickle
import codecs

tokenizer = nltk.tokenize.punkt.PunktSentenceTokenizer()
text = codecs.open("someplain.txt", "r", "utf8").read()
tokenizer.train(text)
out = open("someplain.pk", "wb")
pickle.dump(tokenizer, out)
out.close()

К сожалению, при запуске кода я получил ошибку, что недостаточно памяти. (Главным образом потому, что я сначала объединил все файлы в один большой файл.)

Теперь мои вопросы:

  1. Как я могу тренировать алгоритм по частям, и это приведет к снижению потребления памяти?
  2. Могу ли я использовать стандартный файл английских огурцов и продолжить обучение с этим уже обученным объектом?

Я использую Python 3.6 (Anaconda 5.2) в Windows 10 на компьютере с процессором Core I7 2600K и 16 ГБ ОЗУ.

1 Ответ

0 голосов
/ 03 сентября 2018

Как описано в исходном коде :

Punkt Sentence Tokenizer

Этот токенизатор делит текст на список предложений используя неконтролируемый алгоритм для построения модели для аббревиатуры слова, словосочетания и слова, начинающие предложения. Должно быть обучение на большой коллекции открытого текста на целевом языке прежде чем он может быть использован.

Не очень понятно, что на самом деле означает большая коллекция . В статье нет информации о кривых обучения (когда достаточно остановить процесс обучения, потому что было видно достаточно данных). Там упоминается корпус Wall Street Journal (в нем около 30 миллионов слов). Поэтому очень неясно, можете ли вы просто обрезать тренировочный корпус и иметь меньше следов памяти.

В вашей теме также есть открытый выпуск , в котором говорится о 200 ГБ ОЗУ и более. Как вы можете видеть, NLTK, вероятно, имеет плохую реализацию алгоритма, представленного Kiss & Strunk (2006).

Я не вижу, как его пакетировать, как вы можете видеть в сигнатуре функции train() -метод (NLTK версия 3.3):

def train(self, train_text, verbose=False):
    """
    Derives parameters from a given training text, or uses the parameters
    given. Repeated calls to this method destroy previous parameters. For
    incremental training, instantiate a separate PunktTrainer instance.
    """

Но, возможно, есть и другие проблемы, например, если вы сравните сигнатуру данной версии 3.3 с git-тегом версии 3.3, там - новый параметр finalize, который может быть полезен и указывает на возможный пакетный процесс или возможное слияние с уже обученной моделью :

def train(self, text, verbose=False, finalize=True):
    """
    Collects training data from a given text. If finalize is True, it
    will determine all the parameters for sentence boundary detection. If
    not, this will be delayed until get_params() or finalize_training() is
    called. If verbose is True, abbreviations found will be listed.
    """

В любом случае, я настоятельно рекомендую не использовать токенайзер предложений Punkt от NLTK, если вы хотите сделать токенизацию предложений вне игрового уровня. Тем не менее, если вы хотите придерживаться этого токенизатора, я бы просто рекомендовал использовать и данные модели, а не обучать новым моделям, если у вас нет сервера с огромной оперативной памятью.

...