Тематическое моделирование — это неконтролируемый подход к обнаружению латентной (скрытой) семантической структуры текстовых данных (часто называемых документами).

Почему тематическое моделирование?

Каждый документ построен с иерархией, от слов до предложений, от абзацев до документов. Таким образом, извлечение тем из документов помогает нам анализировать наши данные и, следовательно, приносит больше пользы для нашего бизнеса. Разве не здорово иметь какой-то алгоритм, который сделает всю работу за вас? Да!! Тематическое моделирование — это автоматизированный алгоритм, не требующий маркировки/аннотаций. Учитывая кучу документов, это дает вам интуитивное представление о темах (историях), о которых идет речь в вашем документе.

Применения тематического моделирования:

  • Кластеризация документов
  • Поиск информации
  • Средство извлечения признаков для классификации текста

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

Прежде чем мы начнем, вот основное предположение:

  • Каждый документ рассматривается как смесь тем.
  • Каждая тема рассматривается как сочетание слов.

Учитывая некоторые исходные данные, давайте сначала начнем изучать различные методы тематического моделирования, а в конце мы рассмотрим реализацию Скрытого распределения Дирихле (LDA), самого популярного метода в тематическое моделирование. Если вы уже знакомы с LSA, pLSA и ищете подробное объяснение LDA или его реализации, пропустите следующие два раздела и начните с LDA.

Скрытый семантический анализ

LSA создает векторное представление текста, фиксируя совпадения слов и документов.

Здесь M — количество документов со Словарным запасом (V) аппроксимируется двумя матрицами (Матрица назначения тем и Матрица слов-тем).

Шаги:

  • Постройте матрицу терминов документа (X), где каждая запись Xᵢⱼ представляет собой необработанное количество j-го слова, встречающегося в i-м документе. Однако на практике мы используем векторизатор TF-IDF для присвоения веса каждому элементу в документе.
  • Примените Разложение усеченных единичных значений, чтобы найти несколько скрытых тем и выявить взаимосвязь между словами и документами.

Затем мы выбираем k лучших тем (т. е.) X = Uₖ * Sₖ * Vₖ.

Однако LSA, будучи первой топической моделью и эффективной для вычислений, не имеет интерпретируемости.

Вероятностный анализ скрытой семантики

pLSA — это усовершенствование LSA, представляющее собой генеративную модель, целью которой является поиск скрытых тем в документах путем замены SVD в LSA вероятностной моделью.

Шаги:

  • Выберите документ dᵢ с вероятностью P(dᵢ)
  • Выберите скрытый класс Zₖ с вероятностью P(Zₖ|dᵢ)
  • Сгенерировать слово с вероятностью P(wⱼ|Zₖ)

В простом контексте мы сначала сэмплируем документ, затем на основе документа мы сэмплируем тему, а на основе темы мы сэмплируем слово, что означает, что d и w условно независимы, учитывая скрытую тему «z».

Ограничения:

  • «d» — полиномиальная случайная величина, основанная на обучающих документах. Модель изучает P(z|d) только для документов, на которых она обучалась, поэтому она не является полностью генеративной и не может присвоить вероятность невидимым документам.
  • Параметры модели имеют порядок k|V| + k|D|, так что параметры растут линейно с документами, поэтому они склонны к переоснащению. На практике используется «эвристика смягчения» для сглаживания параметров модели и предотвращения переобучения.

Скрытое распределение Дирихле

LDA — это байесовская версия pLSA.

Распределение Дирихле представляет собой многомерное обобщение бета-распределения. По сути, Дирихле — это распределение над распределением.

LDA использует априоры Дирихле для распределения темы документа и слова темы.

Предположение

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

Шаги

  • Случайная выборка тематического распределения (θ) из распределения Дирихле (α)
  • Произвольная выборка распределения слов (φ) из другого распределения Дирихле (β)
  • Из распределения (θ) выберите тему (z)
  • Выберите слово (w) из распределения слов (β) по заданной теме z.

Так предполагается, что каждое слово генерируется в документе.

Наша цель здесь — оценить параметры φ, θ, чтобы максимизировать p(w; α, β). Основное преимущество LDA перед pLSA заключается в том, что он хорошо обобщает невидимые документы.

Реализация LDA в Python

Я буду использовать набор данных 20Newsgroup для этой реализации. Я просмотрел и использовал этот набор данных для своих предыдущих работ, поэтому я заранее знал об основных темах и мог проверить, правильно ли LDA их определяет.

Этот набор данных доступен в sklearn и может быть загружен следующим образом:

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')

Ниже приведены категории новостных данных:

