Токенизация — это первый шаг в обработке текстовых данных. Без токенизации компьютеры не смогли бы понимать текст и находить в нем полезную информацию. Токенизаторы помогают преобразовать текст в данные, которые можно анализировать и использовать для решения различных задач, таких как классификация текстов, распознавание речи, машинный перевод и многие другие. Без них компьютерам было бы гораздо сложнее «понимать» и анализировать текстовые данные.

Пока всё понятно, правда? Если так, то идем дальше.

Популярные токенизаторы: кто кого перетопчит в борьбе за лучшую токенизацию?

Существует очень много токенизаторов, и каждый из них имеет свои «светлые» и «темные» стороны. Одни из них лучше справляются с определенными типами текстовых данных, а другие — с какими‑то ещё.

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

NLTK (Natural Language Toolkit)

NLTK (Natural Language Toolkit) — одна из самых известных библиотек для обработки текстовых данных на Python. Включает в себя несколько различных токенизаторов, но мы рассмотрим три: RegexpTokenizer, TreebankWordTokenizer и WhitespaceTokenizer.

RegexpTokenizer, TreebankWordTokenizer и WhitespaceTokenizer ‑- это три разных токенизатора, которые доступны в библиотеке NLTK (Natural Language Toolkit) для Python. Они используются для разделения текста на токены (отдельные слова или другие единицы текста) с помощью различных подходов.

RegexpTokenizer использует регулярные выражения для разделения текста на токены. Например, вы можете использовать его для разделения текста на слова, разделенные пробелами, или для разделения текста на слова, разделенные знаками препинания.

Вот пример с RegexpTokenizer для разделения текста на слова, разделенные пробелами:

from nltk.tokenize import RegexpTokenizer

text = "This is an example text."
tokenizer = RegexpTokenizer(r'\w+')
tokens = tokenizer.tokenize(text)
print(tokens)

Этот код выведет следующее:

This, is, an, example, text

TreebankWordTokenizer использует правила разметки корпуса Penn Treebank для разделения текста на токены. Он более точный, чем RegexpTokenizer, но может быть медленнее и сложнее в использовании.

Работает он так:

from nltk.tokenize import TreebankWordTokenizer

text = "This is an example text."
tokenizer = TreebankWordTokenizer()
tokens = tokenizer.tokenize(text)
print(tokens)

Вывод:

This, is, an, example, text

А вот WhitespaceTokenizer использует пробелы для разделения текста на токены. Хотя он и самый простой и быстрый из трех, но он может быть менее точным, чем другие токенизаторы.

Работает так:

from nltk.tokenize import WhitespaceTokenizer

text = "This is an example text."
tokenizer = WhitespaceTokenizer()
tokens = tokenizer.tokenize(text)
print(tokens)

Получаем:

This, is, an, example, text

SpaCy

SpaCy — другая популярная библиотека для обработки текстовых данных на Python. Известна своей высокой скоростью и точностью, а также поддержкой многих языков.

У SpaCy есть токенизатор DocBin, который может обрабатывать большие объемы текстовых данных.

Рассмотрим подробнее?

import spacy
from spacy.tokens import DocBin

# Загрузка модели spaCy
nlp = spacy.load("en_core_web_sm")

# Создание пустого объекта DocBin
doc_bin = DocBin()

# Тексты для токенизации
texts = [
    "Hello, world!",
    "This is a sample sentence.",
    "SpaCy is an awesome tool for NLP!",
    "I love working with natural language processing.",
]

# Токенизация каждого текста и добавление его в DocBin
for text in texts:
    doc = nlp(text)
    doc_bin.add(doc)

# Сохранение DocBin в файл
with open("processed_texts.spacy", "wb") as f:
    f.write(doc_bin.to_bytes())

Здесь мы используем DocBin, чтобы сохранить несколько документов (текстов) после их токенизации с помощью библиотеки spaCy. Мы загружаем модель en_core_web_sm из spaCy для токенизации текста. Затем мы создаем пустой объект DocBin и добавляем каждый документ в него с помощью метода add(). После того, как все документы добавлены, мы сохраняем DocBin в файл с расширением .spacy. Этот файл можно затем использовать для дальнейшей обработки или анализа текстов в spaCy.

Gensim

Gensim — это библиотека на языке Python, которая специализируется на алгоритмах анализа текстов и тематическом моделировании. Она предоставляет простой интерфейс для работы с текстовыми данными, включая функционал для векторизации текста, создания моделей тематического моделирования, сравнения текстов и других задач.

Одним из ключевых компонентов Gensim является Word2Vec, модель, предназначенная для создания векторных представлений слов на основе контекста, в котором они встречаются.

Рассмотрим пример использования Word2Vec в Gensim:

from gensim.models import Word2Vec

sentences = [["I", "love", "natural", "language", "processing"],
             ["Gensim", "is", "an", "awesome", "library", "for", "NLP"],
             ["Word2Vec", "creates", "word", "embeddings"]]

# Обучение модели Word2Vec
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)

# Получение векторного представления слова "Word2Vec"
vector = model.wv["Word2Vec"]
print(vector)

