FingerprintSimilarity
和 BulkTanimotoSimilarity
是 RDKit 库中用于计算化学分子相似度的两种方法,它们的主要区别在于输入格式和效率。
1. FingerprintSimilarity
- 作用: 计算两个化学指纹之间的相似性(Tanimoto 相似度)。
- 用法:
- 适合计算单对分子的相似度。
- 接受两个指纹对象作为输入。
- 返回一个介于 0 到 1 之间的浮点值,表示两个指纹的 Tanimoto 相似度。
from rdkit import Chem
from rdkit.Chem import AllChem, DataStructsmol1 = Chem.MolFromSmiles('CCO')
mol2 = Chem.MolFromSmiles('CCN')
fp1 = AllChem.GetMorganFingerprintAsBitVect(mol1, 2)
fp2 = AllChem.GetMorganFingerprintAsBitVect(mol2, 2)similarity = DataStructs.FingerprintSimilarity(fp1, fp2)
print("Tanimoto Similarity:", similarity)
2. BulkTanimotoSimilarity
- 作用: 计算一个指纹与一组指纹之间的相似性。
- 用法:
- 适合批量计算一个指纹与多个指纹之间的相似度。
- 接受一个指纹对象和一个指纹列表作为输入。
- 返回一个浮点列表,其中每个元素表示输入指纹与列表中相应指纹的 Tanimoto 相似度。
- 更高效,因为它在内部做了批处理优化。
from rdkit import Chem
from rdkit.Chem import AllChem, DataStructsmol1 = Chem.MolFromSmiles('CCO')
mol_list = [Chem.MolFromSmiles('CCN'), Chem.MolFromSmiles('CCC'), Chem.MolFromSmiles('CCCO')]
fp1 = AllChem.GetMorganFingerprintAsBitVect(mol1, 2)
fp_list = [AllChem.GetMorganFingerprintAsBitVect(mol, 2) for mol in mol_list]similarities = DataStructs.BulkTanimotoSimilarity(fp1, fp_list)
print("Bulk Tanimoto Similarities:", similarities)
3. 区别总结
特性 | FingerprintSimilarity | BulkTanimotoSimilarity |
---|---|---|
输入 | 两个指纹 | 一个指纹和一个指纹列表 |
输出 | 单个 Tanimoto 相似度值 | 相似度列表 |
适用场景 | 两两比较 | 批量比较 |
计算效率 | 逐对计算 | 内部优化,批量处理更快 |
4. 选择建议
- 单对分子比较: 使用
DataStructs.FingerprintSimilarity
。 - 批量比较: 使用
DataStructs.BulkTanimotoSimilarity
以提高效率。
5. 使用例子
import pandas as pd
import pandas as pd
from rdkit import Chem
from rdkit.Chem import MACCSkeys
from rdkit import DataStructs
import numpy as np
from rdkit.Chem import AllChem
from rdkit.Avalon import pyAvalonToolspairs_file = r'E:\ProteinDrugInter\SNAPData\data\our_data\drug_target_information.csv'
pairs_df = pd.read_csv(pairs_file)# Index(['DrugbankID', 'UniprotID', 'SMILES', 'Sequence', 'Label'], dtype='object')
# pairs_df.columns# 计算每个分子的 avalon 指纹
def calculate_maccs(smiles):mol = Chem.MolFromSmiles(smiles)return pyAvalonTools.GetAvalonFP(mol) if mol is not None else None# return AllChem.GetMorganFingerprintAsBitVect(mol, 2, 1024) if mol is not None else Nonefilter_df = pairs_df[['DrugbankID', 'SMILES']].drop_duplicates()
filter_df.reset_index(drop=True, inplace=True)# 计算并添加 avalon 指纹到 DataFrame
filter_df['Avalon'] = filter_df['SMILES'].apply(calculate_maccs)res = []
n = len(filter_df)
for i in range(n):for j in range(i + 1, n):if i != j:drug_i = filter_df['DrugbankID'][i]drug_j = filter_df['DrugbankID'][j]# print(drug_i, drug_j)if filter_df['Avalon'][i] is not None and filter_df['Avalon'][j] is not None:sim = DataStructs.FingerprintSimilarity(filter_df['Avalon'][i], filter_df['Avalon'][j])# print(sim)res.append([drug_i, drug_j, sim])result_df = pd.DataFrame(res, columns=['Drug1', 'Drug2', 'Similarity'])
output_file = r'E:\ProteinDrugInter\datasets\SNAP\drug_similarity_avalon.csv'
result_df.to_csv(output_file, index=False)print(f"相似性结果已保存到 {output_file}")
6. 绘制密度图
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as pltsimi_file = r'E:\ProteinDrugInter\datasets\SNAP\drug_similarity_avalon.csv'
simi_df = pd.read_csv(simi_file)
iden = simi_df['Similarity']# 绘制密度图
plt.figure(figsize=(7, 4))sns.kdeplot(iden, fill=True, color='#2894FF', linewidth=1,
linestyle='--', label = 'Sequence')
plt.axvline(x=0.5, color='r', linestyle='--', linewidth=1, label='x=0.5')
plt.title('Avalon Fingerprint', fontsize=15, weight='bold')
plt.xlabel('Similarity', fontsize=12, weight='bold')
plt.ylabel('Density', fontsize=12, weight='bold')
# plt.grid(True, which="major", linestyle="-", color="#D0CECE", linewidth=0.75)
# plt.grid(True, which="minor", linestyle="-", color="#D0CECE", linewidth=0.75)
plt.legend()plt.tight_layout()
plt.savefig(r'E:\ProteinDrugInter\datasets\SNAP\Figures\drug_similarity_avalon.png', dpi=600, transparent=True)
plt.savefig(r'E:\ProteinDrugInter\datasets\SNAP\Figures\drug_similarity_avalon.pdf')
plt.show()