В моем предыдущем сообщении в блоге я обсуждал различных игроков, участвующих в опровержении биомедицинской и медико-биологической литературы. Один вопрос, который заинтриговал меня и остался без ответа: какие темы / темы исследований представлены в этих отозванных публикациях? Я пытаюсь ответить на этот вопрос в этом сообщении блога, используя тематическое моделирование.

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

Доступно множество техник тематического моделирования. Здесь я использовал один из самых популярных методов - скрытое распределение Дирихле (LDA) ¹.

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

Математически этот порождающий процесс можно объяснить следующим образом:

Такая диаграмма называется обозначением пластины. Поскольку Medium не позволяет использовать индексы, следуйте обозначениям на диаграмме или в приведенном уравнении или прочтите этот пост на моем веб-сайте. Из распределения Дирихле с параметром λ мы получаем распределение по словам для темы 𝑘∈1..𝐾 и обозначается как 𝛽𝑘. Здесь каждая тема представляет собой 𝑁-мерный вектор (𝑁 - размер словарного запаса), который имеет вероятность для каждого слова в теме 𝑘 согласно распределению 𝛽. Из второго распределения Дирихле с параметром 𝛼 мы строим распределение по темам для каждого документа 𝑑∈1..𝑀, и это отображается как 𝜃𝑑. Таким образом, для каждого документа у нас есть 𝐾-мерный вектор, который имеет вероятность для каждой темы (𝐾 - количество тем) в соответствии с этим распределением по темам. Для каждой позиции слова 𝑛∈1..𝑁 в документе мы рисуем тематическое задание 𝑧𝑛 из 𝜃. Затем мы используем 𝛽, соответствующее назначению темы 𝛽𝑧𝑛, чтобы создать слово. Поскольку LDA знает эти слова, оно намеревается найти 𝑧, 𝛽 и 𝜃.

Вкратце, LDA работает следующим образом: сначала мы назначаем количество тем 𝐾, которое мы ожидаем в корпусе. Затем LDA случайным образом назначает тему каждому слову в каждом документе. Затем он переходит к каждому слову в корпусе и проверяет, сколько раз эта конкретная тема встречается в документе и сколько раз это конкретное слово встречается в назначенной теме. На основе результатов этому конкретному слову назначается новая тема, и эта итерация продолжается до тех пор, пока темы не приобретут смысл. В конце концов, интерпретация темы остается за пользователем.

В этом сообщении блога будут описаны следующие шаги по извлечению скрытых тем из моего корпуса отозванной литературы.

  1. Предварительная обработка данных
  2. Построение модели LDA
  3. Визуализация

Как упоминалось в моем предыдущем сообщении в блоге, данные были получены из PubMed и содержат 6485 отозванных публикаций. Для текущего анализа я использовал только отрывки из этих публикаций. Ключевые слова могут использоваться для определения темы любого реферата, но в доступном наборе данных 84% рефератов не имеют ключевых слов, и это побудило меня извлечь темы из рефератов.

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

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

я. Лемматизация

Эта часть включает тегирование части речи (POS) для фильтрации слов, которые являются существительными, существительными собственными или прилагательными. Я игнорировал другие части речи, такие как глаголы и наречия, поскольку они, казалось, не важны для моей текущей задачи. Затем полученные слова были лемматизированы, что означает, что сохранилась только корневая форма слова. Для этой обработки я использовал замечательную библиотеку Python spaCy.

# load spacy and return english language object
nlp=spacy.load('en_core_web_sm')

def lemmatization(doc, allowed_pos=['NOUN','ADJ','PROPN']):

    ``` filtering allowed POS tags and lemmatizing them```

    retracted_corpus=[]
    for text in doc:
        doc_new = nlp(text) 
        retracted_abstract=[]
        for token in doc_new:
            if token.pos_ in allowed_pos:
                retracted_abstract.append(token.lemma_)
        retracted_corpus.append(retracted_abstract)
    return retracted_corpus

abstract_lemmatized = lemmatization(doc,allowed_pos=['NOUN','ADJ','PROPN'])

Это научные документы, и иногда разбиение предложений одним пробелом не является оптимальным (например, в формуле или уравнении могут использоваться другие символы, такие как = или +). Поэтому на дополнительном этапе я использовал другую реализацию разделения текста с использованием некоторых функций NLTK, другой библиотеки Python для обработки естественного языка (NLP).

from nltk.tokenize import RegexpTokenizer
# tokenizer that splits only in the selected symbols or space
tokenizer=RegexpTokenizer('\s+|[<>=()-/]|[±°å]',gaps=True)

def remove_punctuation(text):
    updated_abstract=[]
    for doc in text:
        sent=' '.join(doc)
        updated_abstract.append(tokenizer.tokenize(sent))
    return(updated_abstract)

abstract_processed = remove_punctuation(abstract_lemmatized)

II. Удаление игнорируемых слов