Этот код создает и обучает модель Word2Vec на небольшом корпусе текста, состоящем из трех предложений. Затем он получает векторное представление слова «Word2Vec» с помощью обученной модели и выводит полученный вектор.

В Gensim также доступны и другие модели, такие как LDA (Latent Dirichlet Allocation) для тематического моделирования, TF‑IDF для векторизации текста и другие.

Вот так, к примеру, мы будем использовать токенизацию и векторизацию текста с помощью TF‑IDF модели в библиотеке Gensim:

from gensim.sklearn_api import TfIdfTransformer
from nltk.tokenize import word_tokenize
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.datasets import fetch_20newsgroups

# Загрузка данных
data = fetch_20newsgroups(subset='train')['data']

# Токенизация текста
tokenized_data = [word_tokenize(text.lower()) for text in data]

# Преобразование токенизированных текстов в векторы с помощью CountVectorizer
count_vectorizer = CountVectorizer(tokenizer=lambda x: x, lowercase=False)
X_counts = count_vectorizer.fit_transform(tokenized_data)

# Преобразование векторов в TF-IDF векторы с помощью TfIdfTransformer из Gensim
tfidf = TfIdfTransformer()
X_tfidf = tfidf.fit_transform(X_counts)

# Печать TF-IDF векторов первого документа
print("TF-IDF вектор первого документа:")
print(X_tfidf[0])

Здесь мы используем fetch_20newsgroups, чтобы загрузить набор данных «20 Newsgroups» из библиотеки sklearn.datasets. Затем мы токенизируем текст с помощью word_tokenize из NLTK, приводим текст к нижнему регистру и преобразуем его в векторы с помощью CountVectorizer из scikit‑learn. Далее мы используем TfIdfTransformer из Gensim для преобразования этих векторов в TF‑IDF векторы. В конце мы печатаем TF‑IDF вектор первого документа в наборе данных.

TF‑IDF (Term Frequency‑Inverse Document Frequency) — это статистическая мера, используемая для оценки важности слова в контексте коллекции документов. TF‑IDF векторизация помогает выделить наиболее значимые слова в документе, учитывая их частоту в документе и обратную частоту встречаемости слова в корпусе документов.

Краткий сравнительный анализ токенизаторов: кто лучше, кто хуже, а кто просто неуловим?

Начнем с NLTK и SpaCy — двух из наиболее популярных библиотек для обработки текстовых данных на Python.

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

Представим себе, что вы работаете над проектом по анализу текстов в социальных сетях, и вам нужно токенизировать большое количество коротких текстов, таких как твиты. В этом случае SpaCy подходит лучше всего, так как он быстро и точно токенизирует тексты, даже если они содержат нестандартные сокращения и эмодзи.

NLTK, в свою очередь, может быть немного медленнее и менее точным в этом случае, поэтому не теряйте время.

Теперь давайте посмотрим на Gensim. Его лучше использовать для анализа и обработки текстовых данных различных типов: новостей, блогов и социальных сетей.

Например, в Gensim есть инструмент под названием Phrases, который может быть полезен для токенизации текстов, содержащих многофразовые выражения и идиомы.

Phrases — это модуль, который использует алгоритм моделирования языка для определения частоты встречаемости слов вместе и их последующего объединения в биграммы. Это полезно для классификации текстов и тематического моделирования, где важно учитывать контекст и смысл текста.

Пример использования Phrases для токенизации текста:

from gensim.models.phrases import Phrases, Phraser

sentences = [["I", "love", "natural", "language", "processing"],
             ["Gensim", "is", "an", "awesome", "library", "for", "NLP"],
             ["Word2Vec", "creates", "word", "embeddings"]]

# Обучение модели Phrases
bigram = Phrases(sentences, min_count=1, threshold=1)

# Преобразование текста с помощью Phraser
phrases = Phraser(bigram)

# Токенизация текста с учетом многофразовых выражений
for sent in sentences:
    print(phrases[sent])

После выполнения кода в ячейке, будет выведена токенизированная версия каждого предложения с учетом многофразовых выражений.

Также в Gensim есть инструмент BigramCollocationFinder. Он используется для выявления и обработки биграмм и коллокаций в текстах. Биграммы представляют собой пары слов, которые часто встречаются вместе, например, «белый дом».

Коллокации ‑- это более общая концепция, описывающая связь между словами в тексте, включая биграммы, триграммы и более сложные словосочетания. Например, «играть в футбол» может быть коллокацией, часто встречающейся в текстах о футболе.

Пример использования BigramCollocationFinder для токенизации текста:

from gensim.models.phrases import Phrases, Phraser
from nltk.tokenize import word_tokenize

# Предложения для токенизации
sentences = ["I love natural language processing.",
             "Gensim is an awesome library for NLP.",
             "Word2Vec creates word embeddings."]

# Токенизация предложений
tokenized_sentences = [word_tokenize(sent) for sent in sentences]

# Создание биграмм с использованием Phrases
bigram = Phrases(tokenized_sentences, min_count=1, threshold=1)
phraser = Phraser(bigram)

