Coding/EDA / 또 ChEMBL을 털어보았다.md

또 ChEMBL을 털어보았다

조회

오늘은 좀 다채롭습니다. 왜냐고? 뭐가 많이 들어서.


그 우리 이제 할만큼 하셨으니까... 전처리는 다 안올릴게여... 내가 귀찮아서 이러는거 맞음. 내가 네이버 티스토리 미디움에 동시에 올리는데 그러면 복붙을 몇 번 하는겁니까...


배경설명

이번에 가져온 데이터베이스의 주제가 Kinase Inhibitor입니다. 이게 뭔데요? 를 설명하려면 kinase와 inhibitor를 다 설명해야 하는데… 아…

 

Kinase는 뭐에 인산기를 붙이는 효소입니다. 인산기는 PO4(3-)고, 그걸 어디다가 붙이는 놈들이 다 카이네이스예요. 인산기를 어디다가 붙이는가는 효바효(효소 바이 효소)지만 어쨌든 인산기를 갖다 붙입니다. 보통 ATP에서 떼다가 붙이긴 합니다만.

 

자, 그럼 인히비터에 대한 얘기를 해봅시다. 우리 몸의 모든 것은 신호체계를 기반으로 돌아갑니다. 뭘 대사하는 과정, 숨쉬는것, 세포분열까지 하나한 신호체계가 관여하고 있고, 그 신호체계에 끼어드는 놈이 kinase다 이겁니다. 당연하게도 이 신호체계는 멈춰야 할 때 멈추고, 돌아야 할 때 도는 게 정상입니다. 적절하게 엑셀/브레이크가 제 역할을 해 줘야 한다 이거죠.

 

그런데 이 엑셀과 브레이크가 선천적으로 없거나(유전병이라던가...), 후천적으로 없어진다면(돌연변이 누적)? 네. 질병입니다. 암도 여러 돌연변이가 누적되어서 엑셀, 브레이크가 다 맛이 가면 생기게 되는겁니다. 그럼 인히비터는 여기서 뭘 하는데요? 엇나간 엑셀, 엇나간 브레이크가 신호체계 개발살내는 걸 방해하는겁니다.

 

kinase가 다양한 곳에서 다양한 역할을 하기 때문에, 그 kinase를 타겟으로 하는 약물들도 다양합니다.


전처리

임상단계 범주화

df['Status'] = df['Max Phase'].map({4: 'Approved', 3: 'Clinical', 2: 'Clinical', 1: 'Clinical', 0: 'Clinical', -1: 'Failed'})

전에 이부프로펜 보고 오신 분들은 뭔지 바로 아실듯... 예. 그겁니다. Max Phase가 4면 승인됨, 3~0까지는 임상(0은 엄밀히 말하자면 전임상), -1은 엎음. 참고로 저기서 0 한번도 못봤음...

 

Status
Clinical    1246
Approved     451
Failed       116
Name: count, dtype: int64

이부프로펜보다 쪽수가 훨배 많음둥..

 

분자 타입 카테고리화

얘가 이부프로펜보다 쪽수도 많고 카테고리도 많거든요? 함 보실?

Type
Small molecule             1727
Unknown                      50
Protein                      21
Oligosaccharide               6
Oligonucleotide               4
Antibody drug conjugate       3
Antibody                      2
Vaccine component             1
Gene                          1
Enzyme                        1
Name: count, dtype: int64

그래서 카테고리를 두 단계로 나눌건데

이렇게 나눌겁니다. ㅇㅋ? ㅇㅇㅋ

 

df['Category_1'] = df['Type'].apply(lambda x: "Small molecule" if x == "Small molecule" else "Other")

솔직히 둘로 나누는건 기명함수보다 람다식이 간편하쥬. 

 

# 그룹 정의
groups = {
    'Biologics': ['Protein', 'Antibody', 'Antibody drug conjugate', 'Enzyme', 'Vaccine component'],
    'Nucleic acids': ['Oligonucleotide', 'Gene'],
    'Sugars': ['Oligosaccharide'],
    'Small molecule': ['Small molecule'],
    'Unknown': ['Unknown']
}

