Реализация скрытого распределения Дирихле в Python

Скрытое распределение Дирихле (LDA) - один из наиболее распространенных алгоритмов тематического моделирования. LDA была предложена Дж. К. Притчардом, М. Стивенсом и П. Доннелли в 2000 году и вновь открыта Дэвидом М. Блей, Эндрю Й. Нг и Майклом И. Джорданом в 2003 году. В этой статье я попытаюсь дать вам представление о том, что тематическое моделирование есть. Мы узнаем, как работает LDA, и, наконец, попробуем реализовать нашу модель LDA.

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

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

Предположим, вы читаете статьи в газете, и в этих статьях слово «климат» встречается чаще, чем любые другие слова. Итак, в нормальном смысле можно сказать, что эти статьи, скорее, будут о чем-то, связанном с климатом. Тематическое моделирование делает то же самое в статистическом плане. Он создает темы, группируя похожие слова. Вот два термина: один - «Тематическое моделирование», а другой - «Тематическая классификация». Хотя они выглядят одинаково, это совершенно разные процессы. Первый - это метод машинного обучения без учителя, а второй - метод обучения с учителем.
Давайте подробнее остановимся на концепции.

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

Для тематического моделирования существует несколько существующих алгоритмов, которые вы можете использовать. Факторизация неотрицательной матрицы (NMF), Скрытый семантический анализ или латентное семантическое индексирование (LSA или LSI) и Скрытое распределение Дирихле (LDA) - это некоторые из этих алгоритмов. В этой статье мы поговорим о скрытом распределении Дирихле, одном из наиболее распространенных алгоритмов тематического моделирования.

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

«Скрытое распределение Дирихле (LDA) - это генеративная статистическая модель, которая позволяет объяснять наборы наблюдений ненаблюдаемыми группами, что объясняет, почему некоторые части данных похожий. Например, если наблюдения представляют собой слова, собранные в документы, предполагается, что каждый документ представляет собой смесь небольшого количества тем и присутствие каждого слова связано с одной из тем документа ». - Википедия

Хорошо, давайте попробуем понять это определение.

Основная идея распределения Л Атент Дирихле (LDA) заключается в том, что документы рассматриваются как случайное сочетание различных тем, а темы считаются смесью разные слова. Теперь предположим, что вам нужны статьи, связанные с животными, и перед вами тысячи статей, и вы действительно не знаете, о чем эти статьи. Чтение всех этих статей действительно утомительно, чтобы найти статьи, связанные с животными. Давайте посмотрим на это на примере.

В качестве примера рассмотрим четыре статьи. Артикул № 1 относится к животным, артикул № 2, относящихся к генетическому типу, артикул № 3 относится к типам компьютеров и артикулу № 4 - сочетание животного и генетического типа. Как человек, вы можете легко различать эти темы по содержащимся в них словам. Но что вы будете делать, если статей тысячи и в каждой статье тысячи строк? Ответ будет примерно таким: «Если мы можем сделать это с помощью компьютера, то мы должны это сделать». Да, компьютер может сделать это с помощью скрытого распределения Дирихле. Теперь попробуем разобраться, как работает LDA. Сначала мы увидим графическое представление LDA, а затем мы увидим формулу расчета вероятности.

На приведенном выше рисунке показано графическое представление LDA. На приведенном выше рисунке мы видим шесть параметров:

α (альфа) и η (эта) - представляет распределение Дирихле. Высокое значение альфа указывает, что каждый документ содержит большую часть тем, и наоборот, более низкое значение альфа указывает, что документы, вероятно, будут содержать меньшее количество тем. Как и альфа, более высокое значение η указывает на то, что темы, вероятно, охватывают большую часть слов, и наоборот, более низкое значение эта указывает, что темы, вероятно, будут содержать меньшее количество слов.

β (бета) и θ (тета) - представляет полиномиальное распределение.

z - представляет собой набор тем.

w - представляет собой набор слов

Левая часть формулы указывает вероятность документа. Справа от формулы четыре члена. 1-е и 3-е члены формулы помогут нам найти темы. 2-й и 4-й помогут нам найти слова в статьях. Первые два члена правой части формулы обозначают распределение Дирихле, а остальная часть правой части - полиномиальное распределение.

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

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

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

