Создание поисковой системы по литературе по исследованию коронавируса на базе данных CORD-19

Повышение эффективности исследований COVID-19

Ученые изо всех сил пытаются исследовать COVID-19, но прогресс не всегда бывает таким чистым и эффективным, как нам хотелось бы думать.

Несколько дней назад Институт Аллена, Microsoft и другие выпустили CORD-19, (насколько мне известно) беспрецедентный набор данных, полный тысяч медицинских статей о коронавирусе (и связанных темах). Как пишет Эрик Хорвиц, технический сотрудник и главный научный директор Microsoft, в статье, которая познакомила меня с набором данных CORD-19:

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

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

В этой статье я покажу, как поисковая система по исследованию коронавируса находит наиболее подходящие исследовательские работы в CORD-19 о COVID-19 по любому запросу (например, «Что мы знаем о генетике, происхождении и эволюции коронавируса?») 'или' Какие тесты проводились на масках низкого уровня для борьбы с коронавирусом? ').
(Если хотите, прокрутите вниз до начала последнего раздела, чтобы увидеть некоторые возможности поисковой системы).

Таким образом, исследователи могут найти доступные исследования и воспроизвести их, чтобы укрепить свои выводы или использовать их в качестве ступеньки к более продвинутым исследованиям, упрощая навигацию и применение массивного набора данных CORD-19.

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

Повестка дня

Я расскажу вам о проблемах, возникающих в процессе работы поисковой системы, и о том, как они были преодолены.

  1. Загрузка, очистка и форматирование данных.
  2. Создание классов данных для набора исследовательских данных и статей для инициализации базы данных.
  3. Создание поискового индекса (+ объяснение алгоритма поисковой системы BM25).
  4. Демонстрация возможностей поисковой системы поиска по COVID-19.

Загрузка, очистка и форматирование данных

Данные поступают из набора данных открытого исследования COVID-19, созданного Институтом Аллена в сотрудничестве с такими организациями, как Microsoft, Белый дом, Джорджтаунский университет и другими. Описание набора данных выглядит следующим образом:

В ответ на пандемию COVID-19 Белый дом и коалиция ведущих исследовательских групп подготовили набор данных открытых исследований COVID-19 (CORD-19). CORD-19 - это ресурс, содержащий более 29000 научных статей, в том числе более 13000 с полными текстами, о COVID-19, SARS-CoV-2 и связанных с ними коронавирусах. Этот свободно доступный набор данных предоставляется мировому исследовательскому сообществу для применения последних достижений в обработке естественного языка и других методов искусственного интеллекта для получения новых идей в поддержку продолжающейся борьбы с этим инфекционным заболеванием. Эти подходы становятся все более актуальными из-за быстрого увеличения количества публикаций о новых коронавирусах, что затрудняет работу сообщества медицинских исследователей.

А теперь приступим к проекту!

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

Затем код DOI необходимо преобразовать в URL-адрес. Для тех, кто не знает, DOI или цифровой идентификатор объекта часто используется как своего рода идентификатор для онлайн-статей. Каждая статья имеет свой собственный уникальный и постоянный идентификатор, и к ней можно получить доступ по URL-адресу https:/doi.org/{ID}, где {ID} заменяется любым кодом DOI, присвоенным этой статье. Даже если, как указано в наборе данных, некоторые статьи не являются полным текстом, мы можем получить доступ к полному тексту с веб-сайта DOI с помощью библиотеки Python requests.

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

Некоторые статьи были собраны из разных источников, поэтому есть несколько дубликатов. Их нужно отбросить.

Форматирование авторов зависит от бумаги. Некоторые заключают имена авторов в скобки (которые удаляются), а некоторые используют формат именования [Имя 1] [Фамилия 1], [Имя 2] [Фамилия 2] и т. Д. Вместо [Фамилия 1] , [Имя 1]; [Фамилия 2], [Имя 2] и т. Д. Это необходимо исправить.

Наконец, наши очищенные данные сияют, как ромб:

Рад, что ты спросил!

Создание классов данных для набора данных

Объектно-ориентированное программирование на Python - это прекрасно, поэтому давайте воспользуемся этим. У нас будет два класса, чтобы немного упростить навигацию по источникам данных:

  • dataset, которые предоставляют полезные функции для навигации по набору данных.
  • paper, в котором содержится более подробная информация о каждом документе.

dataset будет иметь следующие атрибуты и внутренние переменные:

  • Внутренняя переменная self.metadata, содержащая метаданные всех статей.
  • Функция get_item, которая возвращает полную длину запрошенной статьи.
  • Функция length, которая возвращает количество статей в базе данных.
  • Функция head, которая возвращает несколько первых статей в базе данных.
  • Функция tail, которая возвращает несколько последних документов в базе данных.
  • Функция abstracts, которая возвращает список всех рефератов в базе данных.
  • Функция titles, которая возвращает список всех заголовков в базе данных.
  • Функция html, которая извлекает HTML-код с веб-сайта DOI (здесь пригодится форматирование URL-адреса веб-сайта DOI).

… И paper будут иметь следующие внутренние переменные и функции:

  • Внутренняя переменная self.paper, содержащая бумажные данные.
  • Функция doi, которая возвращает (DOI) URL-адрес статьи.
  • Функция html, которая возвращает бумагу, отформатированную с использованием исходного HTML.
  • Функция text, которая возвращает текст статьи, полученный с сайта DOI paper.
  • Функция abstract, которая возвращает реферат статьи.
  • Функция title, которая возвращает название статьи.
  • Функция authors, которая возвращает список авторов статьи.
  • Функция raw_html, которая возвращает неформатированный HTML-код статьи.

Присваиваем переменную data = dataset(metadata). Это преобразует метаданные в dataset объект, и оттуда мы можем использовать чистые .function() аспекты объекта.

