2. 分子构象与RMSD基础
做K-means构象聚类之前,有两样东西必须搞懂:构象和RMSD。我当年第一次跑聚类,愣是把两个能量最低的构象归到不同类里,后来才发现是RMSD算错了——那滋味真不好受。这节课咱们就把地基打牢。
2.1 分子构象:你到底在聚什么?
构象(conformation),说白了就是分子在三维空间里的一种瞬时形状。同一个分子,单键旋转一圈,就能变出成千上万种样子。这些样子能量高低不同,有稳定也有不稳定的。
举个例子,丁烷绕着中间C–C键转一圈,你就得到反式、邻位交叉、全重叠等构象。反式能量最低,全重叠最高。你想想看,如果我们要对一大组构象做聚类,总不能靠肉眼盯着几千个结构看吧?所以需要一种数值指标来量化两个构象的差异。
2.2 RMSD:度量构象差异的“尺子”
RMSD(均方根偏差)是计算生物里最常用的结构相似度指标。它的公式长这样:
RMSD(a,b) = sqrt( (1/N) * Σ || p_i - q_i ||² )
其中 p_i 和 q_i 是两分子对应原子(通常是骨架原子)的三维坐标。算出来的数值越小,说明两个构象长得越像。
我这里有个真实教训:千万别忘了对齐。两个构象如果没做最优叠合就直接算RMSD,结果会大得离谱。所以我一般先用Kabsch算法做旋转对齐,再算RMSD。
给你一个Python片段:
import numpy as np
def kabsch_rmsd(coords_p, coords_q):
# 平移至质心
p_cent = coords_p - np.mean(coords_p, axis=0)
q_cent = coords_q - np.mean(coords_q, axis=0)
# SVD 求旋转矩阵
H = p_cent.T @ q_cent
U, _, Vt = np.linalg.svd(H)
R = Vt.T @ U.T
# 对齐
q_aligned = q_cent @ R.T
diff = p_cent - q_aligned
return np.sqrt(np.mean(np.sum(diff**2, axis=1)))
2.3 RMSD矩阵:聚类的“食材”
K-means聚类直接处理的是距离矩阵。对于N个构象,你算出一个N×N的RMSD矩阵,每个元素d_ij代表第i和第j个构象的RMSD。然后把这个矩阵喂给K-means算法(通常先把矩阵转为向量)。
表格对比一下常见的RMSD计算策略:
| 策略 | 适用场景 | 注意 |
|---|---|---|
| 骨架重原子RMSD | 蛋白质、核酸主链构象聚类 | 忽略侧链柔性 |
| 全部重原子RMSD | 小分子构象聚类 | 侧链多时易引入噪声 |
| 自定义核心区域RMSD | 活性位点、结合口袋附近 | 需先定义核心原子索引 |
2.4 分子构象与RMSD核心关系图
下面这张SVG把本章的知识点串起来了:从构象生成到RMSD矩阵,再到聚类入口。
2.5 关于归一化和距离的取舍
你可能要问:RMSD已经是数值了,为什么还要归一化?
嗯,这里有个微妙之处。K-means默认用欧氏距离找中心。如果你的数据是RMSD矩阵的行,那每个构象的“特征”其实就是它与其他构象的距离。这些距离的量纲是Å,通常介于0.5–5 Å之间。直接喂给K-means问题不大,因为量纲本身就是一致的。
但有一种情况需要归一化:当你同时用了RMSD和另一个指标(比如扭转角能量)做联合聚类时,两个指标的量级可能差几个数量级。这时候必须做min-max或z-score归一化。我建议用z-score,因为它对离群点鲁棒。
2.6 小分子 vs 生物大分子:RMSD的差异
处理小分子构象时,由于原子数少,可以直接用全部重原子RMSD。但遇到蛋白质、RNA这类大家伙,你得小心——
- 蛋白质:通常用Cα原子的RMSD就够了,轻量又稳定。我做酶构象聚类时,全原子RMSD能到3 Å,但Cα RMSD只有1.2 Å,后者更能反映主链形态变化。
- 核酸:建议用磷酸二酯骨架的RMSD,因为碱基易堆积,RMSD波动大。
- 配体-受体复合物:如果你关心配体的结合模式,那要算配体重原子RMSD,受体部分一般不动。
2.7 本章小结
到这里你应该清楚了:构象是待聚类的对象,RMSD是对象之间的距离量尺,而RMSD矩阵就是K-means的原材料。下一章我们就要开始写真正的K-means代码了——但别急,先把这些基础消化掉。
最后送你一段话:别嫌RMSD基础枯燥,我见过太多人把项目做砸后才发现是RMSD没算对。这东西就像炒菜的油——油选错了,菜再新鲜也白搭。