所以我是化学信息学和编程领域的新手,我的第一个项目涉及使用摩根指纹作为我的 ML 模型的描述符/特征,但我似乎无法找到合适大小的位向量。我的分析涉及找出给定长度占用的最大位数。
首先我创建一个函数,它接受 SMILES 和位向量长度的列表,并生成所有 SMILES 的指纹,并返回所有生成的指纹中占用的最大位数。
def max_on_bits(smiles_list, nbits):
on_bits = []
for smiles in smiles_list:
mol = Chem.MolFromSmiles(smiles)
fp = AllChem.GetMorganFingerprintAsBitVect(mol,
3,
nBits=nbits,
useChirality=True,
useFeatures=True)
num_on_bits = sum(np.array(fp))
on_bits.append(num_on_bits)
return max(on_bits)
然后我递归地使用该函数来找到最大占用率
nbits_range = range(1024, 20483, 256)
occupancy = []
for nbits in nbits_range:
occupancy.append(max_on_bits(smiles_list, nbits))
最后我绘制结果
import matplotlib.pyplot as plt
plt.plot(nbits_range, occupancy)
plt.xlabel("Bit Vector Size")
plt.ylabel("Maximum Number of bits occupied")
plt.grid()
plt.show()
在生成摩根指纹的过程中,首先为所有非冗余环境生成整数标识符,然后将这些整数折叠(通常使用模运算)以填充指纹。如果两个整数折叠到相同的索引,则会发生位冲突,并且位计数将低于唯一环境计数。发生这种情况的可能性相当高,这反映在你的情节中。如果您想要计算唯一标识符的数量,您可以完全跳过折叠,直接使用环境标识符。 32 位整数发生冲突的可能性要低得多。一般来说,摩根指纹非常稀疏,因此根据您的目的,指纹不必那么长。通常,1024、2048 或 4096 在任务中的表现非常相似,例如从一组中检索高度相似的化合物。
最有可能的是,您的曲线实际上会收敛,但前提是指纹长度要高得多。 PS,如果您使用
fp.GetNumOnBits()
而不是 sum(np.array(fp))
,您的代码会运行得更快,因为大量时间浪费在不必要地将 rdkit fp 转换为 np 数组上。请参阅下面的示例,使用雷帕霉素的 SMILES: