Data mining Pubmed и Pubchem баз медицинской и биохимической информации

от автора

PubMed представляет собой более чем 28 миллионов цитированний (абстрактов и названий) биомедицинской литературы из журналов наук о жизни, онлайн книг и MEDLINE. Также цитирование может включать в себя полный текст статей.
Типичный запрос в Пабмед — type 2 diabetes natural compound

Pubchem — база данных более 100 млн химический соединений и 236 млн веществ. Также в базе результаты биоактивности 1.25 млн соединений (например активность соединений против рака или ингибирования конкретного гена).
На данный момент известно о 9 млн органических химических соединений (сложных веществ). Неорганических химических веществ может быть огромное количество — от 10**18

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

Для того чтобы продолжить установим необходимые python пакеты Biopython и pubchempy

sudo conda install biopython  pip install pubchempy

PubMed

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

(‘High expression of DEK predicts poor prognosis of gastric adenocarcinoma.’, ‘DEK poor prognosis’, ‘DEK’, 277, 15)

Для чего это нужно — по генам можно подсчитать фармакологическое действие молекул и их комбинаций на цели, которые связаны с плохим прогнозом рака. (Например по базе pubchem или LINCS)

Подгружаем файлы с именами генов (около 12000) https://github.com/a-nai/pubmed_mining

import csv genes=[];  with open('/Users/andrejeremcuk/Downloads/genes.txt', 'r') as fp :     reader = csv.reader(fp, delimiter='\t')     for i in range(20000):       genes.append(reader.next())  import time import numpy as np genesq=np.genfromtxt('/Users/andrejeremcuk/Downloads/genesq.txt',dtype='str') 

Для запроса в пабмед обязательно указать свою электронную почту

from Bio import Entrez from Bio import Medline  MAX_COUNT = 100 Entrez.email = '*@yandex.ru' articles=[];genes_cancer_poor=[];genes_cancer_poor1=[];

Запросы и обработка результатов

for u in range(0,len(genesq)):  print u  if u%100==0:    np.savetxt('/Users/andrejeremcuk/Downloads/genes_cancer_poor.txt', genes_cancer_poor,fmt='%s');   np.savetxt('/Users/andrejeremcuk/Downloads/genes_cancer_poor1.txt', genes_cancer_poor1, fmt='%s')  gene=genesq[u];genefullname=genes[u][2]  TERM=gene+' '+'poor prognosis'  try: h=Entrez.esearch(db='pubmed', retmax=MAX_COUNT, term=TERM)  except: time.sleep(5);h=Entrez.esearch(db='pubmed', retmax=MAX_COUNT, term=TERM)  result = Entrez.read(h)  ids = result['IdList']  h = Entrez.efetch(db='pubmed', id=ids, rettype='medline', retmode='text')  ret = Medline.parse(h)  fer=[];  for re in ret:   try: tr=re['TI'];   except: tr='0';   fer.append(tr);

Нахождение в тексте титла ключевых слов

 for i in range(len(fer)):   gene1=fer[i].find(gene)   gene2=fer[i].find(genefullname)   #####   inc=fer[i].find("Increased")   highe=fer[i].find("High expression")   high=fer[i].find("High")   expr=fer[i].find("expression")   Overe=fer[i].find("Overexpression")   overe=fer[i].find("overexpression")   up1=fer[i].find("Up-regulation")   el1=fer[i].find("Elevated expression")   expr1=fer[i].find("Expression of ")   ####   decr=fer[i].find("Decreased")   loss=fer[i].find("Loss")   low1=fer[i].find("Low expression")   low2=fer[i].find("Low levels")   down1=fer[i].find("Down-regulated")   down2=fer[i].find("Down-regulated")   down3=fer[i].find("Downregulation")   #####   acc=fer[i].find("accelerates")   poor=fer[i].find("poor patient prognosis")   poor1=fer[i].find("poor prognosis")   poor2=fer[i].find("unfavorable clinical outcomes")   poor3=fer[i].find("unfavorable prognosis")   poor4=fer[i].find("poor outcome")   poor5=fer[i].find("poor survival")   poor6=fer[i].find("poor patient survival")   poor7=fer[i].find("progression and prognosis")   ###   canc=fer[i].find("cancer")   canc1=fer[i].find("carcinoma")