from pprint import pprint
pprint(list(newsgroups_train.target_names))
['alt.atheism',
 'comp.graphics',
 'comp.os.ms-windows.misc',
 'comp.sys.ibm.pc.hardware',
 'comp.sys.mac.hardware',
 'comp.windows.x',
 'misc.forsale',
 'rec.autos',
 'rec.motorcycles',
 'rec.sport.baseball',
 'rec.sport.hockey',
 'sci.crypt',
 'sci.electronics',
 'sci.med',
 'sci.space',
 'soc.religion.christian',
 'talk.politics.guns',
 'talk.politics.mideast',
 'talk.politics.misc',
 'talk.religion.misc']

В основном их можно сгруппировать по следующим темам:

  • Политика
  • Наука
  • Компьютеры и технологии
  • Религия
  • Спорт и т. д.

Начнем с нашей реализации на LDA,

Повторная обработка данных

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

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

Запуск LDA

Теперь пришло время запустить LDA, и это довольно просто, так как мы можем использовать пакет gensim. Нам нужно указать количество выделяемых тем. Мы можем установить параметры Дирихле альфа и бета как «авто», gensim позаботится о настройке. Давайте начнем с 5 тем, позже мы увидим, как оценивать модель LDA и настраивать ее гиперпараметры.

# Create lda model with gensim library
# Manually pick number of topic:
# Then based on perplexity scoring, tune the number of topics
lda_model = gensim.models.LdaModel(bow_corpus,
                                  id2word=dictionary,
                                  num_topics=5,
                                  offset=2,
                                  random_state=100,
                                  update_every=1,
                                  passes=10,
                                  alpha='auto',
                                  eta="auto",
                                  per_word_topics=True)

Визуализация тем:

Во-первых, давайте напечатаем темы, изученные моделью.

from pprint import pprint
pprint(lda_model.print_topics())
[(0, # Seems to be Computer and Technology
  '0.014*"key" + 0.007*"chip" + 0.006*"encryption" + 0.006*"system" + '
  '0.005*"clipper" + 0.005*"article" + 0.004*"university" + '
  '0.004*"information" + 0.004*"government" + 0.004*"time"'),
 (1, # Seems to be Science and Technology
  '0.008*"drive" + 0.007*"university" + 0.007*"window" + 0.007*"system" + '
  '0.006*"doe" + 0.005*"card" + 0.005*"thanks" + 0.005*"space" + '
  '0.004*"article" + 0.004*"computer"'),
 (2, # seems to be politics
  '0.010*"people" + 0.006*"gun" + 0.006*"armenian" + 0.005*"time" + '
  '0.005*"article" + 0.005*"then" + 0.005*"israel" + 0.004*"war" + '
  '0.004*"government" + 0.004*"israeli"'),
 (3, # seems to be sports
  '0.013*"game" + 0.011*"team" + 0.008*"article" + 0.007*"university" + '
  '0.006*"player" + 0.006*"time" + 0.005*"play" + 0.005*"season" + '
  '0.004*"hockey" + 0.004*"win"'),
 (4, # seems to be religion
  '0.018*"god" + 0.011*"people" + 0.008*"doe" + 0.008*"christian" + '
  '0.007*"jesus" + 0.006*"believe" + 0.006*"then" + 0.006*"article" + '
  '0.005*"life" + 0.005*"time"')]

Я вручную сгруппировал (добавил в комментариях) их в эти 5 категорий, упомянутых ранее, и мы видим, что LDA делает здесь довольно хорошую работу.

Давайте визуализируем LDA с помощью инструмента pyLDAVis,

import pyLDAvis
import pyLDAvis.gensim
pyLDAvis.enable_notebook()
vis = pyLDAvis.gensim.prepare(lda_model, bow_corpus, dictionary)
vis

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

Оценка LDA

Есть два метода, которые лучше всего описывают модель производительности LDA.

  • недоумение
  • когерентность

Недоумение – это мера неопределенности, означающая, что чем меньше недоумение, тем лучше модель. Мы можем рассчитать показатель недоумения следующим образом:

print('Perplexity: ', lda_model.log_perplexity(bow_corpus))

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

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

coherence_model_lda = models.CoherenceModel(model=lda_model, texts=X, dictionary=dictionary, coherence='c_v')
coherence_lda = coherence_model_lda.get_coherence()
print('Coherence Score: ', coherence_lda)

Настройка модели LDA

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

  • Количество тем(К)
  • Параметр Дирихле альфа
  • Параметр Дирихле бета

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

Ссылки:

Проверьте связанные блоги,