Достаточно рутинной задачей в НЛП является удаление стоп-слов или общих слов, не несущих достаточного значения, чтобы отличить один текст от другого, например, «а», «то», «для» и так далее. Я использовал для этого библиотеку стоп-слов NLTK. Он содержит 179 слов. Поскольку в корпусе исследований в области естественных наук и биомедицины есть больше слов, таких как «доказательство», «запись», «исследователь» и т. Д., Которые не различают слова, я добавил дополнительные слова (которые я нашел в текущем корпусе) в список стоп-слов, состоящий из 520 слов. Кроме того, на этом этапе я перевел все буквы в нижний регистр, что необходимо, чтобы алгоритм не считал «Прочитать» и «Прочитать» как два разных слова.

def remove_stopwords(doc):
    retracted_corpus=[]
    for text in doc:
        retracted_abstract=[]
        for word in text: 
            word=word.lower()
            if word not in nltk_stopwords:
                retracted_abstract.append(word)
        retracted_corpus.append(retracted_abstract)
    return retracted_corpus

abstract_no_stop = remove_stopwords(abstract_processed)

iii. Изготовление биграмм

В литературе по естественным наукам часто встречаются биграммы, такие как «клеточный цикл» и «протеинфосфатаза». Эти биграммы передают значение, которое не очевидно при рассмотрении любого слова по отдельности. Поэтому я решил собрать биграммы с помощью библиотеки Python Gensim, еще одной отличной библиотеки Python для обработки естественного языка. На этом этапе создаются биграммы и униграммы, где биграммы выбираются в соответствии с конкретными условиями по частоте появления в корпусе.

#using gensim to construct bigrams
from gensim.models.phrases import Phrases, Phraser
bi_phrases=Phrases(abstract_processed, min_count=5, threshold=10)
bigram = Phraser(bi_phrases)

#provides unigrams and bigrams
def dimers(doc):
    updated_abstract=[]
    for text in doc:
        di = bigram[text]
        updated_abstract.append(di)
    return updated_abstract

abstract_bigram = dimers(abstract_no_stop)

После этого я удалил все, что было только цифрами или длиной менее 2 символов.

def abstract_bigram_clean(doc):
    retracted_corpus=[]
    for text in doc:
        retracted_abstract=[]
        for word in text:
            if not word.isdigit() and len(word)>1:
                retracted_abstract.append(word)
        retracted_corpus.append(retracted_abstract)
    return retracted_corpus

abstract_clean = abstract_bigram_clean(abstract_bigram)

На этих этапах обработки я получил список списков, каждый из которых содержит слова, взятые из одного реферата. Чтобы дать представление о сложности корпуса, в корпусе 35 155 уникальных слов, которые содержат чуть более 6000 абстрактов.

Построение модели LDA

Перед построением модели нам нужно, чтобы наш корпус (все документы) присутствовал в матричном представлении. Для этой цели я подготовил словарь, в котором каждому уникальному слову присваивается индекс, а затем использовал его для создания матрицы документ-термин, также называемой пакетом слов (BoW). Я использовал Gensim для выполнения всех этих задач. Кроме того, 11 998 слов встречаются только один раз. Я удалил их, так как они не указывают на какие-либо закономерности, которые модель обнаружит. Более того, все слова, встречающиеся более чем в 20% документов, были удалены, поскольку они не ограничивают некоторые темы.

# create a dictionary 
from gensim.corpora import Dictionary
dictionary = Dictionary(abstract_clean)
dictionary.filter_extremes(no_below=2, no_above=0.2)

# convert the dictionary into the bag-of-words (BoW)/document term matrix
corpus = [dictionary.doc2bow(text) for text in abstract_clean]

Чтобы построить модель LDA, нам нужно указать количество тем, которое мы ожидаем в корпусе. Это может быть сложно и требует нескольких попыток проб и ошибок, поскольку мы не знаем, сколько тем присутствует. Один из способов оценить это число - вычислить показатель согласованности², показатель, который оценивает качество тем, вычисленных с помощью тематических моделей, и, таким образом, отличает хорошую тематическую модель от плохой.

Мера когерентности рассчитывается в четыре этапа:

  • Сегментация - в котором набор слов t может быть разделен на подмножества слов S
  • Расчет вероятности - где вероятности слов P рассчитываются на основе справочного корпуса.
  • Мера подтверждения - оба набора S и P используются мерой подтверждения для расчета 𝜙 соглашений пар S
  • Агрегация. Наконец, все подтверждения объединяются в единое значение согласованности c.

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

# instantiating an lda model
LDA = gensim.models.ldamodel.LdaModel 

#computing coherence for different LDA models containing different number of topics 
def calculate_coherence(dictionary, corpus, texts, start, stop, step):
    coherence_scores=[]
    for num_topics in range(start,stop,step):
        model=LDA(corpus=corpus, id2word=dictionary,    num_topics=num_topics)
        coherence_lda=CoherenceModel(model=model, texts=texts, dictionary=dictionary, coherence='c_v')
        coherence=coherence_lda.get_coherence()
        coherence_scores.append(coherence)
    return coherence_scores