# Применение биграмм к токенизированным предложениям
for sent in tokenized_sentences:
    print(phraser[sent])

BigramCollocationFinder в Gensim используется для обнаружения часто встречающихся словосочетаний и их объединения в один токен для дальнейшей обработки и анализа текста.

Как выбрать токенизатор для своей задачи

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

Например, можно сравнить точность и скорость работы разных токенизаторов, чтобы выбрать оптимальный вариант.

Иногда один токенизатор не может обеспечить наилучшие результаты для всех типов текстовых данных. В таких случаях может быть полезно использовать несколько для одной задачи. Например, можно применить один токенизатор для текстов с многофразовыми выражениями и идиомами, а другой — для научных текстов.

Пробуйте разные методы и экспериментируйте. Это поможет достичь наилучших результатов.

И ещё немного советов по токенизации:

  • Используйте предварительную обработку текстовых данных

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

  • Используйте нейросети

Нейронки, учитывающие контекст и смысл текста, более точные в токенизации. Особенно для текстов с многофразовыми выражениями и идиомами.

  • Используйте токенизаторы, основанные на правилах

Для научных текстов со специфическими терминами и сокращениями рекомендуется использовать токенизаторы, учитывающие эту специфику языка и терминологии.

  • Используйте токенизаторы, основанные на статистике

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

  • Используйте токенизаторы, основанные на словарном запасе

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

Выводы: кто победил в битве токенизаторов, а кто остался в тени?

В битве между NLTK и SpaCy каждый инструмент имеет свои сильные и слабые стороны. NLTK обладает богатым набором токенизаторов и широкой функциональностью, что делает его:

  1. Доступным;

  2. Универсальным инструментом.

SpaCy представляет собой более мощную и быструю библиотеку с высокой точностью и поддержкой множества языков. Уже из‑за этого SpaCy чаще оказывается предпочтительнее для задач, требующих высокой скорости и точности обработки текстов.

Вообще, как мы уже заметили выше, при выборе токенизатора важно учитывать специфику задачи и особенности текстовых данных. Например, для коротких текстов, таких как твиты, SpaCy больше подходит благодаря своей способности обрабатывать нестандартные сокращения и эмодзи.

Но когда дело доходит до работы с научными текстами или текстами с специфической терминологией, токенизаторы, основанные на правилах или статистике, могут оказаться более эффективными.

Однозначного победителя в битве токенизаторов нет. Каждый инструмент имеет свои преимущества и недостатки, и выбор конкретного токенизатора зависит от конкретной задачи. А также требований к скорости и точности обработки текста. И про особенности данных забывать не стоит.

Короче, всё нужно тестить, но общие принципы мы постарались объяснить. Если вы дочитали эту статью до конца, то огромное вам спасибо за внимание. Хочется надеяться, что всё было понятно и интересно.

Комментарии (2)


  1. LinkToOS
    16.03.2024 10:23

    Представьте себе, что вы читаете книгу и хотите найти все места, где упоминается слово «кот».

    Для этого используется "индексирование".

    использует регулярные выражения для разделения текста на токены. Например, вы можете использовать его для разделения текста на слова, разделенные пробелами

    Разделение на слова это split. Обычная функция текстовых процессоров.

    "Токенизация" это преобразование объекта из текстового формата, в формат базы данных.
    Например, сначала слово преобразуется в адрес. Каждое слово это уникальная последовательность букв, которую можно напрямую преобразовать в уникальное число, которое после редукции можно использовать как адрес в базе данных. Например string "корова" преобразуется в uint_ адрес_коровы. По этому адресу лежит дескриптор слова. Например адрес_коровы{ [Имя: "корова"][код:id_существительное] [код:id_женский] [съедобное:да] [хищное:нет]...[акустически активное: да] [электорально активное:нет] [самодвижущееся:да] [оскорбительное:да] [мем-ассоциированность:0] []}. Набор признаков задается разработчиком. Теперь слово это уже не просто набор букв, а набор признаков, которые можно использовать для реализации модели условного "машинного понимания". После обработки нейросетью, фраза "корова съела человека" будет иметь низкое значение достоверности, из-за значения параметра [хищное:нет].

    Кроме массива признаков может быть массив "степень ассоциированности". Если реализуется двумерный массив Associativity[column,row], то по адресу [строка "корова", столбец"мяч"] значение будет равно 0. ["корова", "поле"] = 100, ["футбол", "поле"] = 100, ["футбол", "корова"] = 0, ["футбол", "трава"] = 100, ["корова", "трава"] = 100. Значения заполняются в процессе обучения на основе текстов, например по частоте нахождения слов в одном текстовом блоке.
    После обработки нейросетью, фраза "корова играет в футбол" будет иметь низкое значение достоверности, из-за низкого значения в массиве по адресу ["футбол", "корова"].
    (принципы организации базы данных даны чисто для примера, и не связаны с реальными моделями обучения)


    1. The-Founder-1 Автор
      16.03.2024 10:23

      Спасибо за развернутый комментарий!