THE ISSUE OF TEXT TOKENIZATION

Research article
DOI:
https://doi.org/10.18454/IRJ.2016.48.070
Issue: № 6 (48), 2016
Published:
2016/06/17
PDF

Гречачин В. А.

ORCID: 0000-0002-1595-0995, Аспирант, Башкирский государственный университет

К ВОПРОСУ О ТОКЕНИЗАЦИИ ТЕКСТА

Аннотация

Предметом исследования данной статьи являются инструменты обработки естественных языков, необходимые для токенизации текста. В статье рассмотрены NLTK (Natural language toolkit) и регулярные выражения. На конкретном примере рассмотрены возможности этих инструментов. В качестве среды программирования использован язык Python. Кроме того, рассмотрена проблема гибкости инструментов токенизации текста. Анализ возможностей NLTK и регулярных выражений позволил сделать выводы о гибкости рассматриваемых инструментов.

Ключевые слова: токенизация, обработка естественных языков, регулярные выражения, Python.

Grechachin V. A.

ORCID: 0000-0002-1595-0995, Postgraduate student, Bashkir State University

THE ISSUE OF TEXT TOKENIZATION

Abstract

The research subject of this article are the tools of natural language processing for text tokenization. The article considers NLTK (Natural language toolkit) and regular expressions. A specific example describes the possibilities of these tools. Python used as the programming environment for NLP. In addition, the article describes the problem of the flexibility of tokenization tools of the text. The analysis of possibilities of NLTK and regular expressions allowed us to draw conclusions about the flexibility of the reporting tools.

Keywords: tokenization, natural language processing, regular expressions, Python.

На сегодняшний день существует множество способов токенизировать текст, то есть разбить электронный текст на отдельно значимые единицы для последующей компьютерной обработки этих единиц. Существуют различные программы-токенизаторы, например, Stanford Tokenizer или специальные библиотеки, например, NLTK. Зачастую у разработчиков лингвистических корпусов возникают определенные требования к токенизации текста, которые не способны удовлетворить существующие программы и библиотеки. В данной статье мы будем рассматривать наиболее гибкий инструмент для токенизации текста – регулярные выражения, покажем преимущества этого инструмента.

Для токенизации мы будем использовать компьютер с установленными Python версии 3.4, который обладает встроенными регулярными выражениями, и библиотекой NLTK (Natural Language Toolkit). «NLTK представляет собой набор инструментов для Python, который направлен на работу с естественными языками» [2].

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

«Этот мудреный и хлопотливый «случай» (как выражался сам Тоцкий) начался очень давно, лет восемнадцать этак назад. Рядом с одним из богатейших поместий Афанасия Ивановича, в одной из срединных губерний, бедствовал один мелкопоместный и беднейший помещик. Это был человек замечательный по своим беспрерывным и анекдотическим неудачам, – один отставной офицер, хорошей дворянской фамилии, и даже в этом отношении почище Тоцкого, некто Филипп Александрович Барашков. Весь задолжавшийся и заложившийся, он успел уже наконец после каторжных, почти мужичьих трудов устроить кое-как свое маленькое хозяйство удовлетворительно». [1] Ф. М. Достоевский «Идиот», 1869 г.

Сперва мы запускаем Python 3.4 и перед нами возникает интрепретатор, куда мы должны вводить команды. Попробуем произвести автоматическую токенизацию с помощью NLTK. Для этого нам нужно ввести серию команд (читатель может воспроизвести все описанное здесь на своем компьютере, установив необходимое ПО, создав текстовый файл text.txt в личной папке пользователя и скопировав в него приведенную выше последовательность символов):

import nltk, re                                       #(1)

from nltk import word_tokenize      #(2)

f = open('Текст.txt')                             #(3)

raw = f.read()                                        #(4)

tokens = word_tokenize(raw)           #(5)

