본문 바로가기
AI / DL/생명과학을 위한 딥러닝

[생명과학을 위한 딥러닝] 3장. DeepChem을 이용한 머신러닝 (1)

by bri9htstar 2022. 10. 15.

본격적인 내용에 들어가기 전에, 이 코드 하나를 실행시키기 위해 겪은 우여곡절을 정리하려한다.

잘 안 쓰이는 머신러닝 라이브러리인 DeepChem이다보니 환경 셋업만 몇 시간 걸렸는지 모르겠다.

나 같은 사람이 다시 나타나지 않도록…

DeepChem 설치하기

https://deepchem.io/

 

DeepChem

Get Started. Select your preferences, then run the DeepChem install command. Conda is our recommended package manager Version stable nightly Package Manager conda pip docker GPU Enabled

deepchem.io

공식 홈페이지에 친절하게 설치하는 방법을 알려준다. 책에서는 DeepChem 설치법으로 (1)Anaconda, (2)Docker, (3)직접 소스 코드 컴파일하는 방법 중 도커(Docker)로 설치하는 방법을 추천하나, Docker 역시 6시간 동안 설치하다 때려친 경험(…)이 있기 때문에 굉장히 친절한 Anaconda(정확히는 Miniconda)로 설치하였다.

conda install -c conda-forge rdkit deepchem==2.6.1
pip install tensorflow~=2.4

 

작성 날짜 기준 다음 코드를 작성하면 된다. 꼭 두 줄 따로 작성해서 다 설치하자.

 

DLL load failed while importing rdBase : 지정된 모듈을 찾을 수 없습니다

이 오류가 뜬 건 다음 코드를 실행시켰을 시점이었다(고비 1).

tox21_tasks, tox21_datasets, transformers = dc.molnet.load_tox21()

 

아무리 실행해도 지정된 모듈을 찾을 수 없다는 오류만 반복되었다. 해당 파일 위치까지 찾아서 rdBase.pyd 파일이 있는 것을 두눈으로 똑똑히 보았음에도 불구하고…

결론은 파이썬 버전을 다운그레이드하자 해결되었다. 원래 3.9.X 버전을 사용하고 있었는데 3.8.0 버전의 가상환경을 새로 만들어서 jupyter notebook을 실행시키니 아무 일도 없다는 듯 해결되었다. jupyter notebook 특성인진 모르겠는데 책과 달리 해당 코드를 쳐도 Output이 나타나지 않았다.?

 

module 'deepchem.models' has no attribute 'multitaskclassifier'

이 오류가 뜬 건 다음 코드를 실행시켰을 시점이었다(고비 2).

models = dc.models.MultitaskClassifier(n_tasks=12, n_features=1024, layer_sizes=[1000])

 

결론은 PyTorch를 설치하면 됐다.

https://pytorch.org/

 

PyTorch

An open source machine learning framework that accelerates the path from research prototyping to production deployment.

pytorch.org

들어가면 친절하게 알려준다. 나는 아래 코드로 설치했다.

 