В качестве демонстрации мы можем просмотреть авторов 3400-й статьи в базе данных с data[3400].authors(print=True):

Мы также можем просмотреть paper класс данных объекта, вызвав первый документ в dataset классе данных: data[0]

Мы также можем отображать HTML-код страницы с атрибутом html класса paper. Обратите внимание, что CSS (который обычно не включается в файл HTML), управляющий цветами, будет недоступен для большинства документов, но отображается необходимое форматирование HTML.

data[0].html()

Ух ты!

Я рада, что вы согласны! Использование объектно-ориентированных методов в Python для структурирования данных делает работу с ними более приятной.

Создание поискового индекса (+ пояснение по BM25)

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

Но сначала текст должен быть размечен. Токенизация - это процесс разбиения текста на отдельные слова, возможно, с исключением некоторых знаков препинания и стоп-слов. Стоп-слова - это обычно используемые в английском языке слова, передающие мало смысла, такие как «а», «ан», «но» и т. Д. В некоторых случаях, например, для создания текста, глупо отбрасывать стоп-слова, но в данном В этом случае использование стоп-слов в тексте может сбить с толку поисковую систему. Токенизацию можно выполнить в одну строку с помощью библиотеки Python nltk.
Обратите внимание, что до токенизации весь текст был сделан в нижнем регистре. Все это будет сделано в preprocess(text) функции.

Затем мы снова воспользуемся преимуществами объектно-ориентированного программирования на Python с двумя структурами данных - search_results и word_tokens.

search_results содержит следующие внутренние переменные и функции:

  • Внутренняя переменная self.results, содержащая данные результатов поиска.
  • Функция get_item, которая возвращает полные атрибуты Paper с учетом индекса элемента в результатах поиска.
  • Функция length, которая возвращает длину результатов поиска.
  • Функция raw_html, которая возвращает необработанный HTML-код результатов поиска.

word_tokens содержит следующие внутренние переменные и функции:

  • Внутренняя переменная self.corpus, содержащая набор текстов.
  • Внутренняя переменная search_str, которая объединяет заголовок и аннотацию каждой статьи для строкового поиска.
  • Внутренняя переменная self.index, которая содержит термины каждой статьи (в заголовке и в аннотации).

Это сделает код чище, даже если для его ввода потребуется немного больше времени.

Теперь пора перейти к поисковому алгоритму BM25!

Алгоритм BM25

Алгоритм BM25 вычисляет оценку для каждого документа в корпусе, которая представляет его пригодность для запроса.

  • q sub i - это i -й термин запроса. Если бы запрос был «как дела», формула перебирала бы «как» (индекс 0), «есть» (индекс 1) и «вы» (индекс 2).
  • Функция IDF представляет обратную частоту документа (это может показаться знакомым по TD-IDF). Функция IDF находит и штрафует слова, которые являются общими для всех документов в корпусе, так что выделяются больше различающих / идентифицирующих слов каждого документа.
  • fieldLen/avgFieldLen показывает, какова длина документа по отношению к средней длине документа. Это означает, что чрезмерно длинные документы, которые по своей природе гарантированно лучше «подходят» к запросу, поскольку в них больше слов, масштабируются, а короткие документы, которые «соответствуют» запросу, увеличиваются (делятся на меньшее количество).
  • b - это просто множитель, который показывает, насколько важна метрика fieldLen/avgFieldLen. Если b больше, этому метрике придается больший вес. Это статическая переменная; он устанавливается на определенную переменную и остается там.
  • f(q sub i, D) представляет количество раз, когда q sub i встречается в документе D.
  • k1 - это (постоянная, как b) переменная, которая ограничивает то, насколько один термин запроса может повлиять на оценку документа.

Внедрение BM25

Алгоритм BM (Best Match) 25 (или, если хотите, назовите его формулой) невероятно эффективен. Давайте настроим еще один класс данных (обещаю, последний) как rank_BM25. Это содержит:

  • Ввод структуры данных word_tokens, которая автоматически преобразуется через rank_bm25 библиотеку в индекс BM25, сохраняемый во внутренней переменной self.bm25.
  • Функция search, которая принимает search_query (поисковый запрос) и количество включаемых лучших результатов n. Эта функция предварительно обрабатывает запрос и создает оценку BM25 для каждой статьи, а затем находит статьи с лучшими оценками n BM25, возвращая класс данных search_results (мы создали его ранее) для упрощения навигации.

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

bm25 = rank_BM25(metadata.head(100))
bm25.search('south korea')

Пришло время погрузиться в изучение этой жемчужины поисковой системы!

Демонстрация возможностей поисковой системы

Темы исследований NASEM (Постоянный комитет национальных академий наук, инженерии и медицины по новым инфекционным заболеваниям и угрозам здоровью 21-го века) и План исследований и разработок Всемирной организации здравоохранения по COVID-19 определяют 7 основных вопросов исследования коронавируса.

  • Что известно о передаче, инкубации и устойчивости окружающей среды?
  • Что мы знаем о факторах риска COVID-19?
  • Что мы знаем о генетике, происхождении и эволюции вирусов?
  • Что было опубликовано об этических и социальных науках?
  • Что мы знаем о диагностике и надзоре?
  • Что было опубликовано о медицинском обслуживании?
  • Что мы знаем о вакцинах и терапевтических средствах?

Давайте посмотрим на результаты поисковой системы по первому вопросу:

Красивый!

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

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

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

Примечание редакции: todatascience.com - это издание Medium, в основном основанное на изучении науки о данных и машинного обучения. Мы не профессионалы в области здравоохранения и не эпидемиологи. Чтобы узнать больше о пандемии коронавируса, нажмите здесь.