蛋白质序列的embedding嵌入

2023-11-06 16:28:32 浏览数 (2)

最近在看ESMfold和embedding的知识,然后就来简单写一个简单易懂的蛋白质embedding的demo

这是esm的官网截图,很震撼,meta团队预测了772 million个蛋白质序列,然后将这些蛋白再组合成一个atom map就是上图的样子。

然后我们开始我们今天的代码部分,首先embedding的作用大家应该知道,但是以防读者不清楚,我们今天再来介绍一下:

代码语言:javascript复制
`embedding`是深度学习中常用的一种技术,它用于将离散的符号(如单词、字符、类别等)映射到一个低维的连续向量空间中。嵌入向量(Embedding Vector)是这个映射的结果,也称为嵌入表示(Embedding Representation)或嵌入表征。

嵌入的作用主要有以下几个方面:

1. **降低维度和稀疏性:** 在自然语言处理(NLP)中,文本数据通常是高维且稀疏的,每个单词或字符都对应于一个独立的维度。通过使用嵌入技术,可以将高维的离散输入转换为低维的连续向量表示,从而降低了数据的维度,并且减少了数据中的稀疏性。

2. **提取语义信息:** 嵌入向量可以捕捉到输入符号之间的语义关系。相似的符号在嵌入空间中通常具有较近的距离,而语义上不相关的符号则具有较远的距离。通过学习这样的嵌入表示,模型可以更好地理解和表示输入符号之间的语义关联。

3. **通用特征表示:** 嵌入向量的学习是无监督的过程,因此可以在大规模的语料库上进行预训练。这些预训练的嵌入向量可以被用作下游任务的通用特征表示,从而提供了更好的初始特征表示,减少了对大量标注数据的依赖。

4. **改善模型性能:** 嵌入向量的使用通常可以提升深度学习模型在各种任务上的性能。在自然语言处理中,常见的应用包括文本分类、命名实体识别、机器翻译等任务。通过将离散的符号映射为连续的嵌入向量,模型可以更好地捕捉输入数据的结构和语义信息,从而提升模型的表达能力和泛化能力。

总而言之,嵌入技术通过将离散的符号映射到低维的连续向量空间中,克服了高维和稀疏数据的问题,并提供了更好的特征表示和语义信息,从而改善了深度学习模型在各种任务上的性能。

其实embedding就是将独热编码那种稀疏和高纬度的缺点给改良了一些

接下来我们对代码部分进行说明,首先是对蛋白质进行编码:

代码语言:javascript复制
# 定义氨基酸编码映射
amino_acid_map = {
    'A': 0, 'R': 1, 'N': 2, 'D': 3, 'C': 4, 'Q': 5, 'E': 6, 'G': 7, 'H': 8, 'I': 9,
    'L': 10, 'K': 11, 'M': 12, 'F': 13, 'P': 14, 'S': 15, 'T': 16, 'W': 17, 'Y': 18, 'V': 19
}

20个氨基酸的编码映射

然后进行独热编码:

代码语言:javascript复制
def amino_acid_to_one_hot(amino_acid):
    # 创建20维独热编码向量
    one_hot_encoded = np.zeros(len(amino_acid_map))
    # 将对应氨基酸位置设置为1
    one_hot_encoded[amino_acid_map[amino_acid]] = 1
    return one_hot_encoded

这样可以把一个向量转化成一个20维的向量

现在氨基酸已经编码成功了,我们只需要把我们输入的蛋白质序列转化成高维序列

代码语言:javascript复制
def protein_to_high_dimensional(protein_sequence):
    one_hot_encoded = [amino_acid_to_one_hot(amino_acid) for amino_acid in protein_sequence]
    high_dimensional_vector = torch.LongTensor(np.array(one_hot_encoded))
    return high_dimensional_vector

这一步利用编码好的氨基酸编码,然后对序列进行再次编码

然后创建我们的embedding嵌入矩阵:

打印一下权重:

Embedding的第一个参数20代表了20种氨基酸,40代表了我们要设置的维度,这里设置为了40,大家也可以设置成其他数字

然后把我们的蛋白质序列进行embedding:

代码语言:javascript复制
proteinA1_sequence = 'ADNKFNKREGGFDDFGFDGDDGNGFIQSLKDDPSQSANLLAEAKKLNDAQAPK'
high_dimensional_vector1 = protein_to_high_dimensional(proteinA1_sequence)

print("Protein Sequence:", proteinA1_sequence)
print("High-Dimensional Vector Shape:", high_dimensional_vector1.shape)
e1=embedding(high_dimensional_vector1)

e1就是我们的embedding之后的结果

e1的shape是我们的蛋白质长度N*20*40

然后再对另外一条蛋白质进行embedding也会得到一个结果e2

然后就可以对e1和e2求余弦相似度了

代码语言:javascript复制
similarity = torch.nn.functional.cosine_similarity(e1.flatten(), e2.flatten(), dim=0)

可以看到通过embedding后 这两个蛋白序列的相似度是

0.9981

0 人点赞