- PVSM.RU - https://www.pvsm.ru -

Учим машину разбираться в генах человека

Всегда приятно осознавать, что применение технологий сводится не только к финансовой выгоде, бывают ещё и идеи, делающие мир лучше. Об одном из проектов с такой идеей мы и расскажем в этот морозный пятничный день. Вы узнаете о решении, которое позволило увеличить точность экспресс-анализа крови, с помощью применения алгоритмов машинного обучения для выявления связей между микро-РНК и генами. Также, стоит отметить, что методы, описанные ниже можно использовать не только в биологии.

Учим машину разбираться в генах человека - 1

Цикл статей «Digital Transformation»

Технологические статьи:
1. Начало [1].
2. Лотерея в облаке [2].
3. Блокчейн в банке [3].
4. Учим машину разбираться в генах человека.
5. Loading…

Серия интервью с Дмитрием Завалишиным на канале DZ Online [4]:
1. Александр Ложечкин из Microsoft: Нужны ли разработчики в будущем? [5]

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

Проблема

Задача системы Miroculus [6] — выявлять взаимосвязь отдельных микро-РНК [7] с определенными генами или заболеваниями. На основе этих данных разрабатывается и постоянно совершенствуется инструмент, с помощью которого исследователи смогут быстро выявлять связи между микро-РНК, генами и типами заболеваний (например, онкологическими).

Хотя в медицинской литературе доступна масса исследований касательно взаимозависимости между отдельными микро-РНК, генами и заболеваниями, единая централизованная база данных, которая содержала бы такую информацию в упорядоченной структурированной форме, отсутствует.

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

Выявление связей между объектами в неструктурированном тексте называется извлечением отношений [8].

Строго говоря, задача получает неструктурированные текстовые входные данные и группу объектов, а затем выводит результирующую группу триад вида «первый объект, второй объект, тип связи». То есть это подзадача в рамках более крупной задачи извлечения информации [9].

Поскольку мы имеем дело с двоичной классификацией, нам необходимо создать классификатор, который получает предложение и пару объектов, а затем выводит результирующий балл в диапазоне от 0 до 1, отражающий вероятность наличия связи между этими двумя объектами.

Например, можно передать классификатору предложение «mir-335 регулирует BRCA1» и пару объектов (mir-335, BRCA1), и классификатор выдаст результат «0,9».

Исходный код для этого проекта доступен на странице [10].

Создание набора данных

Мы использовали текст медицинских статей из двух источников данных: PMC [11] и PubMed [12].

Текст документов, загруженных из указанных источников, был разделен на предложения с помощью библиотеки TextBlob [13].

Каждое предложение было передано в инструмент распознавания объектов GNAT [14], чтобы извлечь названия микро-РНК и генов, которые содержатся в предложении.

Одна из самых сложных задач, связанных с извлечением отношений (или с базовыми задачами машинного обучения) — наличие данных с метками. В нашем проекте такие данные были недоступны. К счастью, мы могли использовать метод «дистанционного наблюдения».

Дистанционное наблюдение

Термин «дистанционное наблюдение» был впервые введен в исследовании [15] «Дистанционное наблюдение при извлечении отношений без использования данных с метками» Минцем и соавторами. Метод дистанционного наблюдения предполагает создание набора данных с метками на основе базы данных известных связей между объектами и базы данных статей, в которых эти объекты упоминаются.

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

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

Учим машину разбираться в генах человека - 2

Преобразование текста

После создания обучающего множества с метками создается классификатор связей с помощью библиотеки Python scikit-learn [16] и нескольких библиотек Python на базе технологий обработки естественного языка (NLP). В порядке эксперимента мы попробовали использовать несколько разных отличительных признаков и классификаторов.

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

Замена объекта

Идея в том, что обучение модели не требуется в соответствии с именем конкретного объекта, однако оно необходимо в соответствии со структурой текста.

Пример:

miRNA-335 was found to regulate BRCA1

Выполняется преобразование в:

ENTITY1 was found to regulate ENTITY2

То есть мы практически взяли все пары объектов из каждого предложения и для каждой из них заменили искомые объекты местозаполнителями. При этом ОБЪЕКТ1 всегда заменяет микро-РНК, а ОБЪЕКТ2 — ген. Мы также использовали еще один специальный местозаполнитель, чтобы помечать объекты, которые являются частью предложения, но не участвуют в искомой связи.

Итак, для следующего предложения:

High levels of expression of miRNA-335 and miRNA-342 were found together with low levels of BRCA1 

мы получили следующий набор преобразованных предложений:

High levels of expression of ENTITY1 and OTHER_ENTITY were found together with low levels of ENTITY2
High levels of expression of OTHER_ENTITY and ENTITY1 were found together with low levels of ENTITY2

На этом этапе можно использовать метод Python string.replace(), если требуется заменить объекты, а также методы itertools.combinations или itertools.product, если необходимо просмотреть все возможные комбинации.

Разметка

Разметка — это процесс разделения последовательности слов на сегменты меньшего размера. В данном случае мы разделяем предложения на слова.
Для этого мы используем библиотеку nltk [17]:

import nltk
tokens = nltk.word_tokenize(sentence)

Усечение

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

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

WINDOW_SIZE = 3
# make sure that we don't overflow but using the min and max methods
FIRST_INDEX = max(tokens.index("ENTITY1") - WINDOW_SIZE , 0)
SECOND_INDEX = min(sentence.index("ENTITY2") + WINDOW_SIZE, len(tokens))
   
trimmed_tokens = tokens[FIRST_INDEX : SECOND_INDEX]

Нормализация

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

Удаление стоп-слов/чисел

В данном случае мы используем стандартный процесс удаления стоп-слов и чисел из предложения. Стоп-словами называются слова с высокой частотностью, например, предлоги «в», «к» и «на». Поскольку эти слова встречаются в предложениях очень часто, они не несут в себе смысловой нагрузки о связях между объектами в предложении.

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

Выделение корней

Выделение корней [18] — это процесс сокращения отдельного слова до корня.
В результате объем семантического пространства для слова сокращается, что позволяет сосредоточиться собственно на значении слова.

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

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

cleaned_tokens = []
porter = nltk.PorterStemmer()

for t in trimmed_tokens:
    normalized = t.lower()
    if (normalized in nltk.corpus.stopwords.words('english') 
        or normalized.isdigit() or len(normalized) < 2):
        continue
    stemmed = porter.stem(t)
    processed_tokens.append(stemmed)

Представление отличительных признаков

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

Мы использовали три типа признаков: мультимножество слов, синтаксические признаки и векторное представление слов.

Мультимножество слов

Модель мультимножества слов [19] (МС) — распространенный метод, используемый в задачах обработки естественного языка (NLP) для преобразования текста в числовое векторное пространство.

В модели МС каждому слову в словаре назначается уникальный числовой идентификатор. Затем каждое предложение преобразуется в вектор в объеме словаря. Положение в векторе выражено значением «1» в том случае, если слово с таким идентификатором является текстом, или значением «0» в противном случае. В качестве альтернативного подхода можно настроить отображение в каждом элементе вектора количества вхождений данного слова в тексте. С примером можно ознакомиться здесь [20].

Тем не менее описанная выше модель не учитывает порядок различных слов в предложении, а только вхождение каждого отдельного слова. Чтобы включить порядок слов в модель, мы использовали популярную модель N-граммы [21], которая оценивает совокупность последовательных слов длиной в N слов и обрабатывает каждую такую совокупность как отдельное слово.

Дополнительные сведения об использовании N-грамм в текстовом анализе см. в разделе [22] «Представление отличительных признаков для текстового анализа: однограмма, двуграмма, триграмма… сколько же всего?».

К счастью для нас, модели МС и N-граммы реализованы в scikit-learn посредством класса CountVectorizer [23].