# 근데 뒤집을거면 처음부터 반대로 만들면 안되는거임? 
# 안된답니다. 
mapping = {val: key for key, values in groups.items() for val in values}

# 예 적용됐습니다. 
df['Category_2'] = df['Type'].map(mapping)

딕셔너리 만들고 뒤집어서 적용할거면 그냥 리스트를 키에 올리면 안되나요? 안된단다. 딕셔너리 키에 튜플이라면 몰라도 리스트는 못간다.


임상 단계별 분자량 평균

df.groupby('Status')['Molecular Weight'].mean() # 평균
Status
Approved    503.598337
Clinical    487.756129
Failed      598.249815
Name: Molecular Weight, dtype: float64

평균은 이런데... 과연 분포는 어떨까?

 

# boxplot
sns.boxplot(df, x = 'Status', y = 'Molecular Weight', hue = 'Status')
plt.yscale('log')
plt.title('Molecular Weight by Status')
plt.show()

분자량 6000 넘는거 확인해봤더니(수상하게 멀리 튀어있음) 올리고뉴클레오타이드더라... 하나는 클리니컬, 하나는 페일드인데 일단 올리고뉴클레오타이드는 원래 뚠뚠합니다. 인별 릴스 보면 뭐 딸기에서 DNA 뽑기 이런거 하죠? 그게 일단 전체 조직에서 뽑는거기도 하고 DNA가 세포 안에 실패로 감고 감고 감아서 염색체로 짱박아야 할 정도로 뚠뚠함.

 

쟤는 VEGF라는 애가 타겟인데, 타겟인 애가 kinase가 아니고 kinase를 작동하기 위한 열쇠다. 그러니까 자동차로 비유하자면 자동차에 차 키를 못 꽂게 방해하는겁니다.

 

근데 왜 실패했냐고? DNA도 뱃속으로 들어가면 걍 영양원입니다 여러분. 그리고 쟤가 siRNA인데... 그 우리 RNA 뽑을 때 DEPC-증류수 쓰는게 RNase때문입니다. 실험에 써야되는데 걔가 다짤라... 걔를 무력화할 수단 중 하나가 DEPC라서 물에 그걸 타서 쓰는건데... 약 하나 투여하자고 그걸 같이 넣을 순 없잖습니까... GHS에 느낌표 떴다고... 이렇게 말하면 아니! RNA 백신은 그럼 허구냐! 하실 수 있는데, 제약사들도 똥멍청이가 아닙니다. 석박들이 모여서 머리를 맞대고 이거 분해 안되고 배달되게 할 방법 없을까? 해서 방법을 강구했죠. 리포좀이나 인지질같은 걸로 싸서 효소가 접근을 못 하게 하거나, 아예 퀵으로 목적지까지 쏴버리거나, backbone(그 사다리에 양 옆에 1자로 서있는거)을 바꾸거나.

 

바이오액티비티

df.groupby('Status')['Bioactivities'].mean() # 평균
Status
Approved    587.428977
Clinical    185.371498
Failed       33.195122
Name: Bioactivities, dtype: float64

롸?

 

# boxplot
sns.boxplot(df, x = 'Status', y = 'Bioactivities', hue = 'Status')
plt.yscale('log')
plt.title('Bioactivities by Status')
plt.show()

그… 실패한 애들은 어쩌다…

 

AlogP

df.groupby('Status')['AlogP'].mean() # 평균
Status
Approved    3.149507
Clinical    3.531329
Failed      3.429429
Name: AlogP, dtype: float64

평균은 무난하다. 근데 분포도 그럴까?

 

# boxplot
sns.boxplot(df, x = 'Status', y = 'AlogP', hue = 'Status')
plt.title('AlogP by Status')
plt.show()

이렇게 봐서는 그놈이 그놈같으니까 ANOVA 함 해보자.

 

ANOVA