kirti141 반응 = 내 반응 (https://github.com/deepchem/deepchem/issues/2913)

이번 과정을 통해 나를 정의하는 코드를 만들 수 있게 되었다.

 

>>> any([born_idiot, alcohol_related_dementia])
True

 

이하 본문.


DeepChem의 기본 데이터셋

본 장에서는 생명과학에 초점(분자 데이터, 유전학 데이터, 현미경 이미지 처리)을 맞춘 DeepChem 라이브러리를 사용한다.

 

필요한 라이브러리를 부르고 넘파이 배열을 만들어 호출해봤다.

배열의 x축은 각 샘플에 대해 5개의 피처를 갖고 있으며, 배열의 y축은 각각의 샘플을 나타낸다.

(1)

배열을 NumpyDataset 객체로 저장하여 출력해본다.

(2)

np.array_equal()로 원본과 동일한지 확인했을 때 True임을 알 수 있다.

 

독성 분자 예측 모델 만들기

DeepChem에는 사용자의 편의를 위해 자주 사용되는 데이터셋을 dc.molnet(MoleculeNet의 줄임말) 모듈에 포함하고 있다. 여기서는 dc.molnet.load_tox21() 명령을 사용해 Tox21 독성 데이터를 불러온다. 여기서 Tox21 독성 데이터는 Tox21 데이터 챌린지 대회에 사용된 데이터로 약물의 독성 예측과 관련된 표적의 실험 데이터를 포함한다. 자세한 것은 https://tripod.nih.gov/tox21/challenge/ 에서 확인.

이 명령을 실행하면 DeepChem이 자동으로 로컬 디스크에 데이터를 다운로드한다.

 

tox21_tasks, tox21_datasets, transformers = dc.molnet.load_tox21()

 

피처화(featurizaiton)는 분자 정보가 포함된 데이터셋을 머신러닝에 사용되는 행렬 및 벡터로 변환하는 것이다. 피처화된 데이터를 간단히 살펴보자.

(3)

이 12개의 값은 생물학적 표적(target)을 나타낸다. 이들 표적은 잠재적인 신약에 대한 독성 반응과 관련돼 있다고 여겨지는 단백질들이다. 이 생물학적 표적 각각에는 실험을 통해 얻은 수치가 포함돼 있다. Tox21 데이터셋에 있는 각각의 분자와 해당 단백질의 결합력을 나타낸다.

 

(4)

tox21_datasets 객체 이름이 복수형인 것은 이 객체가 실제로는 여러 개의 dc.data.Dataset 객체를 포함한 튜플이라는 점을 암시한다. 출력 결과를 보면 dc.molnet 모듈이 로컬 디스크에서 해당 데이터셋을 불러와 DiskDataset 객체로 만들었다는 것을 알 수 있다. 사용하기 위해 데이터셋을 분리한다.

(5) X 벡터의 모양을 알 수 있다.
(6) y 벡터의 모양을 알 수 있다.

y 벡터의 경우 각 샘플에 대해 12개의 데이터 포인트(레이블)가 있다. 이것들은 앞에서 설명한 12가지 표적에 해당한다. 이 데이터셋에서 샘플은 각각의 분자에 해당하고, 각 데이터 포인트의 값은 특정 분자에 대한 생화학 분석 결과값이다.

데이터의 결측치, 여기서는 생화학 분석이 돼 있지 않은 값을 제외하고 실제 측정된 값을 판단하는 법은 가중치를 기록하는 데이터셋의 w 행렬을 사용하면 된다. 가중치는 모델에 대한 손실 함수를 계산할 때마다 작업과 샘플을 합산하기 전에 곱하는 값이다. 이것은 몇 가지 목적으로 사용되는데, 그중 하나가 누락된 데이터를 나타낼 때 사용된다. 만약 가중치가 0이면 해당 레이블은 손실에 영향을 주지 않으며 학습 중에 무시된다. 데이터셋에서 얼마나 많은 레이블이 측정됐는지 확인하기 위해 출력을 해보자.

(7)

w 행렬에 있는 6,264 × 12 - 75,168개의 요소 중 63,647개만 실제로 측정됐다. 나머지 11,521개의 요소는 누락된 측정값에 해당하므로 무시한다.

 

(8)

transformers 변수는 원본 데이터셋을 수정한 객체이다. 위 출력 결과를 통해 BalancingTransformer 도구가 사용된 것을 알 수 있다. 이 도구는 불균형한 데이터셋을 보완하는 데 사용된다. Tox21 데이터셋의 분자 대부분이 표적에 결합하지 않는 데이터셋이며, 실제 90%가 넘는 데이터의 레이블이 0이다. 이런 불균형한 데이터는 분류 문제에서 흔히 접하게 된다.

BalancingTransformer는 각 클래스에 할당된 총가중치가 동일하도록 개별 데이터 요소의 가중치를 조절한다. 이렇게 하면 손실 함수는 어느 한 분류에 대한 선입견을 갖지 않고 학습을 통해 손실 함수의 값을 줄일 수 있다.

 

DeepChem의 dc.models 하위 모듈에는 다양한 생명과학 관련 모델이 포함돼 있다. 이러한 다양한 모델은 모두 부모 클래스 dc.models.Model에서 상속받는다. 이 상위 클래스는 일반적인 파이썬 규칙을 따르는 공통 API를 제공하도록 설계됐다.

 

model = dc.models.MultitaskClassifier(n_tasks=12, n_features=1024, layer_sizes=[1000])

 

MultitaskClassifier 모델은 입력 데이터를 통해 여러 가지 예측값을 출력하는 다층 퍼셉트론을 구축하는 것으로, 모든 샘플에 대해 여러 레이블이 있는 다중 분류 문제를 해결하는 데 사용된다. Tox21 데이터셋에는 12개의 작업과 1,024개의 피처가 있다. 이 경우네는 신경망에 너비가 1,000이고 하나의 숨겨진 레이어를 사용하는 모델이다.

(9) epoch : 데이터셋의 모든 샘플이 학습 알고리즘을 한 번 통과하는 것

DeepChem의 모든 모델 객체는 모델을 데이터셋에 맞춰주는 fit() 메서드가 있다. 위 코드로 MultitaskClassifier 모델 객체를 간단하게 데이터와 맞출 수 있다.

 

학습을 마친 모델은 평가하는 과정을 거친다. 모델의 성능을 평가하기에 앞서 가장 먼저 평가 지표(metric)를 정해야 한다. DeepChem의 클래스 dc.metrics.Metric은 일반적으로 사용되는 평가 지표들이 들어있다. Tox21 데이터셋의 경우 ROC AUC 점수를 사용해 모델의 성능을 평가한다. Tox21 데이터셋에는 총 12개의 분류 작업이 존재하는데, 이런 경우 모든 분류 작업의 평균 ROC AUC을 계산한다.

 

metric = dc.metrics.Metric(dc.metrics.roc_auc_score, np.mean)

 

모델 성능을 평가하는 model.evaluate() 함수를 사용한다.

(10)

학습 데이터셋에 대한 ROC AUC 값은 0.95로 테스트 데이터셋에 대한 값인 0.68보다 훨씬 높다. 이것은 딥러닝 모델이 과적합됐다는 뜻이다.

댓글