Datawhale AI夏令营-分子指纹-随机深林

109 阅读4分钟

自然语言处理领域自从ChatGPT于2022年11月的发布得到了极大的关注,因此2023年也被AI元年。自然语言是人类的母语,而分子,原子也可以说是自然的母语(尽管后续研究探究发现RNN以及transformer,用于处理自然语言,有序数据的较优的模型,在这个根据分子结构预测产率的问题上远不及rf,但GNN被在此类问题上优势很大)。人工智能可以解决两类问题,分类和回归问题,领悟机器学习的核心在于特征工程和方式模型。特征工程在化学领域主要依赖于rdkit库,这是一个开源的化学信息python库,简而言之,分子指纹就是将分子向量化如:

  1. 拓扑指纹 Chem.RDKFingerprint(mol)
  2. MACCS 指纹
  3. Atom Pairs
  4. topological torsions
  5. 摩根指纹(圆圈指纹)
  6. 摩根指纹拓展
  7. ESTATE指纹(rdkit version 2022.03+)
dc_smiles = data['Smiles']
rdkit_featurizer = dc.feat.RDKitDescriptors()
rdkit_feature = rdkit_featurizer.featurize(dc_smiles)
dc_feature = pd.DataFrame(rdkit_feature)
dc_feature.columns = [f'smiles_dc_{i}' for i in range(dc_feature.shape[1])]
zeros_count = dc_feature.eq(0).sum()
columns_to_drop = zeros_count[zeros_count >= 704].index.tolist()
smiles_feature = dc_feature.drop(columns=columns_to_drop)

最大的好处就是可以使用矩阵的方式包含了分子特征,特征得以提取,其次我们可以定量衡量分子相似性,这没有计算机思维之前是不可能的。化学从萌芽阶段到燃素化学,描述化学从自然语言到化学特有符号,用了3000年,而发展到如今的现代化学,化学的符号得以有简便的输入方法(SMILES),又花费了800年。除此以外,随着计算化学的发展,自然得以与计算机交互。值得注意的是InChi格式,是一种更好的标识远比SMILES所包含的信息更多,并且转换是开源的。以下都是可以使用rdkit对InChi格式所能获得的。