# 표본 수 확인용
# 결측값 안지우면 통계량 안나와요... 
df_approved = df.query('Status == "Approved"')['Bioactivities'].dropna()
df_clinical = df.query('Status == "Clinical"')['Bioactivities'].dropna()
df_failed = df.query('Status == "Failed"')['Bioactivities'].dropna()
f_stats, p_val = stats.f_oneway(df_approved, df_clinical, df_failed)
print(f'F-Statistics: {f_stats:.2f}')

if p_val < 0.05:
    print(f"p-value: {p_val:.2e}: 귀무가설 기각! Tukey 드가자!") # 아 Tucky가 아니구나... 튜키씨 미안... 
else:
    print(f"p-value: {p_val:.2e}: 귀무가설 기각 실패")

근데 왜 피밸류는 f 아니고 e예요? 피밸류가 급나 완전 작게 나올 때(-111e 이런거) f때리면 0으로 나옵니다... 아무 튼 그래서 어떻게 됐냐고?

 

F-Statistics: 52.70
p-value: 1.13e-22: 귀무가설 기각! Tukey 드가자!

뭘 어떻게돼요 튜키 해야돼 우리...

 

all_vals = list(df_approved) + list(df_clinical) + list(df_failed)
all_labels = (['Approved'] * len(df_approved) + ['Clinical'] * len(df_clinical) + ['Failed'] * len(df_failed))

tukey = pairwise_tukeyhsd(endog=all_vals, groups=all_labels, alpha=0.05)
print(tukey)
     Multiple Comparison of Means - Tukey HSD, FWER=0.05     
=============================================================
 group1   group2   meandiff p-adj    lower     upper   reject
-------------------------------------------------------------
Approved Clinical -402.0575    0.0 -497.2978 -306.8172   True
Approved   Failed -554.2339    0.0 -800.9217  -307.546   True
Clinical   Failed -152.1764 0.2947 -391.4005   87.0477  False
-------------------------------------------------------------

누누이 말하는거지만 어노바(분산분석)는 얘네들 중 뭔가 다른데? 만 알려주는거고 튜키까지 해야 뭐가 구체적으로 다른지를 알려줍니다. 여기서는 승인됨 그룹이 다른 두 그룹과 다르다는 걸 튜키가 알려준거임.

 

AlogP의 경우 임상 단계와 상관 없이 6을 넘는 애들이랑 0보다 작은 애들이 있었는데, 일단 6보다 큰 애들은 그만큼 기름지시다는 의미고 0보다 작은 애들은 이건 뭐 물이야 뭐야라고 보시면 된다. 리핀스키 룰에서는 0~5까지로 지정하는데 왜 그러냐면 세포막은 인지질이지만 우리 몸은 물이거든...

 

AlogP가 규격 외인 약물들이  승인 단계에서 가장 많이 보이는 게 의외였음. 일단 임상중에서도 혼자 3상인 SONROTOCLAX 혼자 3상이다. 엥? 뭐지? 너무 기름지면 안된다면서요? 근데 쟤는 타겟이 기름바다에 위치해 있어서 기름져? 오히려 좋아! 인겁니다. AlogP가 낮은 애들 중에는 염기 짝퉁(이미테이션), 항생제(주사로 놓기때문에 기름질 필요가 없음), 올리고당이 보인다. 그러니까 누누이 말하는거지만 RO5를 지키면 좋다는거지 꼭 어길 필요가 없어요… 그 특성과 타겟에 따라서는 오히려 좋아! 인 경우도 있거든. 승인된 약물 중 EPTIFIBATIDE는 뱀독 유래 펩타이드다.

 

부작용 플래그

df.query('`Withdrawn Flag` != False')[['Name','Status','Type', 'AlogP','Type','Withdrawn Flag']]
	Name	Status	Type	AlogP	Type	Withdrawn Flag
