Работа с файлами MeSH в Python: связывание терминов и номеров

24 января 2018

В этом учебнике показано, как мы можем использовать различные аспекты Python (например, словари, списки и регулярные выражения) вместе для решения различных проблем. Он также показывает, как мы можем использовать Python для связывания отношений в файле MeSH, что упрощает понимание его иерархии и структуры.

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

Что такое MeSH?

MeSH является акронимом для медицинских рубрик. Он считается контролируемой лексикой (тезаурусом) Национальной библиотеки США, которая обеспечивает единообразие и последовательность индексации и каталогизации биомедицинской литературы. MeSH, отличительная особенность MEDLINE, устроена иерархически, называемая структурой дерева MesH, и обновляется ежегодно.

MeSH является, таким образом, номенклатурой медицинских терминов, доступных из Национальной медицинской библиотеки США, которая направлена ​​на создание новых знаний путем использования отношений между терминами, которые аннотируют биомедицинскую литературу.

Поиск людей MEDLINE PubMed и другие базы данных используют MeSH для поиска объектов. Индексы Национальной библиотеки медицины (НЛМ) используют MeSH для описания предметного содержания журнальных статей для MEDLINE. Каталогизаторы используют MeSH для описания книг и аудиовизуальных материалов в NLM и других библиотечных коллекциях. Поэтому MeSH можно использовать для многочисленных задач, связанных с индексацией, тегами, поиском, извлечением, анализом, кодированием, слиянием и обменом биомедицинским текстом.

Структура файла MeSH

Дескрипторы MeSH организованы в 16 категорий:

A: анатомия B: организмы C: заболевания D: наркотики и химические вещества E: аналитические, диагностические и терапевтические методы и оборудование F: психиатрия и психология G: явления и процессы H: дисциплины и профессии I: антропология, образование, социология и социальные явления J: технология, промышленность, сельское хозяйство K: гуманитарные науки L: информатика M: названные группы N: здравоохранение V: характеристики публикации Z: географические объекты

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

Вот еще несколько сведений о структурах дерева MeSH:

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

Загрузка файла MeSH

Для целей этого руководства нам нужен файл MeSH для работы с Python. Файл MeSH можно найти на сайте загрузки NLM.

Давайте продолжим и загрузим последний файл ASCII MeSH. Сначала мы можем перейти к файловому архиву MeSH FTP: ftp: nlmpubs.nlm.nih.gov онлайн, а затем выбрать каталог 2017. В каталоге asciimeshe вы найдете три.bin-файла: c2017.bin, d2017.bin и q2017.bin. Давайте загрузим d2017.bin. Вы можете скачать файл: ftp: nlmpubs.nlm.nih.gov онлайн-сетка 2017 asciimesh d2017.bin (27.5 MB).

Связывание терминов с числами

Давайте перейдем к сути этой статьи. То, что мы пытаемся сделать, это прочитать файл MeSH (т. Е. Загруженный файл.bin), просмотреть записи, найти все номера MeSH для каждой записи и перечислить термины вместе с их соответствующие номера.

Первое, что мы обычно делаем, это прочитать файл.bin следующим образом:

meshFile = 'd2017.bin'
with open(meshFile, mode='rb') as file:
    mesh = file.readlines()

Обратите внимание, что мы использовали режим rb, что означает, что мы читаем двоичный код без перевода перевода строки.

Нам также необходимо определить выходной файл, в котором мы будем хранить результаты (вывод):

outputFile = open('mesh.txt', 'w')

На этом этапе мы хотим проверить линии, начинающиеся с MH = (термин MeSH) и MN = (номер MeSH). Я не должен делать этого сейчас, но покажу вам снимок файла MeSH, чтобы иметь представление о структуре и удалить любые путаницы (MH и MN окружены красными прямоугольниками соответственно).

Чтобы проверить строки, начинающиеся с MH = и MN =, нам нужно использовать регулярные выражения. Итак, если мы хотим проверить строки, которые начинаются с MH =, за которыми следуют любые символы, мы будем делать это, как показано в приведенном ниже коде (я дойду до строки, которая находится в данный момент). Обратите внимание, что я использовал b вместо r для регулярного выражения, так как мы применяем шаблон к байтовому объекту, а не к строковому объекту, поэтому мы должны использовать шаблон байта.

import re
meshTerm = re.search(b'MH = (.+)$', line)

То же самое относится и к числу MeSH, но на этот раз для строк, начинающихся с MN =.