, которые мы проверяем на порядок в титле и на присутствие по наиболее распространенным фразам

  if (gene1!=-1)or(gene2!=-1): #<poor1,poor,poor2,poor3,poor4,poor5,poor6,poor7    if (canc1!=-1)or(canc!=-1):     if (poor!=-1)or(poor1!=-1)or(poor2!=-1)or(poor3!=-1)or(poor4!=-1)or(poor5!=-1)or(poor6!=-1)or(poor7!=-1): #      genel=-1;      if (gene1!=-1): genel=gene1;      if (gene2!=-1): genel=gene2;      gene1=genel;      if (expr!=-1): #<poor1,poor,poor2,poor3,poor4,poor5,poor6,poor7       if (gene1<expr):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,1))      if (low1!=-1)and(gene1!=-1):       if (low1<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,2))      if (el1!=-1)and(gene1!=-1):       if (el1<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,3))      if (Overe!=-1)and(gene1!=-1):       if (Overe<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,4))      if (overe!=-1)and(gene1!=-1):       articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,5))      if (expr1!=-1)and(gene1!=-1):       if (expr1<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,6))      if (up1!=-1)and(gene1!=-1):       if (up1<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,7))      if (highe!=-1)and(gene1!=-1):       if (highe<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,8))      if (high!=-1)and(gene1!=-1)and(expr!=-1):       if (high<gene1<expr):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,9))      if (gene1!=-1)and(expr1!=-1):       if (expr1<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,10))      if (gene1!=-1)and(inc!=-1):       if (inc<gene1):         articles.append((fer[i],TERM,gene,u,i));genes_cancer_poor.append((gene,u,i,11))      ###########      if (gene1!=-1)and(decr!=-1):       if (decr<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,12))      if (gene1!=-1)and(loss!=-1):       if (loss<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,13))      if (gene1!=-1)and(low1!=-1):       if (low1<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,14))      if (gene1!=-1)and(low2!=-1):       if (low2<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,15))      if (gene1!=-1)and(down1!=-1):       if (down1<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,16))      if (gene1!=-1)and(down2!=-1):       if (down2<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,17))      if (gene1!=-1)and(down3!=-1):       if (down3<gene1):         articles.append((fer[i],TERM,gene,u,i,'low'));genes_cancer_poor1.append((gene,u,i,18))   

В результате получаем несколько списков: генов с низкой и с высокой экспрессией при плохом прогнозе рака.

Всего нашлось 913 статей с вхождение как ключевых слов так и целевых фраз.

PubChem

Эта база данных предоставляет два способа доступа к своей информации: через REST API в формате json где запрос выглядит так:
https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/2516/description/json
Важно запросов через этот путь не может быть больше 5 в секунду, но пока превышение лимитов я не проверял, должны спасти прокси.

и через библиотеку pubchempy

import pubchempy as pcp c = pcp.Compound.from_cid(5090) c.canonical_smiles

импорт необходимых пакетов PUG REST API

import re import urllib, json, time import numpy as np

функция которая очищает текст от хтмл тэгов

def cleanhtml(raw_html):   cleanr = re.compile('<.*?>')   cleantext = re.sub(cleanr, '', raw_html)   return cleantext

В следующем коде мы будем открывать англоязычные описание молекул от 1 до 100000 номера в pubchem и искать намеки что эта молекула имеет органическую природу (от растения животного или в составе напитка), при этом оно не токсично и не канцерогенно

 natural=[]; for i in range(1,100000):  url = "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/"+str(i)+"/description/json"  time.sleep(0.2)  try: response = urllib.urlopen(url)  except: time.sleep(12);response = urllib.urlopen(url)  data = json.loads(response.read())  op=0;ol=0;ot=0;  try:   for u in range(1,len(data['InformationList']['Information'])):    soup=str(data['InformationList']['Information'][u]['Description'])    soup1=cleanhtml(soup)     if (soup1.find('carcinogen')!=-1)or(soup1.find('death')!=-1)or(soup1.find('damage')!=-1): break;    if (soup1.find('toxic')!=-1): break;    if (soup1.find(' plant')!=-1)and(op!=9)and(soup1.find('planting')==-1):      natural.append((i,'plant',str(data['InformationList']['Information'][0]['Title'])));op=9;    if (soup1.find(' beverages')!=-1)and(ot!=9):      natural.append((i,'beverages',str(data['InformationList']['Information'][0]['Title'])));ot=9;    if (soup1.find(' animal')!=-1)and(ol!=9):      natural.append((i,'animal',str(data['InformationList']['Information'][0]['Title'])));ol=9;  except: ii=0;  if i%100==0: print i;np.savetxt('/Users/andrejeremcuk/Downloads/natural.txt', natural,fmt='%s', delimiter='<')

Для поиска упоминаний в тексте растения используем .find(‘ plant’)

В конце сохраняем файл с получившимися органическими соединениями и их номеров в ПабЧем-е.

https://github.com/a-nai/pubmed_mining/tree/master


ссылка на оригинал статьи https://habr.com/post/424271/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *