Это история о том, как и почему нам пришлось написать нашу собственную форму скрытого распределения Дирихле (LDA). Я также говорю о том, почему нам нужно было создать управляемую тематическую модель (GuidedLDA), и о процессе открытого исходного кода всего на GitHub.

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

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

Что касается следующих заголовков, вы соглашаетесь, что 1 и 5 относятся к политике, 2 и 4 - к спорту, а 3 и 6 - к науке:

Для человека не составляет труда определить, к какой теме принадлежит новостная статья. Но как научить компьютер понимать одни и те же темы?

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

После того, как мы сгруппировали слова по темам, мы теперь можем видеть, о какой группе слов говорится в новостных статьях и документе. Затем мы можем отнести его к этой группе или теме.

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

Примечание: слова не группируются напрямую по темам. Скорее рассчитывается вероятность, такая как «Какова вероятность того, что слово принадлежит теме?».

Он задается как p (t | w). Или вероятность темы t данного слова w. По сути, это просто байесовская вероятность.

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

Итак, что такое Guided LDA?

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

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

Пара тем совпадала, а некоторых тем, о которых я ожидал, не было. Что-то в этом роде произошло, Космос и Технологии объединились.

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

Но с чего начать, когда модель находится без присмотра? Решили отладить…

Мы обнаружили, что объединяемые темы не имели достаточного количества документов, чтобы выделиться.

Мы решили сказать модели, чтобы космос и технологии были отделены друг от друга. Идея заключалась в том, чтобы задать несколько исходных слов для Space и несколько исходных слов для Tech. Затем приведите модель к сходству с этими терминами.

Это была простая и интуитивно понятная идея, но мы не смогли найти никакой реализации GuidedLDA. Было очень мало газет, в которых говорилось о руководстве LDA.

Мы сослались на статью Джагадиша Джагарламуди, Хала Даума III и Рагхавендры Удупы Включение лексических априорных значений в тематические модели. В статье рассказывается о том, как априорные значения (в данном случае априорные означают начальные слова) могут быть введены в модель, чтобы вести ее в определенном направлении. Мы немного поговорим о деталях.

После того, как мы внесли эти изменения, модель сместилась так, как мы этого хотели.

Итак, как мы изменили LDA на GuidedLDA?

Чтобы объяснить эту часть, нам нужно будет подробнее остановиться на том, как работает LDA. Я сделаю все возможное, чтобы это было просто. Если вы не хотите вдаваться в подробности, можете сразу перейти к разделу Использование GuidedLDA.

Обычный LDA работает так: сначала каждое слово случайным образом назначается теме. Этой инициализацией можно управлять с помощью приоров Дирихле через параметр Alpha. Отсюда и название LDA (Latent Dirichlet Allocation). Эта случайность может быть равномерной инициализацией, если альфа большой, или искаженной инициализацией, если альфа мала. А пока давайте продолжим унифицированную инициализацию.

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

Допустим, вы хотите найти тему для термина Blue Origin. LDA сначала предполагает, что все остальные термины в корпусе относятся к правильной теме. На последнем этапе мы равномерно распределили каждый термин по всем темам, поэтому предположим, что это правильная тема для этих терминов.

Затем мы вычисляем, какие термины Blue Origin часто встречаются. Тогда это самая распространенная тема среди этих терминов. Этой теме мы присвоим Blue Origin.

Blue Origin, вероятно, подойдет к той теме, в которой находятся SpaceX и NASA. Теперь вы можете видеть, что NASA, SpaceX и Blue Origin немного ближе друг к другу, чем были до этого шага. Затем мы перейдем к следующему сроку и повторим процесс. Мы будем повторять весь этот процесс столько раз, сколько потребуется для схождения модели.

Формула для этого будет:
Probability из Blue Origin, чтобы соответствовать теме Z {0,1,2, ..}, когда это встречается в document равно количеству раз, когда Blue Origin присваивается теме Z, умноженному на количество других words в этом документе, которые уже принадлежат Z, разделенному на общее количество раз любое слово присваивается теме Z.

Вот настоящая формула:

Для каждого документа (D) и для каждого слова (W) в этом документе мы рассчитаем вероятность того, что это слово относится к каждой теме (_10 _) .

for d in all_documents_D:
    for w in all_words_W_in_d:
        for z in all_topics_Z:
            w_in_z = count(across all documents w belongs to z)
            d_in_z = count(in d all words that belong to z)
            tokens_in_z = count(all assignments in z)
            p(z| w, d) = w_in_z * d_in_z / tokens_in_z
        # so w belong to max p(z)
        # whichever topic the probability was maximum for w
        w_z = max(p(z| w, d))

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

Что меняется при заполнении документов?

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

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

В показанной выше инициализации NASA и SpaceX засеваются для Topic_0, Apple и Google для Topic_1 и Physics и Chemistry для Topic_2.

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

# for seeded words belonging to seeded topics
# this count will be higher now for seeded z.
w_in_z = count(across all documents w belongs to z)
# Thus probability of p belonging to seeded z will be higher
p(z| w, d) ∝ w_in_z

Отсюда и руководство LDA. Или GuidedLDA.

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

Использование GuidedLDA

GuidedLDA - это библиотека Python, исходный код которой открыт на репозитории GitHub.

Вы можете установить его с помощью простой установки pip:

pip install guidedlda

Код для его использования довольно прост. Создайте словарь для seed_topics с картой word_id - topic_id. И передайте его методу model.fit().

  1. seed_confidence может варьироваться от 0 до 1.
  2. seed_topics - это словарь с {word_id по topic_id}
  3. X - это матрица терминов документа.
seed_topics = {
    'NASA': 0, 'SpaceX': 0,
    'Apple': 1, 'Google': 1,
    'Physics': 2, 'Chemistry': 2,
}
model.fit(X, seed_topics=seed_topics, seed_confidence=0.15).

Ссылка на документацию для GuidedLDA находится здесь.

Кредиты

Большая часть кода заимствована из библиотеки python LDA.

Огромный привет авторам этой библиотеки: Аллену Ридделлу и Тиму Хопперу.

Особая благодарность Винодху Равиндранатху, который наставлял меня на протяжении всего проекта.

Используя GuidedLDA, мы смогли выделить темы, которые меньше представлены в корпусе, и направить классификацию документов.

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