mol = Chem.MolFromInchi(inchi)
    
    # 氢键供体
    h_donors = Descriptors.NumHDonors(mol)
    
    # 氢键受体
    h_acceptors = Descriptors.NumHAcceptors(mol)
    
    # 旋转键个数
    rotatable_bonds = Descriptors.NumRotatableBonds(mol)
    
    # 芳香环数
    aromatic_ring_count = Descriptors.NumAromaticRings(mol)
    
    # 总极性表面积 (TPSA)
    tpsa = rdMolDescriptors.CalcTPSA(mol)
    
    # XLogP
    xlogp = Descriptors.MolLogP(mol)
    
    # 价电子数
    num_valence_electrons = Descriptors.NumValenceElectrons(mol)
    
    # 平均信息含量
    avg_ipc = GraphDescriptors.AvgIpc(mol)
    
    # Balaban's J
    balaban_j = GraphDescriptors.BalabanJ(mol)
    
    # BertzCT 复杂度
    bertz_ct = GraphDescriptors.BertzCT(mol)
    
    # 重原子分子量
    heavy_atom_mol_wt = Descriptors.HeavyAtomMolWt(mol)
    
    # 最大绝对部分电荷
    max_abs_partial_charge = Descriptors.MaxAbsPartialCharge(mol)
    
    # 最大部分电荷
    max_partial_charge = Descriptors.MaxPartialCharge(mol)
    
    # 最小绝对部分电荷
    min_abs_partial_charge = Descriptors.MinAbsPartialCharge(mol)
    
    # 最小部分电荷
    min_partial_charge = Descriptors.MinPartialCharge(mol)
    
    # 分子的Kappa1
    kappa1 = rdMolDescriptors.CalcKappa1(mol)
    
    # 分子的Kappa2
    kappa2 = rdMolDescriptors.CalcKappa2(mol)
    
    # 分子的Kappa3
    kappa3 = rdMolDescriptors.CalcKappa3(mol)
    
    # 分子的Labute ASA
    labute_asa = rdMolDescriptors.CalcLabuteASA(mol)
    
    # 分子的Morgan指纹
    morgan_fingerprint = rdMolDescriptors.GetMorganFingerprint(mol, 2)
    
    # 分子的自旋轨道耦合常数
    kappa = rdMolDescriptors.CalcPhi(mol)
    
    # 分子的饱和碳环数
    num_saturated_carbocycles = rdMolDescriptors.CalcNumSaturatedCarbocycles(mol)
    
    # 分子的饱和杂环数
    num_saturated_heterocycles = rdMolDescriptors.CalcNumSaturatedHeterocycles(mol)
    
    # 分子的饱和环数
    num_saturated_rings = rdMolDescriptors.CalcNumSaturatedRings(mol)
    
    # 分子的螺原子数
    num_spiro_atoms = rdMolDescriptors.CalcNumSpiroAtoms(mol)
    
    # 分子的氧化数
    rdMolDescriptors.CalcOxidationNumbers(mol)
    
    # 分子的CSP3分数
    fraction_csp3 = Lipinski.FractionCSP3(mol)
    
    # 分子的NHOH计数
    nhoh_count = Lipinski.NHOHCount(mol)
    
    # 分子的NO计数
    no_count = Lipinski.NOCount(mol)
    
    # 分子的异原子数
    num_heteroatoms = Lipinski.NumHeteroatoms(mol)
    
    # 分子的非芳香碳环数
    num_aliphatic_carbocycles = Lipinski.NumAliphaticCarbocycles(mol)
    
    # 分子的非芳香杂环数
    num_aliphatic_heterocycles = Lipinski.NumAliphaticHeterocycles(mol)
    
    # 分子的非芳香环数
    num_aliphatic_rings = Lipinski.NumAliphaticRings(mol)
    
    # 分子的芳烃碳环数追求追求追求
    num_aromatic_carbocycles = Lipinski.NumAromaticCarbocycles(mol)
    
    # 分子的芳烃杂环数
    num_aromatic_heterocycles = Lipinski.NumAromaticHeterocycles(mol)
    
    # 分子的摩尔折射率
    mol_refractivity = Descriptors.MolMR(mol)

可以看见InChi格式的优势很多,更适合rf学习,在仅以SMILES单一指纹向量化的rf模型中深度的影响大于决策树的数量,可见有必要引入更多的描述符,发挥集成学习的优势。 多指纹和InChI化是主要的策略。如下就是InChI化,再配合上述

from rdkit import Chem

# SMILES字符串
smiles = "CC(=O)OC1=CC=CC=C1C(=O)O"

# 将SMILES转化为分子对象
mol = Chem.MolFromSmiles(smiles)

# 将分子对象转化为InChI字符串
inchi = Chem.MolToInchi(mol)

print(inchi)

最初的计算化学主要依托于第一性原理,归根到底是根据近似方法计算单分子计算波函数,由此能得到分子的信息,已知的与未知的, 对于复杂的构效关系,多对象系统,复杂度增加,继续追求精准性是不理智的。这样的问题,往往能够根据经验判断得出部分,这正是人类的优势,而机器学习更是无限接近人脑在处理这样的问题上的潜能。 所谓的经验判断都可以拆分为一系列决定,尽管日常的决策都十分简单且只需若干判断即可,这分别决策树的分支和深度,除此以外,不同人的判断不同,考虑多个人一起判断就是集成学习,最普适的案例就是随机深林算法。

from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators=30,max_depth=40,min_samples_split=2,min_samples_leaf=1,n_jobs=-1)
model.fit(train_x,train_y)
predictions = model.predict(train_x)

在skleran库的辅助下搭建这样原理的随机森林也十分轻松。 --未完