Возвращаясь к строке, это относится к строкам в файле MeSH. Поэтому мы будем проходить через файл по строкам, ищем условия и номера MeSH. Как видно из приведенного выше моментального снимка MeSH, термин MeSH предшествует номеру MeSH. Таким образом, в нашем коде число MeSH всегда будет числом, соответствующим ранее захваченному термину MeSH. Таким образом, мы сделаем следующее:

for line in mesh:
    meshTerm = re.search(b'MH = (.+)$', line)
    if meshTerm:
        term = meshTerm.group(1)
    meshNumber = re.search(b'MN = (.+)$', line)
    if meshNumber:
        number = meshNumber.group(1)
        numbers[number.decode('utf-8')] = term.decode('utf-8')
        if term in terms:
            terms[term] = terms[term] + ' ' + number.decode('utf-8')
        else:
            terms[term] = number.decode('utf-8')

Давайте перейдем к приведенному выше этапу шаг за шагом. Если мы посмотрим на регулярное выражение MH = (. +) $, Это в основном говорит нам, чтобы найти литерал MH =, за которым следует хотя бы один символ. (.) означает любой символ, а + означает, что он должен быть одним или несколькими символами и возвращать все в конец строки ($).

Скобка вокруг. +, То есть (. +), Является группой захвата, поэтому мы можем получить результат. Итак, для термина MeSH, окруженного красным прямоугольником в приведенном выше снимке, полученным термином будет Calcomycin. Причина, по которой мы используем if-statements, состоит в том, что некоторые строки не начинаются с MH = и MN =.

Для захваченного термина MeSH и номера MeSH мы создаем новую пару ключ-значение для словарного объекта, как показано в этой строке кода: numbers [str (number)] = term.

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

if term in terms:
            terms[term] = terms[term] + ' ' + number.decode('utf-8')
        else:
            terms[term] = number.decode('utf-8')

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

Теперь мы хотим перечислить разные ключи (термины) и указать соответствующие значения (числа), перечисленные в соответствующем термине. Чтобы перечислить различные термины, мы делаем следующее:

meshNumberList = []
meshTermList = terms.keys()
for term in meshTermList:
    item_list = terms[term].split(' ')
    for phrase in item_list:
        meshNumberList.append(phrase)

Наконец, мы перечислим этот термин и его соответствующие номера следующим образом:

used_items = set()
for item in meshNumberList:
    if numbers[item] not in used_items:
        print(numbers[item], 'n', item, file=outputFile)
        used_items.add(numbers[item])
    else:
        print(item, file=outputFile)

Прежде чем показывать вывод программы, давайте перейдем все вместе.

Включение всего этого

В этом разделе я покажу вам, что наша полная программа Python, которая связывает термин MeSH с его номерами, выглядит так:

import re
terms = {}
umbers = {}
meshFile = 'd2017.bin'
with open(meshFile, mode='rb') as file:
    mesh = file.readlines()
outputFile = open('mesh.txt', 'w')
for line in mesh:
    meshTerm = re.search(b'MH = (.+)$', line)
    if meshTerm:
        term = meshTerm.group(1)
    meshNumber = re.search(b'MN = (.+)$', line)
    if meshNumber:
        number = meshNumber.group(1)
        numbers[number.decode('utf-8')] = term.decode('utf-8')
        if term in terms:
            terms[term] = terms[term] + ' ' + number.decode('utf-8')
        else:
            terms[term] = number.decode('utf-8')
meshNumberList = []
meshTermList = terms.keys()
for term in meshTermList:
    item_list = terms[term].split(' ')
    for phrase in item_list:
        meshNumberList.append(phrase)
meshNumberList.sort()
used_items = set()
for item in meshNumberList:
    if numbers[item] not in used_items:
        print(numbers[item], 'n', item, file=outputFile)
        used_items.add(numbers[item])
    else:
        print(item, file=outputFile)

Вывод

Вы можете загрузить выход из Dropbox (1,77 МБ). Принимая образец вывода, как показано ниже, мы можем видеть, как список MeSH (Pterygopalatine Fossa) указан с его номерами MeSH, которые сгруппированы сразу под ним.

Pterygopalatine Fossa 
 A02.835.232.781.670
A02.835.232.781.750
A02.835.232.781.750.150
A02.835.232.781.750.165
A02.835.232.781.750.400

Заключение

В учебнике показано, как мы можем использовать разные аспекты Python (например, словари, списки и регулярные выражения) вместе для решения различных проблем. Он также показывает, как мы можем использовать Python для работы с файлами MeSH для связывания некоторых частей этого сложного файла таким образом, чтобы было легче понять его иерархию и структуру, как это было сделано здесь, связывая термин MeSH с соответствующими номерами MeSH.