Baseline code 를 봐도 코드 뜻을 모르는 경우
데이콘에서 기본적으로 모든 신약개발경진대회 참가자들에게 Baseline code 를 준다. 하지만 이는 도메인 지식이 없는 사람이 봤을 때에는 이게 대체 무슨 코드인지 모를 수 있는 부분이 있다. 나 역시 해당 도메인에 종사하지는 않고 단지 학부때 전공이 관련이 있고 며칠 전 LAIDD 에서 진행 하는 신약개발 부트캠프 3일간 풀데이로 참여했을 뿐이다. (참고로 다녀오고 나서 몸살 걸렸다..) 그나마 그 부트캠프를 통해 도메인 지식을 알게 되었고 어떤 코드가 어떤 도메인 지식에 해당하는지에 대해 알게 되었는데 다른 참가자들은 충분히 모를 수 있다. 따라서 그분들 입장이라면 어떻게 했을까 궁금해서 혹시 Claude 로 경진대회에 대해 설명하고 Baseline code 를 설명해 달라고 하면 제대로 해주려나 싶어서 실험삼아 해봤다.
Prompt 작성하기
Claude 에서 새 프로젝트를 생성하여 Project 에 대한 description 을 적었다.
Prompt 는 아래와 같이 영어로 적었다.
Below is the sample code gained as a baseline knowledge from the competetion event provider. Provide me with line-by-line interpretation.
라는 질문과 함께 그 밑에 baseline code 를 전부 복사 붙여넣기 해서 붙여넣었더니 claude 가 나름 line-by-line 으로 code 해설 해줬다.
def smiles_to_fingerprint(smiles):
mol = Chem.MolFromSmiles(smiles)
if mol is not None:
fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2, nBits=CFG['NBITS'])
return np.array(fp)
else:
return np.zeros((CFG['NBITS'],))
이 프롬프트에서 나온 Claude 의 설명은 너무 일반적이어서 크게 도움은 안되어서 그냥 신약개발 부트캠프 때 들었던 강의 자료를 참고하며 다음과 같이 이해했다.
이 smiles_to_fingerprint 라는 이름의 사용자 지정 함수는 smiles 형식의 화합물 데이터를 fingerprint 로 바꿔주는 역할을 하고 만약 없으면 0 값이 들어있는 vector 를 return 하도록 되어 있다.
신약개발 도메인지식: SMILES? 웃으라는 뜻인가?
Smiles 형식이란 무엇이고 왜 이것을 fingerprint 로 바꿔주어야 하냐 하는 질문이 들 수 있다. 이에 대해서는 LAIDD 에서 주최하는 신약개발 부트캠프에서 먼저 들은 바가 있는데, SMILES 는 Simplified Molecular Input Line Entry System 의 약자로, 약물 후보가 되는 화합물 분자의 복잡한 구조를 원자를 표현하는 알파벳과 그것들이 연결된 형태를 기호를 이용하여 텍스트로 표현을 한 것이다. 하지만 SMILES 표기법에는 한계가 있다.
1) 한 분자 화합물을 대표하는 SMILELS 표기법이 표준화 되어 있지 않는 경우가 있다. 따라서, 한 분자를 표현하는 SMILES표기가 여러개이다.
2) 2D, 3D 좌표가 없어서 MOL, SDF 등의 부가적인 데이터가 필요하다.
이러한 이유등으로 인해 SMILES 표기는 너무 단순화 된 표기법이라, 이것만으로는 분자 화합물의 구조를 Computer 가 알기 어려워 molecular descriptor 로 표기하여 숫자들로 한 분자의 특성을 표현해야 분석이 가능하다.
Molecular descriptor란, 분자 구조 및 특성을 숫자들의 집합으로 나타낸 것으로 화학적 특성, 생화학적 activity, 물리적 특징을 예측하기 위해 사용된다. 이 중에는 그 유명한 ECFP 도 포함되어 있다. Extended Connectivity FingerPrint의 약자로, 사람이 마치 개인의 지문이 본인임을 특정하는 것 처럼, 특정 분자 화합물이 나는 이런 특성을 갖고 있고 이게 유일하게 분자 화합물을 대표하는 1:1 매칭이 되도록 한 것이다. ECFP 로 나타내는 2가지 parameter로는 radius (diameter 가 아닌 radius 를 사용한다!), nBits 가 있다.
이 코드에서는 제공된 train data 를 읽어다가 SMILES 로 표기된 기존의 data 를 위에서 정의 된 함수를 apply 하여 fingerprint 형태로 변환된 데이터가 들어간 column 을 추가한다.
train = chembl_data[['Smiles', 'pIC50']]
train['Fingerprint'] = train['Smiles'].apply(smiles_to_fingerprint)
Train_x, train_y 도 이렇게 정의한 후
train_x, val_x, train_y, val_y = train_test_split(train_x, train_y, test_size=0.3, random_state=42)
이렇게 train_test_split 함수를 사용하여 random 하게 train data 으로부터 validation set 을 split 한다.
model = RandomForestRegressor(random_state=CFG['SEED'])
model.fit(train_x, train_y)
def pIC50_to_IC50(pic50_values):
"""Convert pIC50 values to IC50 (nM)."""
return 10 ** (9 - pic50_values)
val_y_pred = model.predict(val_x)
mse = mean_squared_error(pIC50_to_IC50(val_y), pIC50_to_IC50(val_y_pred))
rmse = np.sqrt(mse)
print(f'RMSE: {rmse}')
여기가 제일 우리가 optimize 해야 할 부분이다. 여기서는 엄청 나이브하게 random forest regressor 를 사용하여 그 어떠한 hyperparameter tuning 도 없이, Automl 도 사용하지 않고 그냥 1번만 모델 피팅을 ‘하긴 한’ 수준으로만 진행 했다. 이 코드는 어디까지나 예시이고 참가자인 우리는 이 부분을 중점적으로 파고들어서 XGBoost 가 좋을지 아니면 딥러닝으로 할 지, 딥러닝으로 하면 layer는 몇 개 쌓아야 하고 layer 마다 어떤 특징을 갖게 할 것인지 고민고민하고 여러가지의 조합을 테스트 해봐야 한다.
참고로 저 코드에는 ‘pIC50_to_IC50’ 이라는 함수가 쓰였는데 우리에게 주어진 data는 IC50_nM, pIC50 둘 다 있는데 이걸 왜 바꿔줘야 하고 수식은 왜 저렇게 되어있는지는 좀 더 공부해야 알겠다. (Claude 에 이런 걸 상세 질문하면 더 자세히 답해준다.)
test = pd.read_csv('./test.csv')
test['Fingerprint'] = test['Smiles'].apply(smiles_to_fingerprint)
test_x = np.stack(test['Fingerprint'].values)
test_y_pred = model.predict(test_x)
Model 을 만들었으면 이것으로 test data 를 이용하여 IC50 값을 예측한다. 이 때 test data 에서도 앞서 만든 smiles_to_fingerprint 함수를 이용하여 smiles 를 fingerprint 로 바꾼 후 이를 입력으로 받아 model.predict 로 예측대상을 예측한다.
Claude 에서 Baseline code 복사 붙여넣기 한 것을 line-by-line 으로 설명해 달라고 한 것은 딱 1번 질문한 것으로, 깊이없는 일반적인 대답이 나와서 크게 도움은 안되었지만, 여기서 특정 코드를 다시 복사 붙여넣기 하여 이 코드에 대해 더 자세히 물어보면 그에 대한 설명을 해줄 것이다.
예를 들어, 아래와 같은 프롬프트를 추가로 작성했더니 claude가 굉장히 상세하게 답변을 해줬다.
프롬프트에서는 왜 smiles 를 fingerprint 로 전환해야 하는지, 그리고 애초에 smiles 는 뭐고 fingerprint는 뭐냐고 물어봤다.
아래는 이에 대한 claude 의 답이다. 내가 원하는 정보를 이제 보다 상세한 레벨로 설명하고 있다. 이렇게 질문을 한 번 하고 너무 일반적인 답변이다 싶으면 거기서 더 파고드는 질문을 하면 이렇게 아래처럼 상세한 답변을 받아볼 수 있다. 그리고 꽤 내가 알고 있는 것과 일치해서 어느정도 도움이 되겠다 싶었다. 여기서 조금이라도 미심쩍으면 정말로 그런 개념이 있는지 구글링 하면 다 나오게 되어 있다. Claude 같은 생성형 AI가 주는 정보는 참고만 하고 다 믿으면 안된다. 이걸 기초로 해서 현실에서 이런 개념이 있는지 확인하면서 자신의 지식 범위를 확장하는 용도로 쓰면 좋을것 같다.
'데이터 사이언스' 카테고리의 다른 글
생성형AI 로 hyperparameter optimization code 만들어 공부하기 (6) | 2024.10.13 |
---|---|
Claude 를 참고하여 나만의 custom dataset 만들기 (6) | 2024.09.18 |
AI를 이용한 신약개발 경진대회: IRAK4 IC50 활성값을 예측 (8) | 2024.09.16 |
딥러닝으로 하는 신약개발 (2) | 2024.09.14 |
LAIDD 인공지능 & 파이썬 프로그래밍 역량강화 교육과정과 함께하는 신약개발 (0) | 2024.08.25 |