Автор статьи: Рустем Галиев

Привет Хабр! На связи Рустем IBM Senior (помидор) DevOps Engineer и сегодня я хотел бы поговорить про “Feature Engineering: Extracting Features from Text”

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

Кодова база: сслыка на Github.

Основы обработки текста

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

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

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

Для подсчета слов мы можем использовать счетчик из коллекций. Мы будем использовать split() для разделения документа на отдельные токены слов (если мы этого не сделаем, Counter будет считать отдельные символы вместо слов):

Теперь у нас есть словарь со словами и их количеством. Заметьте, однако, что у нас есть запись как для «A»: 1, так и для «a»: 1. Очевидно, это одни и те же слова, поэтому мы хотели бы сосчитать их вместе. Мы можем сделать это, сделав все элементы строки строчными перед их разделением:

Отличная работа! Теперь у нас есть запись для «а»: 2.

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

Если вы присмотритесь, то увидите, что у нас есть запись для  ‘word’: 1, а также запись для ‘word.’: 1. Единственная разница — точка. Мы можем легко убрать знаки препинания, используя метод Python strip(), передав «.» как символ, который мы хотим убрать. Мы можем сделать это с пониманием (comprehension) списка после разделения:

Теперь мы считаем слово дважды: «word»: 2 появляется в счетчике.

Векторизация текстовых данных с использованием tf-idf

Если вы работаете с текстовыми документами, возможно, вы захотите каким-то образом смоделировать их. Для этого вам нужно векторизовать текст и преобразовать его в числовой ввод. Мы собираемся создать вектор tf-idf.

tf–idf — это способ векторизации текста, отражающий важность слова в документе, а не только частоту его появления. Он означает «частота термина — обратная частота документа» и придает вес словам, которые в конечном счете являются более значимыми во всем корпусе слов, — словам, которые не появляются невероятно часто, а также словам, которые не являются чрезвычайно редкими.

Создание векторов tf-idf относительно просто в scikit-learn. Давайте используем поле заголовка из набора данных добровольцев в качестве нашего корпуса текста:

Чтобы векторизовать этот столбец, мы можем использовать TfidfVectorizer. Мы можем просто передать столбец текста, который хотим векторизовать, в метод TfidfVectorizer fit_transform().

Новые векторизованные данные хранятся в спарс матрице SciPy, которая является эффективным способом хранения спарсированных (разреженных) данных — данных, в которых многие значения равны 0.

Почему здесь много значений 0? Давайте посмотрим на форму матрицы:

Итак, эта матрица имеет 665 строк, как и в наборе данных волонтеров, и 1136 столбцов. В матрице есть один столбец для каждого слова, которое появляется в нашем корпусе, а здесь это каждое из 665 заголовков, которые появляются в наборе данных о добровольцах. Для каждого заголовка слова получают веса tf-idf только в соответствующих столбцах, поэтому, если заголовок содержит два слова, для этой строки будут заполнены только эти два столбца.

Объект TfidfVectorizer после того, как вы векторизовали некоторый текст, вернет вам информацию об этом тексте.

Чтобы увидеть список всех уникальных слов в вашем наборе текста, вы можете использовать метод get_feature_names() для объекта векторизатора tfidf_vec:

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

Построение текстовой модели с использованием наивного Байеса

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

Мы можем использовать модель GaussianNB из scikit-learn, чтобы построить модель с векторизованным текстом заголовка из набора данных добровольцев, чтобы продемонстрировать этот процесс. Попробуем предсказать поле category_desc по тексту.

Сначала нам нужно закодировать метки в category_desc, это можно сделать с помощью LabelEncoder scikit-learn. Прежде чем мы это сделаем, мы позаботимся о некоторых значениях NaN в столбце category_desc, заполнив их текстом «None» с помощью fillna().

Затем мы хотим разделить данные на обучающие и тестовые наборы, чтобы избежать переобучения. Обратите внимание, что мы можем передать наш векторизованный текст непосредственно в train_test_split() — нам просто нужно использовать .toarray(), чтобы преобразовать его в массив. Мы также хотим убедиться, что мы стратифицируем наши данные y, поскольку у нас несбалансированное распределение классов.

Наконец, мы готовы обучить и оценить наш наивный Байесовский мод.

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

На этом все. ТАкже хочу порекомендовать всем заинтересованным бесплатный вебинар от OTUS по теме: "Data Engineer в новых реалиях, что ждать бизнесу?".

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


  1. iluha1337
    11.08.2022 12:14
    -1

    Статья ради статьи, вы быть хоть как-нибудь серьезно отнеслись к подготовке материала.
    Даже в самых базовых уроках, книгах, статьях используют нормальные токенизаторы, к примеру из библиотек NLTK/Gensim, а не python-овский strip().

    Не говоря уже о том, что пропущенные такие базовые этапы как удаление стоп слов (его сам TfIdfVectorizer может провести), лемматизация/стемминг, настройка параметров векторизатора.

    Выглядит как какой-та низкокачественная калька с англоязычной статьи по типу этой.