Тематическое моделирование с помощью BERT

Использование BERT и TF-IDF для создания легко интерпретируемых тем.

Часто, когда владелец продукта обращается ко мне с просьбой провести анализ на основе НЛП, мне обычно задают следующий вопрос:

«Какая тема часто встречается в этих документах?»

Отсутствие каких-либо категорий или ярлыков. Я вынужден изучить неконтролируемые методы извлечения этих тем, а именно Тематическое моделирование.

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

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

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

Большим преимуществом Doc2Vec является то, что результирующие вложения документа и слова совместно встраиваются в одно и то же пространство, что позволяет встраиванию документа быть представленным вложениями соседних слов. К сожалению, это оказалось трудным, поскольку вложения BERT основаны на токенах и не обязательно занимают одно и то же пространство **.

Вместо этого я решил придумать другой алгоритм, который мог бы использовать вложения преобразователей BERT и 🤗. Результатом стал BERTopic, алгоритм для создания тем с использованием самых современных встраиваний.

Основной темой этой статьи будет не использование BERTopic, а руководство о том, как использовать BERT для создания вашей собственной тематической модели.

ДОКУМЕНТ *: Ангелов, Д. (2020). Top2Vec: распределенное представление тем. Препринт arXiv arXiv: 2008.09470.

ПРИМЕЧАНИЕ * *. Хотя они могут занимать одно и то же пространство, результирующий размер встраиваемых слов будет довольно большим из-за контекстной природы BERT. Более того, существует вероятность того, что в результате вложения предложений или документов ухудшится качество.

1. Данные и пакеты

В этом примере мы используем знаменитый набор данных 20 Newsgroups, который содержит примерно 18000 сообщений групп новостей по 20 темам. Используя Scikit-Learn, мы можем быстро загрузить и подготовить данные:

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

ПРИМЕЧАНИЕ. Если вы хотите применить тематическое моделирование не ко всему документу, а на уровне абзаца, я бы посоветовал разделить ваши данные перед созданием вложений.

2. Вложения

Самый первый шаг, который нам нужно сделать, - это преобразовать документы в числовые данные. Для этой цели мы используем BERT, поскольку он извлекает различные вложения в зависимости от контекста слова. Мало того, есть много предварительно обученных моделей, готовых к использованию.

Как вы создаете вложения BERT для документа, зависит от вас. Однако я предпочитаю использовать пакет sentence-transformers, поскольку полученные вложения показали высокое качество и обычно достаточно хорошо работают для встраиваний на уровне документа.

Установите пакет с pip install sentence-transformers перед созданием вложений документов. Если у вас возникнут проблемы с установкой этого пакета, то сначала стоит установить Pytorch.

Затем запустите следующий код, чтобы преобразовать ваши документы в 512-мерные векторы:

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

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

3. Кластеризация

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

UMAP

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

Установите пакет с pip install umap-learn, прежде чем мы снизим размерность вложений документа. Мы уменьшаем размерность до 5, сохраняя при этом размер локального окружения равным 15. Вы можете поэкспериментировать с этими значениями, чтобы оптимизировать создание вашей темы. Обратите внимание, что слишком низкая размерность приводит к потере информации, а слишком высокая размерность приводит к худшим результатам кластеризации.

HDBSAN

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

Установите пакет с pip install hdbscan, затем создайте кластеры:

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

Визуализировать отдельные кластеры сложно из-за количества сгенерированных тем (~ 55). Однако мы видим, что даже в двумерном пространстве сохраняется некоторая локальная структура.

ПРИМЕЧАНИЕ. Вы можете пропустить этап уменьшения размерности, если используете алгоритм кластеризации, который может обрабатывать высокую размерность, например k-среднее на основе косинуса.

4. Создание темы

Что мы хотим узнать из кластеров, которые мы создали, - вот что отличает один кластер по своему содержанию от другого?

Как мы можем извлечь темы из сгруппированных документов?

Чтобы решить эту проблему, я придумал вариант TF-IDF на основе классов (c-TF-IDF), который позволил бы мне извлечь то, что делает каждый набор документов уникальным по сравнению с другим.

Интуиция, лежащая в основе метода, заключается в следующем. Когда вы применяете TF-IDF как обычно к набору документов, вы в основном сравниваете важность слов между документами.

Что, если вместо этого мы будем рассматривать все документы в одной категории (например, кластере) как один документ, а затем применять TF-IDF? В результате получится очень длинный документ по каждой категории, а итоговая оценка TF-IDF продемонстрирует важные слова в теме.

c-TF-IDF

Чтобы создать эту оценку TF-IDF на основе классов, нам нужно сначала создать один документ для каждого кластера документов:

Затем мы применяем TF-IDF на основе классов:

Где частота каждого слова t извлекается для каждого класса i и делится на общее количество слов w. Это действие можно рассматривать как форму регуляризации частых слов в классе. Затем общее количество несвязанных документов m делится на общую частоту слова t по всем классам n.

Теперь у нас есть одно значение важности для каждого слова в кластере, которое можно использовать для создания темы. Если мы возьмем 10 самых важных слов в каждом кластере, то получим хорошее представление о кластере и, следовательно, теме.

Представление темы

Чтобы создать представление темы, мы берем 20 лучших слов по каждой теме на основе их оценок c-TF-IDF. Чем выше оценка, тем более репрезентативной должна быть его тема, поскольку оценка является показателем плотности информации.

Мы можем использовать topic_sizes, чтобы узнать, насколько часто встречаются определенные темы:

Название темы-1 относится ко всем документам, которым не назначены темы. Самое замечательное в HDBSCAN заключается в том, что не все документы направляются в определенный кластер. Если кластер найти не удалось, то это просто выброс.

Мы видим, что темы 7, 43, 12 и 41 - это самые большие кластеры, которые мы могли бы создать. Чтобы просмотреть слова, относящиеся к этим темам, мы можем просто использовать dictionarytop_n_words для доступа к этим темам:

Глядя на четыре самые большие темы, я бы сказал, что они прекрасно представляют собой легко интерпретируемые темы!

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

5. Уменьшение количества тем

Есть шанс, что в зависимости от набора данных вы получите сотни созданных тем! Вы можете настроить параметры HDBSCAN таким образом, чтобы вы получали меньше разделов с помощью его параметра min_cluster_size, но он не позволяет вам указать точное количество кластеров.

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

Мы можем использовать похожую технику, сравнивая векторы c-TF-IDF по темам, объединяя наиболее похожие и, наконец, пересчитывая векторы c-TF-IDF для обновления представления наших тем:

Выше мы взяли наименее распространенную тему и объединили ее с наиболее похожей темой. Повторив это еще 19 раз, мы сократили количество тем с 56 до 36!

ПРИМЕЧАНИЕ. Мы можем пропустить часть пересчета в этом конвейере, чтобы ускорить этап сокращения тем. Однако более точно пересчитать векторы c-TF-IDF, так как это лучше представит вновь созданное содержание тем. Вы можете поиграть с этим, например, обновляя каждые n шагов, чтобы ускорить процесс и сохранить хорошее представление темы.

СОВЕТ: вы можете использовать метод, описанный в этой статье (или просто использовать BERTopic), чтобы также создавать вложения на уровне предложений. Основным преимуществом этого является возможность просмотра распределения тем в одном документе.

Спасибо за чтение!

Если вы, как и я, увлечены искусственным интеллектом, наукой о данных или психологией, пожалуйста, не стесняйтесь добавить меня в LinkedIn или подписаться на меня в Twitter.

Все примеры и код из этой статьи можно найти здесь: