Время прочтения: 16 мин.
Перед тем, как набор данных можно будет использовать для создания модели машинного обучения, необходимо его подготовить. Предварительная обработка исходных данных играет важную роль для построения качественной модели.
Для подготовки данных при решении задач обработки естественного языка (англ. Natural Processing Language, NLP) в машинном обучении используются специальные обработчики исходного текста, которые позволяют разбить его на блоки, пригодные для подачи в модель. Такие обработчики называются токенизаторами (англ. Tokenize). Токенизация — самый первый шаг при обработке текста, результатом которого является набор (список) так называемых токенов (подстрок). Они могут быть предложениями, словами или даже отдельными символами. Получить список основных токенизаторов, входящих в состав этой библиотеки, можно, например, так:
from nltk import tokenize
tokenizer_list = [tkn for tkn in dir(tokenize) if tkn[0].isupper()]
print(len(tokenizer_list), tokenizer_list, sep='\n')
19
['BlanklineTokenizer', 'LegalitySyllableTokenizer', 'LineTokenizer', 'MWETokenizer', 'NLTKWordTokenizer', 'PunktSentenceTokenizer', 'RegexpTokenizer', 'ReppTokenizer', 'SExprTokenizer', 'SpaceTokenizer', 'StanfordSegmenter', 'SyllableTokenizer', 'TabTokenizer', 'TextTilingTokenizer', 'ToktokTokenizer', 'TreebankWordTokenizer', 'TweetTokenizer', 'WhitespaceTokenizer', 'WordPunctTokenizer']
Как видите, их 19.
Для начала рассмотрим группу токенизаторов, основанную на использовании регулярных выражений.
RegexpTokenizer
Этот токенизатор разбивает исходный текст на подстроки, используя регулярное выражение, передаваемое ему в качестве параметра. Например, для того, чтобы выбрать из текста только слова, написанные с заглавной буквы, можно использовать следующий код:
pattern = '[А-Я]\w+'
tok = tokenize.RegexpTokenizer(pattern)
print(tok.tokenize(text))
RegexpTokenizer имеет 4 параметра:
- pattern – шаблон регулярного выражения, используемый для создания токенизатора;
- gaps – логический параметр, определяющий, будет ли токенизатор искать сами токены (False) или разделители между ними (True). В первом случае результат работы токенизатора для указанного примера будет аналогичен выполнению команды re.findall(pattern, text) с использованием библиотеки re;
- discard_empty – необходимо установить в значение True, если необходимо отбросить пустые токены, сгенерированные токенизатором (возможно только в случае gaps == True);
- flags – флаги регулярного выражения, используемы при компиляции шаблона. По умолчанию установлены 3 флага: re.UNICODE | re.MULTILINE | re.DOTALL.
Библиотека NLTK содержит также несколько подклассов RegexpTokenizer, использующих заранее определенные регулярные выражения: WhitespaceTokenizer, BlanklineTokenizer, WordPunctTokenizer.
WhitespaceTokenizer
При помощи этого токенизатора исходный текст разделяется на группы символов, ограниченных пробелами (обычно, это отдельные слова, либо слова со следующими за ними знаками препинания).
tok = tokenize.WhitespaceTokenizer()
print(tok.tokenize(text))
Как правило, вместо этого рекомендуется просто использовать строковый метод split().
BlanklineTokenizer
Как понятно из названия, разбивает текст, рассматривая в качестве разделителя любую последовательность пустых строк (содержащих только символы пробела или табуляции). Для этого используется регулярное выражение ‘\s*\n\s*\n\s*’.
tok = tokenize.BlanklineTokenizer()
print(tok.tokenize(text))
WordPunctTokenizer
Преобразует текст в последовательность буквенных и неалфавитных символов с помощью регулярного выражения ‘\w+|[^\w\s]+’. Отличается от WhitespaceTokenizer тем, что отделяет знаки препинания и иные символы пунктуации от слова, за / перед которым они идут, и возвращает их в качестве отдельных токенов.
SExprTokenizer
Этот токенизатор используется для поиска в исходном тексте выражений в скобках. В частности, он делит строку на последовательность подстрок, являющихся выражениями в скобках (включая любые вложенные выражения в скобках) или другими токенами, разделенными пробелами. Следует отметить, что по умолчанию SExprTokenizer вызывает исключение ValueError, если используется для токенизации выражения с непарными круглыми скобками. Чтобы этого избежать, аргументу strict должно быть присвоено значение False. В этом случае любая непарная закрывающая скобка будет выделена в качестве самостоятельного токена. При этом непарная открывающая круглая скобка будет выделена в качестве токена вместе со всеми символами, оставшимися до конца строки. Также необходимо помнить, что отдельная обработка для исключения скобок, встречающихся внутри уже выделенных токенов, или следующих за символом обратной косой черты, не производится. На практике это выглядит так:
txt = '(a + b / (2 + y)) * c - x) + 25 / (87'
tok = tokenize.SExprTokenizer(strict=False)
print(len(tok.tokenize(txt)))
print(tok.tokenize(txt))
10
['(a + b / (2 + y))', '*', 'c', '-', 'x', ')', '+', '25', '/', '(87']
С помощью параметра parens можно изменять символы, используемые в качестве начала и окончания выражения (открывающие и закрывающие скобки).
Токенизатор SExprTokenizer удобно использовать для проверки правильной расстановки скобок в математических выражениях, а также при парсинге и обработке тестов, содержащих большое количество формул, выделяемых круглыми скобками или иными символами.
Следующая группа токенизаторов, входящих в состав библиотеки NLTK, носит название «простых» (simple) токенизаторов. Она включает в себя 3 токенизатора: SpaceTokenizer, TabTokenizer и LineTokenizer.
Они разделяют строки с помощью строкового метода split(). При этом в документации отдельно отмечается, что при токенизации с использованием определенной строки-разделителя следует использовать строковый метод split() напрямую, так как это более эффективно.
Простые токенизаторы, в основном, полезны, потому что используют стандартный интерфейс TokenizerI и поэтому могут применяться с любым программным кодом, который ожидает на входе токенизатор.
SpaceTokenizer
Разбивает строку на токены, используя в качестве разделителя пробел. Результат работы этого метода полностью совпадает с результатом метода s.split(‘ ‘).
TabTokenizer
Аналогичен SpaceTokenizer, только для разделения строки использует символ табуляции, что совпадает с применением метода s.split(‘\t’).
LineTokenizer
Аналогичен SpaceTokenizer, за исключением того, что для разделения строки использует символ новой строки (при необходимости может отбрасывать пустые строки). Его применение похоже на применение метода s.split(‘\n’).
LegalitySyllableTokenizer
Разбивает слова по слогам, основываясь на принципе правильности и максимизации наборов.
Принцип правильности (Legality Principle) – это не зависящий от используемого языка принцип, утверждающий, что начала и окончания слогов (не включая гласный звук) допустимы только в том случае, если они встречаются в качестве начал или окончаний слов в языке. Например, английское слово «admit» должно быть разложено на слоги как «ad—mit», поскольку слово «dm» изначально не встречается в английском языке. Этот принцип был впервые предложен в диссертации Даниэля Кана 1976 года «Слоговые обобщения в английской фонологии».
Кан утверждает, что существует «сильная тенденция к разложению слов на слоги таким образом, чтобы начальные кластеры имели максимальную длину, что соответствует общим ограничениям на кластеры согласных букв в начале слова». Следовательно, в дополнение к тому, что они являются правильными наборами, предпочтительнее самые длинные из них – «Максимизация наборов».
Реализация указанного принципа в библиотеке NLTK по умолчанию предполагает набор английских гласных, но атрибут vowel позволяет установить набор гласных букв любого другого алфавита для использования. Как допустимый набор гласных, так и текстовый корпус слов на соответствующем языке необходимы для определения правильного разложения слов на слоги.
Принцип правильности с максимизацией наборов является универсальным алгоритмом разбиения слов на слоги, хотя это не означает, что он работает одинаково для разных языков.
Этот токенайзер работает с отдельными словами, поэтому исходный текст нужно предварительно обработать. Для этого можно воспользоваться любым удобным способом, например, описанным ранее WordPunctTokenizer. Также для корректной работы токенайзера потребуется словарь слов русского языка и список гласных букв, передаваемый через параметр vowel. Словарь можно загрузить с сайта http://opencorpora.org (понадобится небольшая обработка файла, чтобы вытащить из него только слова без дополнительной информации – предполагается, что текстовый файл со словарем извлечен из архива и размещен в папке с Jupyter Notebook):
with open('dict.opcorpora.txt', 'r', encoding='utf-8') as f:
all_line = f.readlines()
clear_words = [line.split('\t')[0].lower() for line in all_line if len(line.split('\t')) > 1]
print(len(clear_words))
5140577
Получившийся словарь содержит более 5 миллионов слов. Осталось только провести токенизацию каждого слова из набора предварительно полученных на первом этапе слов:
tok = tokenize.LegalitySyllableTokenizer(clear_words, vowels='аеёиоуыэюя')
print([tok.tokenize(word) for word in text_words])
При создании объекта токенайзера я передал в качестве первого параметра список слов русского языка, полученный на предыдущем этапе, а в качестве второго параметра – строку, содержащую 10 гласных букв русского алфавита. Во второй строке кода формируется и выводится на экран список токенов для каждого слова из предварительно подготовленного списка. Можно разбивать на слоги и отдельные слова. Например, для слова «путешественник» результат получился такой:
print(tok.tokenize('путешественник'))
['пу', 'те', 'шест', 'вен', 'ник']
Несмотря на то, что при токенизации текста (отдельных слов) на русском языке при помощи LegalitySyllableTokenizer встречаются ошибки (слова разбиваются с нарушением норм русского языка, например, [‘г’, ‘уашь’], [‘з’, ‘вез’, ‘ды’], [‘ид’, ‘ея’]), в целом, токенизатор отрабатывает достаточно неплохо, и его применение может быть оправдано для решения задач обработки текста. Также не следует забывать, что при подготовке токенизатора можно использовать другие словари, содержащие большее количество слов с более качественной очисткой, что, теоретически, должно привести к улучшению работы токенизатора.
SyllableTokenizer
Это еще один токенизатор для разбиения слов на слоги. Его работа основана на принципе последовательности звучания (Sonority Sequencing Principle, SSP). Алгоритм SSP так же, как и алгоритм Legality Principle не зависит от используемого языка. Несмотря на то, что SSP – это универсальный алгоритм разбиения лов на слоги, это не означает, что он одинаково работает для разных языков. Например, следует иметь ввиду, что в русском языке есть слоги, которые нарушают SSP.
SSP был предложен Отто Джесперсоном в 1904 году. В соответствии с ним о звучности фонемы судят по открытости губ. Разрывы слогов происходят перед падениями звучности.
Реализация алгоритма по умолчанию использует английский алфавит, но параметром sonority_hiearchy можно изменить его на любой другой алфавит, необходимый для использования. Важно отметить, что если выбран вариант с собственной иерархией звучания, в котором гласные охватывают более одного уровня, их следует указывать отдельно для атрибута класса vowels. Для демонстрации примера использования снова разобью на слоги слово «путешественник»:
tok = tokenize.SyllableTokenizer(lang='ru', sonority_hierarchy=['аеёиоуыэюя', 'мн', 'вфзсжшх', 'рптщ'])
print(tok.tokenize('путешественник'))
['пу', 'те', 'шес', 'твен', 'ник']
В качестве первого параметра lang я указал русский язык, а второй параметр принимает список строк, содержащих наборы букв по порядку – гласные (vowels), носовые согласные (nasals), щелевые / фрикативные согласные (fricatives) и стоповые согласные (stops).
Мне не удалось найти полный перечень стоповых согласных для русского языка, да и в правильности списков носовых и фрикативных согласных я тоже не уверен. Возможно, поэтому выбранное слово было разбито на слоги не совсем верно. При решении своих задач вы можете настроить параметры более качественно, что должно привести к лучшему результату.
MWETokenizer (Multi-Word Expression Tokenizer)
MWETokenizer берет строку, которая уже была разделена на токены, и повторно токенизирует ее, объединяя выражения из нескольких слов в отдельные токены, используя словарь MWE. Это может быть полезно в том случае, когда в тексте встречаются устойчивые выражения или именованные сущности, состоящие из нескольких слов.
txt = 'Липецкая область вошла в число лидеров в исполнении поручения Президента России.'
tok = tokenize.WordPunctTokenizer()
text_words = tok.tokenize(txt)
print(len(text_words), text_words)
tok = tokenize.MWETokenizer(separator=' ')
tok.add_mwe(('Липецкая', 'область'))
tok.add_mwe(('Президента', 'России'))
print(len(tok.tokenize(text_words)), tok.tokenize(text_words))
12 ['Липецкая', 'область', 'вошла', 'в', 'число', 'лидеров', 'в', 'исполнении', 'поручения', 'Президента', 'России', '.']
10 ['Липецкая область', 'вошла', 'в', 'число', 'лидеров', 'в', 'исполнении', 'поручения', 'Президента России', '.']
В этом примере текст сначала разбивается на список из 12 отдельных токенов (слова). После этого создается экземпляр MWETokenizer, параметр separator которого указывает, какой символ будет являться связующим для объединяемых в дальнейшем токенов. Метод add_mwe добавляет в словарь токенизатора выражение, состоящее из нескольких слов. Результат применения MWETokenizer к полученному ранее списку слов содержит объединенные на основании словаря токены: «Липецкая область» и «Президента России».
Недостатки использования MWETokenizer очевидны. Ему необходим предварительно заданный список выражений из нескольких слов для определения, существует ли какое-либо из них в тексте. Кроме того он чувствителен к регистру слов, а также не определяет различные словоформы и написания одного и того же слова.
При решении реальных задач, связанных с выделением устойчивых выражений в тексте, старайтесь применять и другие инструменты, сглаживающие недостатки MWETokenizer. Например, для автоматического обнаружения устойчивых выражений и распространенных фраз можно попробовать models.phrases из библиотеки gensim. Он просматривает текстовый корпус и определяет наиболее часто встречающиеся слова, расположенные рядом (например, «машинное обучение»). Более подробно с описанием метода и примерами его использования можно ознакомиться здесь и здесь.
TextTilingTokenizer
TextTiling – это метод автоматического разделения полноразмерных текстовых документов на последовательные блоки, состоящие из нескольких абзацев, которые представляют собой отрывки или подтемы. Алгоритм предполагает, что в ходе описания подтемы используется определенный набор слов, и когда подтема изменяется, значительная часть словарного запаса также изменяется. Подтемы обнаруживаются на основе количественного лексического анализа закономерностей совместной встречаемости. Авторы алгоритма обнаружили, что результат разбиения хорошо соответствует человеческим суждениям о границах основных подтем статей в научных журналах.
Применение метода описано в статье «Subtopic Structuring for Full-Length Document Access» (Marti A. Hearst and Christian Plaunt, Proceedings of the 16th Annual International ACM/SIGIR Conference, Pittsburgh, PA, 1993.), затрагивающей вопрос важности распознавания структуры полноформатного текста для целей поиска информации. Описанный в ней эксперимент демонстрирует полезность обработки полноформатных документов, как состоящих из последовательности локально сконцентрированных обсуждений. Идея состоит в том, чтобы разделить документы на мотивированные сегменты, получить сегменты с наивысшими баллами, которые наиболее точно соответствуют запросу, а затем суммировать баллы для всех сегментов, взятых из одного и того же документа. Это приводит к тому, что наиболее важные части документов вносят свой вклад в итоговую оценку документа. Для более полного погружения в тему дополнительно можно почитать статьи здесь, здесь и здесь.
TextTilingTokenizer принимает текст и преобразует его в список, содержащий отдельные блоки. При этом можно указывать различные параметры. Например: w (int) – размер псевдопредложения, на которые разбивается исходный текст; k (int) – размер блока (в предложениях), используемого в методе сравнения блоков. Исходный текст можно очистить от стоп-слов, используя параметр stopwords (list(str)) – список стоп-слов для фильтрации исходного текста (по умолчанию используется корпус стоп-слов NLTK на английском языке). Для подбора оптимальных параметров w и k можно, например, написать цикл, перебирающий различные сочетания. Для этого воспользуемся функцией product из библиотеки itertools:
from nltk.corpus import stopwords
stopW = stopwords.words('russian')
from itertools import product
w = [1, 2, 3, 4]
k = [1, 2, 3]
for wi, ki in product(w, k):
tok = tokenize.TextTilingTokenizer(w=wi, k=ki, stopwords=stopW)
try:
text_words = tok.tokenize(str_big_text)
if len(text_words) > 1:
print(wi, ki, len(text_words))
except:
pass
После анализа результатов можно выбрать наиболее подходящее для решаемой задачи сочетание параметров.
ToktokTokenizer
Токенизатор Toktok – это простой универсальный токенизатор, на вход которого подается по одному предложению в строке.
Согласно документации он был протестирован и дает достаточно хорошие результаты для английского, персидского, русского, чешского, французского, немецкого, вьетнамского, таджикского и некоторых других языков. Входные данные должны быть представлены в кодировке UTF-8.
Работа токенизатора основана на последовательном применении к исходному тексту списка регулярных выражений. С их помощью происходят, например, замена неразрывных пробелов обычными, замена знака многоточия единичной точкой, расстановка пробелов после открывающих и перед закрывающими знаками препинания. В итоговой строке удаляются начальные и конечные пробелы, а сама строка преобразуется в кодировку Unicode.
Рекомендуется проверять и дополнительно очищать текст после применения ToktokTokenizer, например, от знаков препинания и иных символов – бывает, что они «приклеиваются» к словам.
TweetTokenizer
Это токенизатор с поддержкой особенностей коротких сообщений Twitter, разработанный для гибкой и простой адаптации к новым предметным областям и задачам. Основная логика его работы заключается в следующем:
- Определяется список регулярных выражений, для поиска в исходном тексте гиперссылок, смайликов, телефонных номеров, имен пользователей Twitter, хештегов и др.
- Регулярные выражения помещаются по порядку в скомпилированный объект регулярного выражения, называемый word_re.
- Выполняется токенизация с помощью метода word_re.findall(s), где s – строка, исходного текста.
При создании экземпляров объектов токенизатора можно задать несколько параметров. Например, параметр reduce_len определяет, будет ли токенизатор заменять последовательности повторяющихся более 3 раз символов на последовательность из трех символов («Привееееееет» -> «Привееет»). А параметр strip_handles определяет необходимость удаления из исходного текста имен пользователей Twitter, начинающихся со знака @ («Привет, @username» -> «Привет, »).
TreebankWordTokenizer
В лингвистике Treebank – это проанализированный текстовый корпус, который аннотирует синтаксическую или семантическую структуру предложения. В начале 1990-х годов создание проанализированных корпусов текста произвело революцию в компьютерной лингвистике. Использование этих данных получило большое значение с момента публикации первого крупномасштабного банка деревьев – Penn Treebank.
Токенизатор Treebank использует регулярные выражения для разделения текста на слова так, как это реализовано в Penn Treebank. Для этого последовательно выполняются следующие шаги:
- разделяются стандартные сокращения, например, «don’t» -> »do n’t» или «they’ll» -> «they ‘ll» для английского языка;
- большинство знаков препинания, разделяются на отдельные токены;
- разделяются запятые и одинарные кавычки, если за ними следует пробел;
- отделяются точки, которые проставлены в конце строк.
Вызов токенизатора осуществляется стандартным способом. Какие-либо параметры отсутствуют. Стоит отметить, что у этого токенизатора имеется метод, возвращающий не токены, а их границы, что может быть удобно в некоторых случаях. В результате возвращается объект-генератор:
txt = 'Липецкая область вошла в число лидеров в исполнении поручения Президента России.'
tok = tokenize.TreebankWordTokenizer()
print(list(tok.span_tokenize(txt)))
[(0, 8), (9, 16), (17, 22), (23, 24), (25, 30), (31, 38), (39, 40), (41, 51), (52, 61), (62, 72), (73, 79), (79, 80)]
Результат токенизации TreebankWordTokenizer можно инвертировать с помощью TreebankWordDetokenizer, который использует обратные операции регулярных выражений, соответствующих регулярным выражениям токенизатора Treebank.
NLTKWordTokenizer
Это улучшенный вариант TreebankWordTokenizer, включающий несколько адаптированных списков сокращений.
Стоит отметить, что, по сравнению с TreebankWordTokenizer, NLTKWordTokenizer является «деструктивным» токенизатором. То есть, применяемые регулярные выражения приводят исходный текст в состояние, не поддающееся восстановлению. Можно применить TreebankWordDetokenizer.detokenize к результату токенизации NLTKDestructiveWordTokenizer.tokenize, но нет никаких гарантий возврата к исходному тексту.
StanfordSegmenter
Некоторые языки требуют более обширной предварительной обработки токенов, которая обычно называется сегментацией. Например, StanfordSegmenter предназначен для «токенизации» или «сегментации» слов китайского или арабского текста (также можно использовать для английского, французского и испанского языков).
Арабский – язык, основанный на корнях и шаблонах, с множеством связанных клитик – синтаксически свободных, но фонетически несамостоятельных грамматических элементов. Например, частицы «не», «же», «ли» или предлоги «у», «на», «в» в русском языке. Эти клитики включают притяжательные, местоимения и дискурсивные связки. Арабский сегментатор отделяет клитику от слов (только). Сегментирование клитики, прикрепленной к словам, снижает лексическую разрозненность и упрощает синтаксический анализ. StanfordSegmenter для арабского варианта обрабатывает исходный текст в соответствии со стандартом Penn Arabic Treebank 3.
В китайском языке обычно не пишутся пробелы между словами (как и в некоторых других языках). StanfordSegmenter разделяет китайский текст на последовательность слов, определенную в соответствии со стандартом сегментации.
Сам токенизатор доступен для загрузки на странице https://nlp.stanford.edu/software/segmenter.html#Download. Загружаемый файл представляет собой архив, содержащий файлы модели, скомпилированного кода и исходных файлов. Также в архив включены простые скрипты с примерами вызова segmenter.
Чтобы токенизатор запустился (на ОС Windows), необходимо установить Java 1.8+. Также может понадобиться указать в параметре path_to_jar путь к jar-архиву с кодом токенизатора. Попробуем обработать текст на арабском языке:
tok = tokenize.StanfordSegmenter(path_to_jar='.\stanford-segmenter-2020-11-17\stanford-segmenter-4.2.0.jar')
tok.default_config('ar')
sent = 'لكل شخص الحق في التعلم. ويجب أن يكون التعليم في مراحله الأولى والأساسية على الأقل بالمجان، وأن يكون التعليم الأولي إلزاميا وينبغي أن يعمم التعليم الفني والمهني، وأن ييسر القبول للتعليم العالي على قدم المساواة التامة للجميع وعلى أساس الكفاءة'
tok.segment(sent)
В результате текст разбивается на отдельные символы, что, теоретически, должно помочь при его дальнейшей обработке в задачах машинного обучения.
PunktSentenceTokenizer
Этот токенизатор разделяет текст на список предложений, используя алгоритм обучения без учителя (Unsupervised learning) для построения модели слов-сокращений, словосочетаний и слов, с которых начинаются предложения. Прежде чем использовать, его необходимо обучить на большом наборе текстов, написанных на целевом языке. Однако для простоты можно загрузить предварительно обученную модель из библиотеки NLTK и использовать для токенизации текста ее:
text = 'Липецкая область вошла в число лидеров в исполнении поручения Президента России. А Рязанская область подписала соглашение о развитии сотрудничества с Республикой Беларусь'
tok = nltk.data.load('tokenizers/punkt/russian.pickle')
print(len(tok.tokenize(text)))
print(tok.tokenize(text))
2
['Липецкая область вошла в число лидеров в исполнении поручения Президента России.', 'А Рязанская область подписала соглашение о развитии сотрудничества с Республикой Беларусь']
Видно, что текст разбит на предложения правильно. Однако этот токенизатор предназначен для изучения параметров на текстах, аналогичных целевой предметной области, поэтому готовые модели могут не подойти для решения конкретной задачи.
ReppTokenizer
Токенизатор с использованием алгоритма REPP, описанного в статье « Tokenization: Returning to a Long Solved Problem – A Survey, Contrastive Experiment, Recommendations, and Toolkit» (авторы Rebecca Dridan и Stephan Oepen (2012)). Стоит отметить, что ссылка на статью в оригинальной документации неактуальна. В настоящее время статья размещена по адресу https://aclanthology.org/P12-2074.pdf.
В статье рассматриваются некоторые из часто игнорируемых тонкостей токенизации в стиле Penn Treebank и представляется новый инструментарий предварительной обработки на основе правил, который не только воспроизводит токенизацию Treebank с непревзойденной точностью (по словам авторов), но и поддерживает точные указатели на исходный текст и позволяет гибко настраивать различные варианты использования (например, для специфичных предметных областей). Запустить обработку текста с помощью ReppTokenize мне не удалось в связи с отсутствием исходных файлов с моделью и конфигурацией:
# Checks for the REPP binary and erg/repp.set config file.
--> 149 assert os.path.exists(_repp_dir + "/src/repp")
150 assert os.path.exists(_repp_dir + "/erg/repp.set")
Возможно, получится у вас. В любом случае, попробуйте.
Jupyter notebook с кодом из статьи размещен на github.
При написании статьи использовалась информация из официальной документации библиотеки NLTK, расположенной по адресу https://www.nltk.org/api/nltk.tokenize.html. Надеюсь, что моя статья поможет немного разобраться с различиями между токенизаторами. Также не забывайте, что можно быстро получить описание библиотек и методов, поставив перед их названием знак вопроса «?». Так вы найдете примеры использования и ссылку на файл с исходным кодом интересующего модуля.