BioPlayground

🧬
목록으로

도킹 실무: AutoDock Vina · Glide · Rosetta의 스코어 함수 뜯어보기

확산모델 이전, 실무에서 지금도 널리 쓰이는 전통적 도킹 도구 AutoDock Vina·Glide·Rosetta의 경험적 스코어 함수 구성과 실습 절차를 다룹니다.

중급
|
20
|
검증 완료 (2026-07-29)
AutoDock Vinadockingscoring functionbinding pocket
진행률0/120 (0%)

F08 다음 질문 — 확산모델 없이도 도킹은 20년 넘게 돌아갔다

F08에서 DiffDock이 도킹을 확산모델로 다시 정의한 이야기를 했습니다. 그런데 오해하면 안 되는 게 하나 있습니다. DiffDock이 등장하기 훨씬 전부터, 그리고 지금 이 순간에도, 신약 개발 현장의 스크리닝 파이프라인 대부분은 여전히 AutoDock Vina, Glide, Rosetta 같은 전통적 도킹 도구로 돌아가고 있습니다. 이유는 단순합니다 — 빠르고, 검증됐고, 무엇을 계산하는지 뜯어볼 수 있기 때문입니다. 이 편에서는 F08에서 "생성 모델로 도킹을 다시 정의했다"고 넘어간 그 전통적 접근을 직접 열어봅니다.

원리 — 도킹은 결국 "점수 함수 + 탐색"이다

경험적 스코어 함수의 구성

도킹 소프트웨어는 (1) 여러 자세를 만들고 (2) 각 자세에 점수를 매깁니다. AutoDock Vina의 기본 스코어 함수는 물리량을 그대로 계산하는 힘장이라기보다, 원자쌍 거리 기반 특징과 회전 가능 결합 벌점을 회귀로 맞춘 경험적 함수입니다.

sVina=w1gauss1+w2gauss2+w3repulsion+w4hydrophobic+w5Hbond+w6Nrots_{\text{Vina}} = w_1\,\mathrm{gauss}_1 + w_2\,\mathrm{gauss}_2 + w_3\,\mathrm{repulsion} + w_4\,\mathrm{hydrophobic} + w_5\,\mathrm{Hbond} + w_6\,N_{\mathrm{rot}}

각 항이 뜻하는 바는 다음과 같습니다.

물리적 의미
gauss1,2\mathrm{gauss}_{1,2}서로 다른 거리·폭의 Gaussian 접촉 항
repulsion\mathrm{repulsion}원자가 겹칠 때의 steric 벌점
hydrophobic\mathrm{hydrophobic}소수성 원자쌍 접촉 항
Hbond\mathrm{Hbond}수소결합 가능한 원자쌍 항
NrotN_{\mathrm{rot}}회전 가능 결합 수에 따른 유연성 벌점

가중치는 실험 데이터에 맞춰 피팅됐습니다. 고전 AutoDock4의 electrostatics·desolvation 항과 Vina 기본 함수의 항 구성을 섞어 쓰면 안 됩니다. Glide와 Rosetta도 여러 항을 결합하지만 목적함수와 파라미터화가 달라 “Vina와 같은 식”이라고 등치할 수 없습니다.

탐색: 유전 알고리즘과 국소 최적화

F08의 손 계산에서 봤듯, 결합 자세 공간을 그리드로 다 훑는 건 조합적으로 폭증합니다. AutoDock Vina는 이 문제를 국소 탐색(local search)을 곁들인 확률적 전역 최적화로 풉니다. 대략적인 흐름은 다음과 같습니다.

  1. 무작위로 여러 초기 자세를 생성한다.
  2. 각 자세 주변에서 스코어 함수를 국소적으로 개선하는 방향으로 조금씩 움직인다(gradient 기반 국소 최적화, BFGS 계열).
  3. 여러 국소 최적해 중 스코어가 가장 좋은 것을 최종 결과로 채택한다.

이 과정은 전역 최적해를 수학적으로 보장하지 않습니다. 국소 최적화의 근본적 한계 — 시작점에 따라 다른 국소해로 수렴할 수 있다는 점 — 를 그대로 안고 있어서, 실무에서는 같은 리간드로 여러 번(exhaustiveness 파라미터를 높여) 반복 실행해 결과의 일관성을 확인하는 게 일반적입니다.

손 계산 예제: 반데르발스 항이 거리에 얼마나 민감한가

반데르발스 상호작용을 단순화한 Lennard-Jones 형태로 근사하면 다음과 같습니다.

EvdW(r)=4ϵ[(σr)12(σr)6]E_{\text{vdW}}(r) = 4\epsilon\left[\left(\frac{\sigma}{r}\right)^{12} - \left(\frac{\sigma}{r}\right)^{6}\right]

σ=3.5A˚\sigma = 3.5\,\text{Å}, ϵ=0.2kcal/mol\epsilon = 0.2\,\text{kcal/mol}로 놓고 r=3.5,3.0,2.5A˚r=3.5, 3.0, 2.5\,\text{Å}를 비교해봅시다. r=σr=\sigma는 퍼텐셜이 0인 거리이고, 최소점은 r=21/6σ3.93A˚r=2^{1/6}\sigma\approx3.93\,\text{Å}이며 그때 E=ϵE=-\epsilon입니다.

r=3.5:E=4(0.2)[(1)12(1)6]=0r=3.5: E = 4(0.2)\left[(1)^{12} - (1)^{6}\right] = 0

r=3.0:E=4(0.2)[(3.5/3.0)12(3.5/3.0)6]0.8(6.362.52)3.07r=3.0: E = 4(0.2)\left[(3.5/3.0)^{12} - (3.5/3.0)^{6}\right] \approx 0.8(6.36-2.52) \approx 3.07