coherence_scores = calculate_coherence(dictionary=dictionary, corpus=corpus, texts=abstract_clean, start=2, stop=40, step=3)

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

Я решил построить свою модель LDA, используя 14 тем.

lda_model_abstract = LDA(corpus=corpus,id2word=dictionary, num_topics=14, random_state=10,chunksize=6485,passes=100)

Визуализация

Это ключевой шаг для чтения и понимания тем, полученных от LDA, и pyLDAvis помогает нам в этом. pyLDAvis³ - это пакет Python для интерактивной визуализации тем. Он является производным от LDAvis, который представляет собой веб-инструмент для визуализации тем, оцениваемых с помощью LDA.

pyLDAvis предоставляет две панели для визуализации: Левая панель показывает темы в виде кругов в двух измерениях. Центр кругов определяется путем вычисления межтематических расстояний, а затем с использованием многомерного масштабирования они проецируются на двухмерные. Таким образом, темы, которые тесно связаны, становятся ближе. Кроме того, кружки показывают общую распространенность темы. Таким образом, чем больше круг, тем более распространенной является тема в корпусе. Правая панель показывает гистограмму ключевых терминов для выбранной темы на левой панели. Наложенные столбцы отображают частоту употребления различных терминов в зависимости от темы красным цветом, а частоту всего корпуса - серым цветом. Таким образом, эта правая панель помогает нам понять смысл тем. Обе панели связаны таким образом, что при выборе темы на левой панели важные термины отображаются на правой панели. Дополнительно при выборе термина на правой панели отображается его условное распределение по всем темам. Интересная вещь в pyLDAvis - это метод ранжирования терминов в теме, который называется релевантностью. Релевантность - это средневзвешенное значение логарифма вероятности термина и его подъемной силы. Рост определяется как отношение вероятности термина в теме к его предельной вероятности во всем корпусе. Релевантность термина w теме k с параметром веса λ может быть математически определена как:

где 𝜙𝑘𝑤 - вероятность термина 𝑤∈1..𝑉 для темы 𝑘∈1..𝐾, где 𝑉 - количество терминов в словаре корпуса; 𝑝𝑤 - это предельная вероятность появления термина в корпусе. 𝜆 находится между 0 и 1. Он определяет вес, который придается вероятности выполнения термина 𝑤 в теме 𝑘 по сравнению с лифтом, связанным с 𝑤. Когда 𝜆 = 1, термины ранжируются в порядке убывания их тематической вероятности. Когда 𝜆 = 0, термины ранжируются в темах в соответствии с их ростом. pyLDAvis предоставляет пользовательский интерфейс для настройки 𝜆. Для интерпретации тем я оставил 𝜆 = 0,6, что также является оптимальным значением, полученным в результате исследования пользователей.

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

Были получены следующие темы (перечислены в порядке убывания их распространенности):

Вывод:

Во-первых, тематическое моделирование с использованием LDA показало хорошее разрешение / разделение тематических терминов для тем 1–9 и 12, за исключением 5, и я нашел интерпретацию темы довольно простой. Но интерпретация других тем была затруднена из-за того, что в одну тему входило много не связанных между собой терминов, что указывает на то, что тематическая модель улавливает шум или идиосинкразические корреляции в корпусе. Выбор большего количества тем не улучшил их интерпретацию. Важно отметить, что, поскольку корпус невелик (всего около 6000 статей), содержит только аннотации (краткий текст) и словарный запас составляет 23 157, это может быть причиной того, что в некоторых случаях тематическая модель выбирает шум.

Во-вторых, темы с 1 по 7 показали аналогичную распространенность тем, которая колеблется от 10,2% до 7,9% токенов. Таким образом, указывается, что большинство из этих тем одинаково важны или распространены в корпусе отозванной литературы.

В заключение, несмотря на небольшой набор данных, LDA смогло найти 14 тем в отозванной литературе, которые в основном включают медицину, клеточный цикл и пролиферацию, рак, иммунологию, окислительный стресс, генетику, центральную нервную систему и когнитивные функции. Не будет ошибкой сказать, что LDA - очень мощный инструмент, который обеспечивает простой и быстрый способ исследования шаблонов или тем в корпусе.

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

  1. Блей Д.М., Нг, А.Ю. and Jordan, M.I., 2003. Скрытое размещение дирихле. Журнал исследований по машинному обучению, 3 (январь), стр. 993–1022.
  2. Рёдер, М., Оба, А. и Хиннебург, А., 2015, февраль. Изучение пространства мер когерентности темы. В материалах восьмой международной конференции ACM по веб-поиску и интеллектуальному анализу данных (стр. 399–408). ACM.
  3. Сиверт, К. и Ширли, К., 2014. LDAvis: метод визуализации и интерпретации тем. В материалах семинара по интерактивному изучению языка, визуализации и интерфейсам (стр. 63–70).