Командой (1) мы импортируем в Python библиотеку NLTK и регулярные выражения (re – regular expressions), которые пригодятся нам в дальнейшем. В (2) мы импортируем в Python функцию автоматической токенизации word_tokenize() из библиотеки NLTK. В (3) мы присваиваем переменной f значение для открытия документа Текст.txt. Далее, в (4) функция f.read() читает содержимое переменной f которое мы присваиваем переменной raw. Теперь значением переменной raw является строка, состоящая из данного текста. В (5) с помощью функции NLTK word_tokenize(raw) мы токенизируем текст, а значение, которое получилось после совершения этой операции мы присваиваем переменной tokens.  Теперь текст представляет собой список. Полученный список состоит из элементов, которые получились в результате деления строки на токены. Теперь мы можем помечать элементы тэгами, подсчитывать элементы, группировать, убирать ненужные и добавлять необходимые. Например, мы можем убрать все неинформативные и стоп-слова просто вычитая их из текста. Для того, чтобы просмотреть элементы списка в доступном человеку виде, вводим в интерпретатор команду print(tokens) и получаем содержимое переменной tokens:

['«Этот', 'мудреный', 'и', 'хлопотливый', '«случай»', '(', 'как', 'выражался', 'сам', 'Тоцкий', ')', 'начался', 'очень', 'давно', ',', 'лет', 'восемнадцать', 'этак', 'назад', '.', 'Рядом', 'с', 'одним', 'из', 'богатейших', 'поместий', 'Афанасия', 'Ивановича', ',', 'в', 'одной', 'из', 'срединных', 'губерний', ',', 'бедствовал', 'один', 'мелкопоместный', 'и', 'беднейший', 'помещик', '.', 'Это', 'был', 'человек', 'замечательный', 'по', 'своим', 'беспрерывным', 'и', 'анекдотическим', 'неудачам', ',', '–', 'один', 'отставной', 'офицер', ',', 'хорошей', 'дворянской', 'фамилии', ',', 'и', 'даже', 'в', 'этом', 'отношении', 'почище', 'Тоцкого', ',', 'некто', 'Филипп', 'Александрович', 'Барашков', '.', 'Весь', 'задолжавшийся', 'и', 'заложившийся', ',', 'он', 'успел', 'уже', 'наконец', 'после', 'каторжных', ',', 'почти', 'мужичьих', 'трудов', 'устроить', 'кое-как', 'свое', 'маленькое', 'хозяйство', 'удовлетворительно»', '.', '[', '1', ']', 'Ф.', 'М.', 'Достоевский', '«Идиот»', ',', '1869', 'г', '.']

Квадратные скобки показывают, что это список. Внутри кавычек содержатся значения элементов. Каждый элемент обладает индексом, например, нулевой элемент этого списка - '«Этот'. Как мы видим, автоматический токенизатор NLTK полностью не справился со своей задачей. Перечислим ошибки, которые он допустил: '«Этот'; '«случай»'; 'удовлетворительно»'; '«Идиот»'; 'г', '.'. Кроме того, нам может понадобиться токенизировать ссылку [1] и Ф. М. Достоевский как один элемент, для поиска в тексте авторства, или же токенизировать дату целиком, например, 1869 г.

Теперь попробуем токенизировать данный текст с помощью регулярных выражений. Возвращаемся к переменной raw, которая содержит строку с текстом, в ней мы и будем проводить поиск подстрок. Для этого в интерпретатор Python вводим:

Text = re.findall(r'''(?x)                    #(1.1)     \w+(?:[-]\w+)                                   #(1.2)     |(?:\d+)\sг+\.                                   #(1.3)     |[А-Я]\.\s[А-Я]\.\s[А-Я][а-я]+     #(1.4)     01-06-2016 17-39-30                                    #(1.5)     |[«»]                                                  #(1.6)     |[-\.(]                                                 #(1.7)     |\S\w*                                               #(1.8) ''', raw)                                                  #(1.9)

Все, что находится между тройными кавычками в приведенной выше команде, есть «алгебраические обозначения, необходимые для спецификации набора строк, то есть для создания шаблонов» [1, с.18]. Поясним, что означают использованные нами выражения. С полным списком регулярных выражений можно ознакомиться в книге «Speech and Language Processing» Daniel Jurafsky, James H. Martin.