В следующем примере показано преобразование текста в представление МС 1/0 с помощью модели триграммы.

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(analyzer = "word", binary = True, 
                             ngram_range=(3,3))

# note that 'samples' should be a list/iterable of strings
# so you might need to convert the processes tokens back to sentence
# by using " ".join(...)

data_features = vectorizer.fit_transform(samples)

Синтаксические признаки

Мы использовали два типа синтаксических признаков: маркеры части речи [24] (ЧР) и деревья синтаксического разбора с зависимостями [25].

Мы решили использовать spacy.io [26], чтобы извлечь и маркеры ЧР, и графы зависимости, поскольку эта технология превосходит существующие библиотеки Python в плане скорости, а точность сопоставима с другими системами NLP.

Следующий фрагмент кода извлекает ЧР для данного предложения:

from spacy.en import English
parser = English()
parsed = parser(" ".join(processed_tokens))
pos_tags = [s.pos_ for s in parsed]

После преобразования всех предложений можно использовать описанный выше класс CountVectorizer и модель мультимножества слов для маркеров ЧР, чтобы преобразовать их в числовое векторное пространство.

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

Векторные представления слов

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

Дополнительные сведения о векторном представлении слов см. в следующей статье [27]блога.

Мы применили подход, описанный в документе Paragraph Vector [28]: внедрение предложений (или документов) в высокоразмерное пространство отличительных признаков. Мы использовали реализацию Doc2Vec библиотеки Gensim [29]. Дополнительные сведения доступны в этом учебном пособии [30].

Как параметры, так и размер используемых выходных векторов соответствуют рекомендациям, приведенным в документе Paragraph Vector и учебном пособии по Gensim.

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

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

Оценка моделей классификации

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

Для классификации использовался алгоритм логистической регрессии [31]. Мы опробовали и такие алгоритмы, как машина опорных векторов и случайный лес, однако логистическая регрессия показала лучшие результаты в плане скорости и точности.

Прежде чем приступить к оценке точности данного метода, необходимо разделить [32]набор данных на обучающее множество и тестовый набор. Для этого достаточно просто использовать метод train_test_split:

from sklearn.cross_validation import train_test_split
x_train, x_test, y_train, y_test = train_test_split(data, labels, test_size=0.25)

Этот метод разделяет набор данных произвольно, причем 75 % данных относится к обучающему множеству, а 25 % — к тестовому набору.

Чтобы обучить классификатор на основе логистической регрессии, мы использовали класс scikit-learn LogisticRegression [33]. Для оценки производительности классификатора мы применяем класс classification_report [34], который выводит на печать данные о точности [35], полноте возврата [36] и балл F1-Score [37] для классификации.

В следующем фрагменте кода показано обучение классификатора логистической регрессии и вывод на печать отчета о классификации:

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

clf = linear_model.LogisticRegression(C=1e5)
clf.fit(x_train, y_train)
y_pred = clf.predict(x_test)
print classification_report(y_test, y_pred)

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

  precision    recall  f1-score   support

      0       0.82      0.88      0.85      1415
      1       0.89      0.83      0.86      1660
      
avg / total   0.86      0.85      0.85      3075

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

Результаты

Мы объединили все описанные выше методы и приемы и сравнили различные отличительные признаки и преобразования, чтобы выбрать оптимальную модель.

Мы использовали класс LogisticRegressionCV [38] для создания двоичного классификатора с настраиваемыми параметрами, а затем проанализировали другой тестовый набор, чтобы оценить производительность модели.
Обратите внимание, что для простого и удобного тестирования различных параметров разных отличительных признаков можно использовать класс GridSearch [39].
В следующей таблице приведены основные результаты сравнения различных отличительных признаков.
Для проверки точности модели использовалась шкала F1-Score [37], поскольку она позволяет оценить как точность, так и полноту возврата в модели.