Таким образом, мы найдем слова, которые больше относятся к темам, и сможем распространять статьи на основе этих тем.

Внедрение LDA

Вы можете найти код в GitHub. Для реализации LDA вы можете использовать gensim или sklearn. Здесь мы будем использовать gensim.

Загрузить данные

Для реализации я использовал набор данных Kaggle. Этот набор данных состоит из информации о 2150 наборах данных в 15 столбцах:

dataset = pd.read_csv('/content/drive/My Drive/topic modelling/voted-kaggle-dataset.csv')

Предварительная обработка данных

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

modified_dataset = modified_dataset.dropna()

Затем мы рассчитаем количество уникальных тегов в столбцах Теги, так как мы будем рассматривать это как количество тем для нашей модели.

unique_tag = []
for i in range(len(tag_dataset)):
  tag_string = str(tag_dataset[i])
  if tag_string != "nan" :
    tag_word=convert(tag_string)
    for j in range(len(tag_word)):
      if tag_word[j] not in unique_tag:
        unique_tag.append(tag_word[j])
print(len(unique_tag))

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

remove_digits = str.maketrans('', '', string.digits)
exclude = '[!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~]'
for column in ['Title','Subtitle','Description']:
  modified_dataset[column] = modified_dataset[column].map(lambda x : x.translate(remove_digits))
  modified_dataset[column] = modified_dataset[column].map(lambda x : re.sub(str(exclude), '', x))

Нам нужно токенизировать наш набор данных и выполнить операцию стемминга.

import nltk
nltk.download('punkt')
tokenized_dataframe =  modified_dataset.apply(lambda row: nltk.word_tokenize(row['Description']), axis=1)
print(type(tokenized_dataframe))
def lemmatize_text(text):
    return [ps.stem(w)  for w in text if len(w)>5]
ps = PorterStemmer() 
stemmed_dataset = tokenized_dataframe.apply(lemmatize_text)

Исследовательский анализ данных

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

from wordcloud import WordCloud
import matplotlib.pyplot as plt
#dataset_words=''
#for column in ['Title','Subtitle','Description']:
dataset_words=''.join(list(str(stemmed_dataset.values)))
print(type(dataset_words))
wordcloud = WordCloud(width = 800, height = 500, 
                background_color ='white',  
                min_font_size = 10).generate(dataset_words) 

plt.figure(figsize = (5, 5), facecolor = None) 
plt.imshow(wordcloud) 
plt.axis("off") 
plt.tight_layout(pad = 0) 
  
plt.show()

Построить модель

Для модели LDA нам сначала нужно создать словарь слов, в котором каждому слову присваивается уникальный идентификатор. Затем необходимо создать корпус, который содержит сопоставление идентификаторов слов с word_frequency - - ›(word_id, word_frequency).

dictionary_of_words = gensim.corpora.Dictionary(stemmed_dataset)
word_corpus = [dictionary_of_words.doc2bow(word) for word in stemmed_dataset]

Наконец, обучите модель.

lda_model = gensim.models.ldamodel.LdaModel(corpus=word_corpus,
                                                   id2word=dictionary_of_words,
num_topics=329, 
random_state=101,
update_every=1,
chunksize=300,
passes=50,
alpha='auto',
per_word_topics=True)

Согласованность измеряет относительное расстояние между словами в теме.

coherence_val = CoherenceModel(model=lda_model, texts=stemmed_dataset, dictionary=dictionary_of_words, coherence='c_v').get_coherence()

print('Coherence Score: ', coherence_val)

Значение когерентности: 0,4

Оценка

for  index,score in sorted(lda_model[word_corpus[2]][0], key=lambda tup: -1*tup[1]):
    print("\nScore: {}\t \nTopic: {}".format(score, lda_model.print_topic(index, 10)))

Тема наверху имеет наибольшую вероятность и связана с чем-то вроде экономики.

Вы можете найти весь код на GITHUB.

Ссылки:

  1. Скрытое распределение Дирихле Дэвида М. Блея, Эндрю Й. Нг и Майкла И. Джордана.
  2. Скрытое размещение Дирихле Луиса Серрано.
  3. Скрытое распределение (алгоритм) Дирихле от ML Papers Explained - А.И. Сократовы круги - AISC.

И наконец, спасибо, что прочитали. Любая обратная связь приветствуется.