445	LUMIRACOXIB	Approved	Small molecule	4.16	Small molecule	True
473	TOLRESTAT	Approved	Small molecule	3.56	Small molecule	True
504	CERIVASTATIN	Approved	Small molecule	4.88	Small molecule	True
564	XIMELAGATRAN	Approved	Small molecule	1.10	Small molecule	True
849	VALDECOXIB	Approved	Small molecule	2.96	Small molecule	True
954	UMBRALISIB	Approved	Small molecule	6.66	Small molecule	True
1160	CERIVASTATIN SODIUM	Approved	Small molecule	4.88	Small molecule	True
1389	NOMIFENSINE MALEATE	Approved	Small molecule	2.85	Small molecule	True
1427	NOMIFENSINE	Approved	Small molecule	2.85	Small molecule	True
1548	TOLCAPONE	Approved	Small molecule	2.55	Small molecule	True
1578	APROTININ	Approved	Unknown	NaN	Unknown	True

그… 전에도 얘기했지만 모든 약에는 부작용이 있어요. 근데 여기 플래그가 선 건 뭐다? 부작용이 진지하게 이거 투약하면 X될 것 같다… 수준이라는 얘깁니다.

 

1. CERIVASTATIN: 횡문근융해증(그 운동 무리하면 콜라색 소변 보잖아요? 그겁니다)
2. LUMIRACOXIB: 간독성
3. VALDECOXIB: 심혈관 질환(심장마비, 뇌졸중)의 위험성 증가 및 심각한 피부 반응 위험
4. XIMELAGATRAN: 와파린(항응고제)의 대체제였는데 아... 간독성 아...
5. TOLRESTAT: 간독성
6. UMBRALISIB: 어... 그... 항암제인데요... 다른 의미로 효과가 있었습니다... 
7. NOMIFENSINE MALEATE: 항우울제인데... 아...
    - 급성 용혈성 빈혈: 내 몸의 면역계가 갑자기 내 적혈구를 적으로 오해해서 다 터뜨려버립니다. (피가 모자라!)
    - 노미펜신 열(Fever): 약만 먹으면 고열이 펄펄 끓습니다.
    - 심각한 간 독성: 간 수치가 수직 상승합니다.
    - 조증/환각: 정신과 약(항우울제)인데, 우울증 고치려다 사람이 너무 들떠서 조증이 오거나 환각을 봅니다.
8. TOLCAPONE: 간독성
9. APROTININ: 피를 너무 잘 멈춰서... 아...

 

RO5 violation

df.query('Category_1 == "Small molecule"').groupby(['Status', '#RO5 Violations']).size().unstack()

그 원래 뚠뚠한 애들이 있지 않나요? 그래서 아예 분자만 필터링해서 본겁니다.

 

#RO5 Violations	0.0	1.0	2.0	3.0
Status				
Approved	278	87	56	3
Clinical	695	291	148	20
Failed	71	22	7	4

삼진아웃(3.0)은 대부분 분자량, HBA, HBD, AlogP 중 세 개가 위반인 케이스다. 저기 있는 숫자가 뭔 의미냐면 룰 중에서 몇 개를 위반했느냐임.

 

언노운, 그리고 Gene

언노운

말 그대로 이걸 뭘로 분류할 지 대단히 애매한 놈들이다. 보면 면역글로불린도 있고 뭐 어쩌고팁 어쩌고닙 많아요... 그리고 보면 아 언노운일 만 했다 싶음...

 

Gene

	Name	Synonyms	Status
716	IGRELIMOGENE LITADENOREPVEC	IGRELIMOGEN LITADENOREPVEC|IGRELIMOGENE LITADE...	Clinical

뭔 유전자 치료 해요? 웬 유전자? 나도 그렇게 생각했는데, 쟤는 바이러스다.

 

아니 그런걸 써요? 라고 생각하실 수도 있는데, 쟤는 유전자 개조한 녀석이라 병을 일으키는 대신 암세포를 찾아가서 핑을 찍는다.

'Coding > EDA' 카테고리의 다른 글

Ramen ratings  (0) 2026.02.11
Post-COVID Video Games Worldwide (2021-2025)  (0) 2026.02.10
캐글 EDA-마! 서퍼티파이! (2)  (0) 2026.01.20
캐글 EDA-마! 서퍼티파이!  (0) 2026.01.19
그냥 해보는 ChEMBL EDA  (0) 2026.01.15

댓글

홈으로 돌아가기

검색 결과

"search" 검색 결과입니다.