Возможности F1-Score
Одно-триграммы (мультимножество слов) 0,87
Одно-триграммы (МС) и триграммы (маркеры ЧР) 0,87
Одно-триграммы (МС) и Doc2Vec 0,87
Однограммы (мультимножество слов) 0,8
Двуграммы (мультимножество слов) 0,85
Триграммы (мультимножество слов) 0,83
Doc2Vec 0,65
Триграммы (маркеры ЧР) 0,62

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

Хотя модель Doc2Vec отличается максимальной производительностью при определении схожести слов, она не гарантирует достойных результатов в плане извлечения отношений.

Варианты использования

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

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

Автор: sahsAGU

Источник [40]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/270202

Ссылки в тексте:

[1] Начало: https://habrahabr.ru/company/microsoft/blog/341854/

[2] Лотерея в облаке: https://habrahabr.ru/company/microsoft/blog/342148/

[3] Блокчейн в банке: https://habrahabr.ru/company/microsoft/blog/342364/

[4] DZ Online: https://www.youtube.com/channel/UCJuwCFeP6rhSUqk9gRMAwuw/feed

[5] Александр Ложечкин из Microsoft: Нужны ли разработчики в будущем?: https://habrahabr.ru/company/microsoft/blog/342596/

[6] Miroculus: http://www.miroculus.com/

[7] микро-РНК: https://en.wikipedia.org/wiki/MicroRNA

[8] извлечением отношений: https://en.wikipedia.org/wiki/Relationship_extraction

[9] извлечения информации: https://en.wikipedia.org/wiki/Information_extraction

[10] странице: https://github.com/CatalystCode/corpus-to-graph-ml

[11] PMC: http://www.ncbi.nlm.nih.gov/pmc/

[12] PubMed: http://www.ncbi.nlm.nih.gov/pubmed

[13] TextBlob: http://textblob.readthedocs.io/en/dev/

[14] GNAT: http://gnat.sourceforge.net/

[15] исследовании: http://web.stanford.edu/~jurafsky/mintz.pdf

[16] scikit-learn: http://scikit-learn.org/

[17] nltk: http://www.nltk.org/

[18] Выделение корней: https://en.wikipedia.org/wiki/Stemming

[19] Модель мультимножества слов: https://en.wikipedia.org/wiki/Bag-of-words_model

[20] здесь: https://en.wikipedia.org/wiki/Bag-of-words_model#Example_implementation

[21] N-граммы: https://en.wikipedia.org/wiki/N-gram

[22] разделе: https://www.microsoft.com/developerblog/2015/11/29/feature-representation-for-text-analyses/

[23] CountVectorizer: http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html

[24] маркеры части речи: https://en.wikipedia.org/wiki/Part-of-speech_tagging

[25] деревья синтаксического разбора с зависимостями: https://en.wikipedia.org/wiki/Parse_tree#Dependency-based_parse_trees

[26] spacy.io: https://spacy.io/

[27] статье : http://colah.github.io/posts/2014-07-NLP-RNNs-Representations/

[28] Paragraph Vector: https://cs.stanford.edu/~quocle/paragraph_vector.pdf

[29] Gensim: https://radimrehurek.com/gensim/

[30] учебном пособии: https://github.com/piskvorky/gensim/blob/develop/docs/notebooks/doc2vec-IMDB.ipynb

[31] логистической регрессии: https://en.wikipedia.org/wiki/Logistic_regression

[32] разделить : https://en.wikipedia.org/wiki/Test_set

[33] LogisticRegression: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html

[34] classification_report: http://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html

[35] точности: https://en.wikipedia.org/wiki/Precision_and_recall#Precision

[36] полноте возврата: https://en.wikipedia.org/wiki/Precision_and_recall#Recall

[37] балл F1-Score: https://en.wikipedia.org/wiki/F1_score

[38] LogisticRegressionCV: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegressionCV.html

[39] GridSearch: http://scikit-learn.org/stable/auto_examples/model_selection/grid_search_text_feature_extraction.html

[40] Источник: https://habrahabr.ru/post/343604/?utm_campaign=343604