r=2.5:E=4(0.2)[(3.5/2.5)12(3.5/2.5)6]0.8(56.697.53)39.33r=2.5: E = 4(0.2)\left[(3.5/2.5)^{12} - (3.5/2.5)^{6}\right] \approx 0.8(56.69-7.53) \approx 39.33

거리가 3.5A˚3.5\text{Å}에서 3.0A˚3.0\text{Å}으로 가까워지면 에너지는 약 3.07 kcal/mol로 올라가고, 다시 0.5Å 가까워지면 약 39.33 kcal/mol로 폭증합니다. 이는 steric clash의 물리적 직관을 위한 Lennard–Jones 예제이며, 위 Vina의 실제 repulsion 항을 그대로 수치 계산한 것은 아닙니다.

실습: AutoDock Vina로 소분자-단백질 도킹

bash
# Colab에서 실행. AutoDock Vina + OpenBabel 설치
!apt-get -qq install -y openbabel
!pip install -q vina meeko
# 1. 리간드 SMILES를 3D PDBQT로 변환 (Meeko 사용)
python3 << 'EOF'
from meeko import MoleculePreparation, PDBQTWriterLegacy
from rdkit import Chem
from rdkit.Chem import AllChem
# 아스피린 예시
mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O")
mol = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol, randomSeed=42)
AllChem.MMFFOptimizeMolecule(mol)
preparator = MoleculePreparation()
setups = preparator.prepare(mol)
pdbqt_string, is_ok, error_msg = PDBQTWriterLegacy.write_string(setups[0])
assert is_ok, error_msg
with open("ligand.pdbqt", "w") as f:
f.write(pdbqt_string)
EOF
# 2. 수용체(단백질)는 미리 준비된 PDBQT라 가정하고, 결합 부위 중심 좌표를 지정해 도킹 실행
python3 << 'EOF'
from vina import Vina
v = Vina(sf_name='vina')
v.set_receptor('receptor.pdbqt')
v.set_ligand_from_file('ligand.pdbqt')
# 결합 부위 중심(x, y, z)과 탐색 박스 크기(Å)
v.compute_vina_maps(center=[10.0, 5.0, 15.0], box_size=[20, 20, 20])
v.dock(exhaustiveness=8, n_poses=10)
v.write_poses('docked_poses.pdbqt', n_poses=5, overwrite=True)
energies = v.energies(n_poses=5)
for i, e in enumerate(energies):
print(f"자세 {i+1}: 결합 자유에너지 예측값 = {e[0]:.2f} kcal/mol")
EOF

exhaustiveness는 국소 탐색을 얼마나 여러 번 반복할지를 정하는 파라미터입니다. 값을 높이면 결과가 더 안정적이지만 계산 시간도 비례해 늘어납니다. 결합 부위 중심 좌표를 모른다면, 사전에 pocket detection 도구(fpocket 등)로 결합 부위 후보를 먼저 찾아야 합니다.

CS 매핑

  • 경험적 스코어링 함수(Empirical Scoring Function): 여러 해석 가능한 특징(feature)을 선형 가중합해 하나의 예측값을 만드는 구조는, 전통적인 선형회귀·특징 공학(feature engineering) 기반 머신러닝 모델과 동일한 설계 철학입니다.
  • 지역 탐색 최적화(Local Search): 여러 초기점에서 국소 최적화를 반복하고 최선의 결과를 채택하는 전략은, 조합 최적화에서 전역 최적해를 근사하는 multi-start local search / basin hopping과 같은 계열의 휴리스틱입니다.
  • 표현 vs 학습 스코어의 대비: F07에서 다룬 Boltz-2의 학습된 친화도 회귀 헤드와, 이 편의 손으로 설계된 물리적 가중합 스코어 함수는 "특징을 사람이 설계하는가, 데이터로부터 학습하는가"라는 고전적인 feature engineering vs representation learning 축의 좋은 대비 사례입니다.

자주 만나는 결함

  • 결합 부위 중심 좌표를 대충 추정: 결합 부위 중심이 부정확하면 탐색 박스가 실제 포켓을 벗어나 도킹 자체가 무의미해집니다. 알려진 결합 부위가 없다면 pocket detection 단계를 먼저 거쳐야 합니다.
  • exhaustiveness를 낮게 두고 결과를 신뢰: 계산 시간을 아끼려 exhaustiveness를 지나치게 낮추면 국소 최적화가 충분히 수렴하지 못해, 같은 리간드를 다시 돌렸을 때 완전히 다른 자세와 점수가 나올 수 있습니다.
  • 도킹 스코어를 실험 KdK_d와 직접 비교: 경험적 스코어 함수의 절대값은 서로 다른 화합물 계열 사이에서 실험값과 정량적으로 일치하지 않는 경우가 흔합니다. 같은 표적, 비슷한 화합물 계열 내 상대 순위 비교에 우선 쓰는 것이 안전합니다.

더 깊게 파고 싶다면

본문은 BPD 연구진이 직접 재구성한 서술입니다. 원 논문과 공식 자료로 심화해봅시다.

  • AutoDock Vina 원 논문: Trott & Olson (2010), AutoDock Vina: Improving the speed and accuracy of docking, J. Comput. Chem. 31(2).
  • AutoDock Vina 공식 문서: vina.scripps.edu — 스코어 함수 전체 항과 파라미터 설명.
  • Glide 방법론 논문: Friesner et al. (2004), Glide: A New Approach for Rapid, Accurate Docking and Scoring, J. Med. Chem. 47(7).

다음 편 F10에서는 도킹 이후의 질문 — 결합한 복합체가 시간에 따라 어떻게 움직이는지 — 를 분자동역학(GROMACS·OpenMM)으로 다룹니다.