化合物数据集的降维可视化

对于分子聚类后的结果,或者是某个化合物数据集,有时希望可视化后有个直观的对比来确认不同来源的分子集合所占据的化学空间。 但对于化合物这种高维度数据,直接可视化是不行的,需要先降到2维或3维才能在平面或者立体空间内展示。降维方式多种多样,这里演示最常用的t-SNE和PCA的降到二维平面的做法。

注意一点是,t-SNE与PCA降维效果见仁见智,虽然通认t-SNE在降维中应用更广,但个人认为对于化合物而言没有明确的优劣之分,但一般来说t-SNE相比PCA降维的速度慢数倍,处理分子规模较大时,可以优先考虑PCA方式。

一、tSNE

t-Distributed Stochastic Neighbor Embedding (t-SNE),创建了一个缩小的特征空间,相似的样本由附近的点建模,不相似的样本由高概率的远点建模。在高水平上,t-SNE为高维样本构建了一个概率分布,相似的样本被选中的可能性很高,而不同的点被选中的可能性极小。然后,t-SNE为低维嵌入中的点定义了相似的分布。最后,t-SNE最小化了两个分布之间关于嵌入点位置的Kullback-Leibler(KL)散度。

我们先将化合物转成分子指纹后,再实现可视化

from rdkit import DataStructs
from rdkit.Chem import AllChem
import numpy as np

class FP:
    """
    建立一个FP的类方便后续的分子指纹处理
    """
    def __init__(self, fp, names):
        self.fp = fp
        self.names = names
    def __str__(self):
        return "%d bit FP" % len(self.fp)
    def __len__(self):
        return len(self.fp)

def get_cfps(mol, radius=2, nBits=1024, useFeatures=False, counts=False, dtype=np.float32):
    arr = np.zeros((1,), dtype)
    if counts is True:
        info = {}
        fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius, nBits=nBits, useFeatures=useFeatures, bitInfo=info)
        DataStructs.ConvertToNumpyArray(fp, arr)
        arr = np.array([len(info[x]) if x in info else 0 for x in range(nBits)], dtype)
    else:
        DataStructs.ConvertToNumpyArray(AllChem.GetMorganFingerprintAsBitVect(mol, radius, nBits=nBits, useFeatures=useFeatures), arr)
    return FP(arr, range(nBits))

def calFP(smi):
    try:
        mol = Chem.MolFromSmiles(smi)
        fp = get_cfps(mol)
        return fp
    except Exception as e:
        return None

以一个pandas 表格为例, 表格最初仅包含SMILES与所属的类别两列,

df['FP'] = df['canonSMILES'].apply(calFP)
df.head(3)
SMILES                                            cluster      FP   
Clc1ccc(-c2c[nH]c(-c3cccnc3)n2)cc1                    1     1024 bit FP     
C=CCOC(=O)C1=C(C)N=C(C)C(C(=O)OCC=C)C1c1cn(-c2...     1     1024 bit FP     
O=C(CCc1c[nH]c2ccccc12)NC(Cc1ccccc1)C(=O)O            2     1024 bit FP 

然后对FP这一列进行tSNE降维

from sklearn.manifold import TSNE
tsne_model = TSNE(n_components=2, random_state=42, perplexity=30, n_iter=5000)
# 将表格中的分子指纹转为numpy array的形式
X = np.array([x.fp for x in df['FP']])
tsne_result = tsne_model.fit_transform(X)
# 将降维结果加到表格中去
df['tSNE_1'] = tsne_result.T[0]
df['tSNE_2'] = tsne_result.T[1]
df.head(3)
SMILES                                            cluster      FP           tSNE_1         tSNE_2
Clc1ccc(-c2c[nH]c(-c3cccnc3)n2)cc1                    1     1024 bit FP     122.361221  -21.181770
C=CCOC(=O)C1=C(C)N=C(C)C(C(=O)OCC=C)C1c1cn(-c2...     1     1024 bit FP     -64.470451  -21.792231
O=C(CCc1c[nH]c2ccccc12)NC(Cc1ccccc1)C(=O)O            2     1024 bit FP      4.770935    64.870430

这时我们可以可视化刚刚降维的结果了。

import matplotlib.pyplot as plt
import seaborn as sns

sns.set()
sns.scatterplot(x='tSNE_1', y='tSNE_2', hue='cluster', s = 15,  data=df, alpha=0.2, edgecolors='none')
plt.show()
图一、t-SNE降维图示意(图片经过后处理、与代码绘图用参数细节略有出入)

二、PCA降维

PCA降维核心在于提取数据的主要特征分量,使得降维后的各主成分的方差值尽可能保持降维前的总方差。
类似的,我们仅需在计算出FP的表格中,应用PCA的方式,代替tSNE,即可实现降维与可视化

from sklearn.decomposition import PCA
pca_model = PCA(n_components=2, random_state=42)

X = np.array([x.fp for x in df['FP']])
pca_result = pca_model.fit_transform(X)
df['PCA_1'] = pca_result.T[0]
df['PCA_2'] = pca_result.T[1]
sns.set()
sns.scatterplot(x='PCA_1', y='PCA_2', hue='cluster', s = 15,  data=df, alpha=0.2, edgecolors='none')
plt.show()
图二、PCA降维图示意(图片经过后处理、与代码绘图用参数细节略有出入)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容