В (1.1) мы присваиваем значение переменной Text, которое получим в результате выполнения функции re.findall() на строке raw, с помощью регулярных выражений. Результатами поиска будут подстроки, которые станут элементами списка. Далее в скобках функции re.findall() мы задаем шаблон. В (1.2) мы ищем слова с дефисами, в нашем случае под этот шаблон попадает местоименное неопределенное наречие кое-как. Каждый отдельный шаблон мы разделяем дизъюнктором «|». В (1.3) мы ищем даты, извлекая подстроку, содержащую цифровой символ (\d), который может повторяться (+), за которым следует пробел (\s), после которого идет г и точка (\.), в нашем случае это 1869 г. В (1.4) мы извлекаем имена формата И. О. Фамилия. Выражение дает команду искать подстроку, содержащую заглавную букву от А до Я, после которой стоит точка, после идет пробел, после снова заглавная буква от А до Я с точкой и пробелом, а затем заглавная буква от А до Я, после которой идет строчная буква от а до я, которая может повторяться. В (1.5) ищем ссылки в квадратных скобках с указанием страниц и без. В (1.6) ищем все кавычки. В (1.7) тире, точки, запятые. В (1.8) несокращенные слова и цифры – даты, номера, цены и т. д. В (1.9) указываем, что поиск проводим в строке raw.

Теперь посмотрим, что у нас получилось с помощью функции print(Text):

print(Text)

['«', 'Этот', 'мудреный', 'и', 'хлопотливый', '«', 'случай', '»', '(', 'как', 'выражался', 'сам', 'Тоцкий', ')', 'начался', 'очень', 'давно', ',', 'лет', 'восемнадцать', 'этак', 'назад', '.', 'Рядом', 'с', 'одним', 'из', 'богатейших', 'поместий', 'Афанасия', 'Ивановича', ',', 'в', 'одной', 'из', 'срединных', 'губерний', ',', 'бедствовал', 'один', 'мелкопоместный', 'и', 'беднейший', 'помещик', '.', 'Это', 'был', 'человек', 'замечательный', 'по', 'своим', 'беспрерывным', 'и', 'анекдотическим', 'неудачам', ',', '–', 'один', 'отставной', 'офицер', ',', 'хорошей', 'дворянской', 'фамилии', ',', 'и', 'даже', 'в', 'этом', 'отношении', 'почище', 'Тоцкого', ',', 'некто', 'Филипп', 'Александрович', 'Барашков', '.', 'Весь', 'задолжавшийся', 'и', 'заложившийся', ',', 'он', 'успел', 'уже', 'наконец', 'после', 'каторжных', ',', 'почти', 'мужичьих', 'трудов', 'устроить', 'кое-как', 'свое', 'маленькое', 'хозяйство', 'удовлетворительно', '»', '.', '[1]', 'Ф. М. Достоевский', '«', 'Идиот', '»', ',', '1869 г.'] 

Как мы видим, данный текст токенизирован так, как нам необходимо. Теперь мы можем подсчитать количество всех элементов, отдельных элементов с помощью функции len(). Не составит труда построить конкорданс, построить график частотного распределения слов с помощью nltk.FreqDist(). Кроме того, теперь мы можем создать словарь слов текста с помощью функций set() и sorted(). Таким образом текст готов для дальнейших процедур NLP.

Литература

  1. Jurafsky, D. Speech and Langauge Processing / D. Jurafsky, J. H. Martin. – 2nd – New Jersey: Prentice Hall, 2008. – 1024 p.
  2. Natural Language Processing with Python [Электронный ресурс] URL: http://www.nltk.org/book/ch00.html (дата обращения05.2016).

References

  1. Jurafsky, D. Speech and Langauge Processing / D. Jurafsky, J. H. Martin. – 2nd – New Jersey: Prentice Hall, 2008. – 1024 p.
  2. Natural Language Processing with Python [Jelektronnyj resurs] URL: http://www.nltk.org/book/ch00.html (data obrashhenija05.2016).