NLTK
Данная статья была создана в рамках учебного задания.
В настоящее время задание завершено и проверено. Данная страница может свободно правиться другими участниками NLPub. |
nltk (Natural Language ToolKit) — пакет библиотек и программ для символьной и статистической обработки естественного языка, написанных на языке программирования Python. Сопровождается обширной документацией, включая книгу с объяснением основных концепций, стоящих за теми задачами обработки естественного языка, которые можно выполнять с помощью NLTK.
Установка
pip
pip install nltk
conda
conda install -c anaconda nltk
Использование
Загрузка данных
Скачиваем данные, необходимые для работы библиотеки:
import nltk
nltk.download('popular')
Аргумент popular
скачивает часто используемые компоненты (данные, словари, заранее обученные модели). Вместо него можно написать аргумент all
, который скачает все доступные пакеты, или имя конкретного пакета.
Чтобы исследовать доступное, можно воспользоваться особым интерфейсом:
>>> import nltk
>>> nltk.download()
NLTK Downloader ---------------------------------------------------------------------------
d) Download l) List u) Update c) Config h) Help q) Quit ---------------------------------------------------------------------------
Downloader> l Packages:
[ ] abc................. Australian Broadcasting Commission 2006
[ ] alpino.............. Alpino Dutch Treebank
[ ] averaged_perceptron_tagger Averaged Perceptron Tagger
[ ] averaged_perceptron_tagger_ru Averaged Perceptron Tagger (Russian)
[ ] basque_grammars..... Grammars for Basque
...
Деление текста на предложения
Для разбиения на предложения используем nltk.sent_tokenize
.
У этой функции есть параметр language
, по-умолчанию 'english'. Замена языка на 'russian' иногда может помочь корректно разделить предложения:
>>> text = "Ай да А.С. Пушкин! Ай да хитрец!"
>>> nltk.sent_tokenize(text)
['Ай да А.С.', 'Пушкин!', 'Ай да хитрец!']
>>> nltk.sent_tokenize(text, language="russian")
['Ай да А.С. Пушкин!', 'Ай да хитрец!']
Однако использование этого значения параметра иногда может привести к неожиданным ошибкам:
>>> text = "Ты плохой муж. Я бы этим особо не хвастался."
>>> nltk.sent_tokenize(text)
['Ты плохой муж.', 'Я бы этим особо не хвастался.']
>>> nltk.sent_tokenize(text, language="russian")
['Ты плохой муж. Я бы этим особо не хвастался.']
Токенизация
Для токенизации используем nltk.word_tokenize
.
У этой функции также есть параметр language
, по-умолчанию 'english' и который тоже можно заменить на 'russian'.
>>> text = "Всё самое лучшее случается неожиданно."
>>> nltk.word_tokenize(text)
['Всё', 'самое', 'лучшее', 'случается', 'неожиданно', '.']
Примеров различий между методами для разных языков найти не удалось, поэтому, возможно, пока всё работает с языком по-умолчанию, то лучше использовать так.
Простое разбиение текста на токены:
import nltk
from nltk.corpus import stopwords
from string import punctuation
russian_stopwords = stopwords.words("russian")
text = "Ты не забывай, что у меня в голове опилки. Длинные слова меня только огорчают!"
tokens = nltk.word_tokenize(text.lower())
tokens = [token for token in tokens if token not in russian_stopwords and token not in punctuation]
В этом примере текст переводится в нижний регистр с помощью стандартной функции lower
.
После разбиения текста на токены, из их списка удаляется пунктуация по словарю string.punctuation
и удаляются стоп-слова в русском языке по словарю, который получаем из nltk.corpus.stopwords
[1].
В модуле nltk.tokenize
есть множество классов токенизаторов и функции nltk.sent_tokenize
и nltk.word_tokenize
на самом деле являются обертками, которые делают вызовы к этим классам.
PunktSentenceTokenizer
Класс, разбивающий текст на предложения, к которому под капотом обращается функция nltk.sent_tokenize
. Использует алгоритм без учителя для построения модели сокращённых слов, словосочетаний и слов, начинающих предложения, а затем использует эту модель для поиска границ предложений.
>>> from nltk.tokenize import PunktSentenceTokenizer
>>> tokenizer = PunktSentenceTokenizer()
>>> text = 'В этом предложении пять слов. А вот еще пять слов. Предложения из пяти слов хорошие.'
>>> tokenizer.tokenize(text)
['В этом предложении пять слов.', 'А вот еще пять слов.', 'Предложения из пяти слов хорошие.']
TreebankWordTokenizer
Класс используется для разделения предложений на слова и вызывается под капотом в функции nltk.word_tokenize
.
Он предполагает, что текст уже был разделён на предложения и выполняет следующие шаги:
- Разделяет стандартные сокращения, например don't -> do n't and they'll -> they 'll
- Рассматривает большинство знаков препинания как отдельные токены
- Отделяет запятые и одинарные кавычки, если за ними следует пробел
- Отделяет точки в конце предложений
>>> from nltk.tokenize import TreebankWordTokenizer
>>> s = '''Good muffins cost $3.88\nin New York. Please buy me\ntwo of them.\nThanks.'''
>>> TreebankWordTokenizer().tokenize(s)
['Good', 'muffins', 'cost', '$', '3.88', 'in', 'New', 'York.', 'Please', 'buy', 'me', 'two', 'of', 'them.', 'Thanks', '.']
>>> s = "They'll save and invest more."
>>> TreebankWordTokenizer().tokenize(s)
['They', "'ll", 'save', 'and', 'invest', 'more', '.']
>>> s = "hi, my name can't hello,"
>>> TreebankWordTokenizer().tokenize(s)
['hi', ',', 'my', 'name', 'ca', "n't", 'hello', ',']
TweetTokenizer
Токенизатор для твитов (не удаляет хэштеги и знаки пунктуации).
>>> from nltk.tokenize import TweetTokenizer
>>> tknzr = TweetTokenizer()
>>> s0 = "This is a cooool #dummysmiley: :-) :-P <3 and some arrows < > -> <--"
>>> tknzr.tokenize(s0)
['This', 'is', 'a', 'cooool', '#dummysmiley', ':', ':-)', ':-P', '<3', 'and', 'some', 'arrows', '<', '>', '->', '<--']
MWETokenizer
Принимает текст, который уже был разбит на токены и объединяет выражения из нескольких слов в один токен, используя словарь.
>>> from nltk.tokenize import MWETokenizer
>>> tokenizer = MWETokenizer([('a', 'little'), ('a', 'little', 'bit'), ('a', 'lot')])
>>> tokenizer.add_mwe(('in', 'spite', 'of'))
>>> tokenizer.tokenize('Testing testing testing one two three'.split())
['Testing', 'testing', 'testing', 'one', 'two', 'three']
>>> tokenizer.tokenize('This is a test in spite'.split())
['This', 'is', 'a', 'test', 'in', 'spite']
>>> tokenizer.tokenize('In a little or a little bit or a lot in spite of'.split())
['In', 'a_little', 'or', 'a_little_bit', 'or', 'a_lot', 'in_spite_of']
TextTilingTokenizer
Используется для разделения текста на абзацы.
import nltk
nltk.download('gutenberg')
alice = nltk.corpus.gutenberg.raw('carroll-alice.txt')
tokenizer = nltk.tokenize.TextTilingTokenizer()
tiles = tokenizer.tokenize(alice[140309 : ])
StanfordTokenizer
Интерфейс для Stanford Tokenizer (работает только с английским языком).
>>> from nltk.tokenize import StanfordTokenizer
>>> s = "Good muffins cost $3.88\nin New York. Please buy me\ntwo of them.\nThanks."
>>> StanfordTokenizer().tokenize(s)
['Good', 'muffins', 'cost', '$', '3.88', 'in', 'New', 'York', '.', 'Please', 'buy', 'me', 'two', 'of', 'them', '.', 'Thanks', '.']
>>> s = "The colour of the wall is blue."
>>> StanfordTokenizer(options={"americanize": True}).tokenize(s)
['The', 'color', 'of', 'the', 'wall', 'is', 'blue', '.']
WordPunctTokenizer
Разделяет текст на последовательности алфавитных и неалфавитных символов с помощью регулярного выражения \w+|[^\w\s]+
.
>>> from nltk.tokenize import WordPunctTokenizer
>>> s = "Good muffins cost $3.88\nin New York. Please buy me\ntwo of them.\n\nThanks."
>>> WordPunctTokenizer().tokenize(s)
['Good', 'muffins', 'cost', '$', '3', '.', '88', 'in', 'New', 'York',
'.', 'Please', 'buy', 'me', 'two', 'of', 'them', '.', 'Thanks', '.']
Прочие классы
nltk.tokenize.RegexpTokenizer
— разделяет текст с помощью регулярного выражения, которое необходимо самостоятельно задать.nltk.tokenize.SExprTokenizer
— разделяет текст, состоящий из S-выражений.nltk.tokenize.SpaceTokenizer
— разделяет токены по пробелам аналогичноs.split(' ')
.nltk.tokenize.TabTokenizer
— разделяет токены по символам табуляции аналогичноs.split('\t')
.nltk.tokenize.LineTokenizer
— разделяет токены по символам переноса строки аналогичноs.split('\n')
.nltk.tokenize.WhitespaceTokenizer
— разделяет токены по символам пробела, табуляции или переноса строки аналогичноs.split()
.nltk.tokenize.BlanklineTokenizer
— разделяет токены используя в качестве разделителя любые последовательности пробелов и табуляций.
NLTK и русский язык
Данная статья является непроверенным учебным заданием.
До указанного срока статья не должна редактироваться другими участниками NLPub. По его окончании любой участник вправе исправить данную статью по своему усмотрению и удалить данное предупреждение, выводимое с помощью шаблона {{Задание}}. См. также методические указания наших коллег с MachineLearning.ru по использованию Вики-ресурсов в учебном процессе. |
Ссылки
https://www.nltk.org/ — официальный сайт и документация
См. также
Примечания
- ↑ В реальности токенизация может использовать капитализацию, а проверку по списку стоп-слов стоит делать после приведения токенов к словарной форме.