新手向-药物研发中的常见数据处理方法与代码实践
©️ Copyright 2023 @ Authors
作者:
黄逍 📨
日期:2023-09-25
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
快速开始:点击上方的 开始连接 按钮,选择 基础 notebook镜像及任意CPU节点配置,稍等片刻即可运行。
引言
在药物研发领域,数据集的重要性不言而喻。但是,尽管市场上存在大量的数据集,其质量却参差不齐。高质量的数据是研究成功的关键,但很多时候研究者们会遇到各种数据问题,如缺失数据、噪声过多或结构混乱等。这就使得数据处理和清洗变得尤为关键。一个合理处理且信息丰富的数据集不仅可以提高研究的准确性,也能为后续的研究提供有力支持。
在本教程中,我们将学习如何从ChEMBL数据库下载和处理数据。读完教程后,你应该熟悉数据结构,简单的数据分析,并了解与分子数据集相关的挑战。一个干净且信息丰富的数据集可以用于许多化学信息学任务,如相似性搜索、聚类或机器学习。
本教程中涉及到的工作流程
加载数据
数据清洗 2.1 基本清洗
2.2 简单数据处理
2.3 高级清洗
2.4 可视化IC50值
2.5 IC50与Ki的相关性
2.6 清洗化学结构导出数据
1. 加载数据
在这个教程中,我们将关注环氧酶-2 (COX-2) 的配体,这是抗炎药的一个重要药物靶点。例如,像阿司匹林、扑热息痛和布洛芬这样的日常和广泛开处方的药物都针对环氧酶。
首先,我们导入可能有用的Python库。
从ChEMBL数据库下载数据有几种方法。详细教程请参考这里。一种可能性是直接使用HTML GET请求访问API。我们可以如下所述直接使用Python来完成这个操作。这使得ChEMBL可以直接集成到你的工作流中,并允许你自定义想要检索的数据内容。然而,对于像COX2这样研究得很透彻的目标来说,这样的请求相对较慢。因此,下面的代码仅供你参考。
在这个教程中,为了确保每个人都能访问相同的数据集,我们将使用我们提供的数据文件。
下载完文件后,你可以导入并将其转化为Pandas的DataFrame,这是一个用于数据操作和分析的便捷数据结构。
Pandas有内置的 functions 可以读取各种格式的文件。
注意,你可能需要仔细选择特殊字符,如"注释"、"引号"和"换行符",以确保SMILES字符串和数据库的其他部分没有歧义。
Unnamed: 0 | activity_comment | activity_id | activity_properties | assay_chembl_id | assay_description | assay_type | assay_variant_accession | assay_variant_mutation | bao_endpoint | ... | target_organism | target_pref_name | target_tax_id | text_value | toid | type | units | uo_units | upper_value | value | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | NaN | 34205 | [] | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | NaN | NaN | BAO_0000190 | ... | Homo sapiens | Cyclooxygenase-2 | 9606 | NaN | NaN | IC50 | uM | UO_0000065 | NaN | 0.06 |
1 | 1 | NaN | 34209 | [] | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | NaN | NaN | BAO_0000190 | ... | Homo sapiens | Cyclooxygenase-2 | 9606 | NaN | NaN | IC50 | uM | UO_0000065 | NaN | 3.23 |
2 | 2 | NaN | 35476 | [] | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | NaN | NaN | BAO_0000190 | ... | Homo sapiens | Cyclooxygenase-2 | 9606 | NaN | NaN | IC50 | uM | UO_0000065 | NaN | 0.08 |
3 | 3 | NaN | 36218 | [] | CHEMBL769655 | Tested in vitro for inhibition against Prostag... | B | NaN | NaN | BAO_0000190 | ... | Homo sapiens | Cyclooxygenase-2 | 9606 | NaN | NaN | IC50 | nM | UO_0000065 | NaN | 0.12 |
4 | 4 | NaN | 36708 | [] | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | NaN | NaN | BAO_0000190 | ... | Homo sapiens | Cyclooxygenase-2 | 9606 | NaN | NaN | IC50 | uM | UO_0000065 | NaN | 100.00 |
5 rows × 46 columns
2. 数据清洗
2.1 基础清洗
虽然我们已经有了一个包含多个记录的数据集,但它可能包含许多不必要的甚至是错误的信息。因此,在我们开始分析数据集并从中得出任何结论之前,我们首先需要对其进行"清洗"。
现在,让我们进行数据过滤,只考虑:
- 结合数据(试验类型
assay_type "B"
) - 精确测量(关系
relation "="
) - 标准的生物活性类型(standard_type为
"IC50"
,"Ki"
和"Inhibition"
)
对于每个记录,我们只保留感兴趣的特征。
There are 7530 entries.
activity_id | assay_chembl_id | assay_description | assay_type | canonical_smiles | molecule_chembl_id | standard_type | standard_units | standard_value | pchembl_value | target_chembl_id | target_organism | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 34205 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1ccc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccccc1 | CHEMBL297008 | IC50 | nM | 60.00 | 7.22 | CHEMBL230 | Homo sapiens |
1 | 34209 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1c(C=O)cc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccc(F)cc1 | CHEMBL289813 | IC50 | nM | 3230.00 | 5.49 | CHEMBL230 | Homo sapiens |
2 | 35476 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1c(COc2cccc(Cl)c2)cc(-c2ccc(S(C)(=O)=O)cc2)n... | CHEMBL43736 | IC50 | nM | 80.00 | 7.10 | CHEMBL230 | Homo sapiens |
3 | 36218 | CHEMBL769655 | Tested in vitro for inhibition against Prostag... | B | Fc1ccc(-c2[nH]c(-c3ccc(F)cc3)c3c2C2CCC3CC2)cc1 | CHEMBL140167 | IC50 | nM | 0.12 | 9.92 | CHEMBL230 | Homo sapiens |
5 | 39073 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | CC(=O)c1cc(-c2ccc(S(C)(=O)=O)cc2)n(-c2ccc(F)cc... | CHEMBL44290 | IC50 | nM | 1610.00 | 5.79 | CHEMBL230 | Homo sapiens |
为了了解生物活性类型的组成,我们可以生成柱状图来可视化每种生物活性类型(IC50,Ki,Inhibition)的条目数量。
你可以使用matplotlib.pyplot.bar函数。请正确标记你的坐标轴。
在教程的后续部分,我们将对数据进行一系列数学计算,因此检查并确保数据类型是兼容的非常重要,或者看是否需要将列转换为其他数据类型。
activity_id int64 assay_chembl_id object assay_description object assay_type object canonical_smiles object molecule_chembl_id object standard_type object standard_units object standard_value float64 pchembl_value float64 target_chembl_id object target_organism object dtype: object
2.2 简单数据处理 - 寻找最强效的COX2抑制剂
既然我们已经下载了COX-2的IC50数据并确保Python将其识别为数字,那么让我们尝试找出最已知的最强效的COX-2抑制剂是什么。按照升序对所有IC50值进行排序,并尝试找到最小的IC50值(即最强效的化合物)。
activity_id | assay_chembl_id | assay_description | assay_type | canonical_smiles | molecule_chembl_id | standard_type | standard_units | standard_value | pchembl_value | target_chembl_id | target_organism | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
8491 | 12072259 | CHEMBL2161532 | Inhibition of human recombinant COX2 expressed... | B | CC(Oc1cc(=O)oc2ccccc12)C(=O)N1CCCC1 | CHEMBL2158361 | IC50 | nM | 0.0 | NaN | CHEMBL230 | Homo sapiens |
4721 | 2233024 | CHEMBL969894 | Inhibition of human COX2 | B | O=C(O)CCCC[C@@H]1CCSS1 | CHEMBL134342 | IC50 | nM | 0.0 | NaN | CHEMBL230 | Homo sapiens |
4722 | 2233025 | CHEMBL969894 | Inhibition of human COX2 | B | O=c1c2ccccc2[se]n1-c1ccccc1 | CHEMBL51085 | IC50 | nM | 0.0 | NaN | CHEMBL230 | Homo sapiens |
4724 | 2233027 | CHEMBL969894 | Inhibition of human COX2 | B | Clc1ccc(-c2cn[se]c2-c2ccc(Cl)cc2)cc1 | CHEMBL501676 | IC50 | nM | 0.0 | NaN | CHEMBL230 | Homo sapiens |
4725 | 2233028 | CHEMBL969894 | Inhibition of human COX2 | B | Cc1ccc(-c2[se]ncc2-c2ccc(Cl)cc2)cc1 | CHEMBL471171 | IC50 | nM | 0.0 | NaN | CHEMBL230 | Homo sapiens |
可以思考的小问题
数据集中最小的IC50值是多少?
您的答案:0 nM
您如何解释IC50值?
您的答案:IC50值应该始终大于零。零值可能只是在手动记录时未被注意到的错误。此外,零IC50值也可能意味着该化合物对目标无活性,显示有限的抑制效果。
您现在认为知道最强效的COX2抑制剂是什么吗?
您的答案:不。尽管我们可以简单地丢弃所有IC50值为零的条目,但在确定最强效的抑制剂之前仍然存在一些其他问题。理想情况下,当将所有文献中报道的实验IC50数据输入数据库时,应将其转换为"标准值",其"标准单位"为纳摩尔(nM)。但是,如果在记录值时单位被正确转换,而值没有经过转换(例如,0.005 uM -> 0.005 nM,应该是5 nM),那么数据库中也会出现小于1的值。这些非零的错误值甚至更难以被识别和处理,而且它们与零值一起,当输入到机器学习模型时可能会导致非常偏见的和误导性的预测。
所以,不幸的是,即使有了像ChEMBL数据库和pandas这样强大的工具,由于数据中的错误,要回答什么是最强效的抑制剂这个问题可能并不简单。如果您有兴趣进一步研究这个问题,您需要手动检查这里的顶部注释的论文或依赖于另一个数据来源。但对于这个教程,我们将继续探讨其他问题。
2.3 高级清理
正如你可能已经意识到的,一个没有经过数据策划和清洗步骤的"原始"数据集对我们来说远远没有用处,因为存在各种问题。除了不准确和不相关的数据,其他的不一致性,如缺失数据或重复数据,也应该被正确地识别和处理。
为了分析的便利,我们将整个数据集根据生物活性类型分为三个单独的数据集。
重复条目中的不一致生物活性值可能来自不同的研究或重复输入,这在使用数据集训练机器学习模型时可能会引起严重问题。在我们处理重复数据之前,让我们看一下阿司匹林的测定条目的差异,它是最著名的COX-2抑制剂。
activity_id | assay_chembl_id | assay_description | assay_type | canonical_smiles | molecule_chembl_id | standard_type | standard_units | standard_value | pchembl_value | target_chembl_id | target_organism | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
9169 | 13830396 | CHEMBL3088737 | Inhibition of COX-2 (unknown origin) using ara... | B | CC(=O)Oc1ccccc1C(=O)O | CHEMBL25 | Ki | nM | 52000.0 | 4.28 | CHEMBL230 | Homo sapiens |
讨论
根据Cheng-Prusoff方程 ,Ki值永远不应超过IC50值。但是对于阿司匹林,几乎所有的IC50条目都比Ki值小。
所有独立的数据条目都似乎达成了共识,这在数据中是非常不可能的错误。Cheng-Prusoff方程错误吗?它当然是一个正确且科学的数学模型,但关键的前提是抑制剂必须以可逆的方式与目标蛋白竞争性地结合。研究表明,阿司匹林是一个不可逆的抑制剂,与其目标COX-2形成共价键。因此,该方程不能再准确描述阿司匹林的IC50和Ki值之间的数学关系。
好的,现在是时候去除所有重复项了。
IC50 数据集中有 1424 个重复项。 清洗后,IC50 数据集中还剩下 0 个重复项。 ---------- Ki 数据集中有 0 个重复项。 清洗后,Ki 数据集中还剩下 0 个重复项。
2.4 可视化 IC50 值
现在我们有了一个更加整洁的 IC50 数据集,让我们通过绘制直方图来查看 IC50 值的分布。
嗯,您可能会发现这个图不是很有用,因为值似乎分布得很稀疏,并且它们之间可能存在数个数量级的差异。解决此问题的一种方法是绘制对数(以10为底)值。
我们快完成了!让我们使用10uM(1uM = 1000nM)作为阈值,将所有条目分为“活性”和“非活性”COX-2抑制剂,并将这个结果作为一个新列名为“class_label”添加到IC50 dataframe中。
active 2849 inactive 557 Name: class_label, dtype: int64
activity_id | assay_chembl_id | assay_description | assay_type | canonical_smiles | molecule_chembl_id | standard_type | standard_units | standard_value | pchembl_value | target_chembl_id | target_organism | class_label | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 34205 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1ccc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccccc1 | CHEMBL297008 | IC50 | nM | 60.00 | 7.22 | CHEMBL230 | Homo sapiens | active |
1 | 34209 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1c(C=O)cc(-c2ccc(S(C)(=O)=O)cc2)n1-c1ccc(F)cc1 | CHEMBL289813 | IC50 | nM | 3230.00 | 5.49 | CHEMBL230 | Homo sapiens | active |
2 | 35476 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | Cc1c(COc2cccc(Cl)c2)cc(-c2ccc(S(C)(=O)=O)cc2)n... | CHEMBL43736 | IC50 | nM | 80.00 | 7.10 | CHEMBL230 | Homo sapiens | active |
3 | 36218 | CHEMBL769655 | Tested in vitro for inhibition against Prostag... | B | Fc1ccc(-c2[nH]c(-c3ccc(F)cc3)c3c2C2CCC3CC2)cc1 | CHEMBL140167 | IC50 | nM | 0.12 | 9.92 | CHEMBL230 | Homo sapiens | active |
4 | 39073 | CHEMBL762912 | In vitro inhibitory activity against human pro... | B | CC(=O)c1cc(-c2ccc(S(C)(=O)=O)cc2)n(-c2ccc(F)cc... | CHEMBL44290 | IC50 | nM | 1610.00 | 5.79 | CHEMBL230 | Homo sapiens | active |
2.5 IC50 vs. Ki 相关系数
根据我们的讨论,让我们找出那些同时具有IC50和Ki值的分子,并生成一个散点图来可视化IC50和Ki的关系。
注意:你可以在你的图中包括一个"helper curve y = x",这样所有的点都会分布到分界线的两边。
molecule_chembl_id | IC50 | Ki | |
---|---|---|---|
0 | CHEMBL6 | 49.0 | 1500.0 |
1 | CHEMBL25 | 62500.0 | 52000.0 |
2 | CHEMBL404108 | 7.0 | 320.0 |
3 | CHEMBL259218 | 47.0 | 1200.0 |
4 | CHEMBL559089 | 42500.0 | 65500.0 |
有7个分子遵循Cheng-Prusoff方程,其中IC50值不小于Ki值。
2.6 清洗化学结构
清洗结构是作为一个重要的预处理步骤。其中的一个步骤是去除如盐类的次要组分。通常,在一个SMILES表达式中,两个或多个组分被写为分开的SMILES表达式,并使用"."作为分隔符。因此,检测次要组分可以通过查找"."来执行,并且移除次要组分可以通过仅保留最大的SMILES表达式来完成。
例如:CN(C)C.Cl -> CN(C)C
这里有一个例子:CS(=O)(=O)c1ccc(-c2cc(N)sc2-c2ccc(F)cc2)cc1.Cl 有32个分子在它们的smiles中包含盐组分。
清洁后,仍有0个分子在其smiles中含有盐。
3. 输出数据集
好工作!最后一步:将处理过的 IC50 数据集导出为 .csv 文件。
与导入文件类似,pandas 中也有函数可以用来将你的结果导出到文件中。
yufeng