# Modelado de la Estructura de Proteínas

# Antecedentes

Las proteínas, codificadas por nuestros genes, son los bloques fundamentales de la vida y exhiben complejidad y dinamismo. Realizan una amplia gama de funciones, como detectar la luz para la visión, combatir virus a través de anticuerpos y generar movimiento en microbios y músculos. Nuestro objetivo es analizar la estructura de las proteínas para comprender mejor su composición y funciones intrincadas, lo que nos permite arrojar luz sobre las complejidades de la vida y realizar avances en campos como la bioquímica, la medicina y la biotecnología. Específicamente en esta demostración, aprovechamos las representaciones vectoriales de los modelos de lenguaje de proteínas de última generación con la base de datos MyScale para la búsqueda de proteínas similares y la predicción de la actividad de las proteínas.

# ¿Cómo interactuar con la demostración?

demo

# Método

Hasta ahora, los modelos de lenguaje de proteínas se han centrado en analizar secuencias individuales para la inferencia. Tradicionalmente, la biología computacional se basa en ajustar modelos separados para cada familia de secuencias relacionadas. Nuestra demostración utiliza el modelo ESMFold (opens new window) para codificar un conjunto de datos de 12 millones de secuencias de proteínas y realizar una búsqueda vectorial utilizando la base de datos MyScale, lo que facilita tareas como la búsqueda de proteínas y la predicción de la actividad biológica.

# Codificador de Proteínas

ESMFold es un modelo de lenguaje evolutivo a escala que predice la estructura de las proteínas asignando una probabilidad a cada aminoácido en cada posición de una proteína en función de su contexto en el resto de la secuencia. La representación vectorial es un componente clave de ESMFold, ya que sirve como una codificación universal para la secuencia de proteínas. El modelo utiliza esta representación para capturar la información contextual de cada aminoácido en la secuencia y las relaciones entre diferentes aminoácidos. Esto permite que ESMFold genere una distribución de probabilidad sobre las posibles estructuras de una proteína a partir de una sola secuencia de entrada. Al aprovechar el objetivo de modelado de lenguaje enmascarado durante el entrenamiento, ESMFold ha aprendido a generar predicciones más precisas, lo que lleva a una mejora en el rendimiento de la predicción de la estructura de las proteínas.

# Búsqueda Vectorial con MyScale

MyScale combina el poder de las bases de datos SQL y vectoriales para realizar búsquedas de alta velocidad en miles de millones de vectores. Los últimos algoritmos de búsqueda eliminan los desafíos de la búsqueda de ejemplos similares y de los negativos difíciles. Los negativos difíciles se encuentran en solo milisegundos y el entrenamiento del clasificador ahora está a solo unos clics de distancia en la página web, lo que le ahorra tiempo y reduce los costos de sus aplicaciones de IA. Además, su mejorada gestión de datos, implementada a través de consultas híbridas de vectores SQL, acelera significativamente su proceso de investigación y desarrollo.

# Aplicación en la Búsqueda de Proteínas y la Predicción de la Actividad de las Proteínas

En esta demostración, mostramos dos aplicaciones: la búsqueda de proteínas y la predicción de la actividad de las proteínas. Esta última implica predecir el impacto biológico de las mutaciones de proteínas utilizando incrustaciones predefinidas de ESM. Ambas aplicaciones utilizan la búsqueda vectorial en MyScale.

# Instalación de los Prerrequisitos

Esta demostración se construye principalmente utilizando las siguientes bibliotecas, entre otras:

  • transformers: Ejecución del modelo ESMFold
  • clickhouse-connect: Cliente de base de datos
  • streamlit: Servidor web de Python para ejecutar la aplicación

Para instalar los prerrequisitos necesarios, utilice el siguiente comando:

python3 -m pip install -r requirement.txt

Puede descargar los datos a través de archivos fasta en https://github.com/facebookresearch/esm#bulk_fasta (opens new window), utilizando el siguiente comando:

python esm/scripts/extract.py esm2_t33_650M_UR50D examples/data/some_proteins.fasta \
  examples/data/some_proteins_emb_esm2 --repr_layers 0 32 33 --include mean per_tok

# Creación de una Base de Datos con Vectores

# Verificar los Datos

Veamos la estructura de los archivos fasta. El archivo P62593.fasta contiene la secuencia de proteínas y la actividad en una fila y se ve así:

id>protein name>activity>protein sequence
>0|beta-lactamase_P20P|1.581033423 > MSIQHFRVALIPFFAAFCLPVFAHPETLVKVKDAEDQLGARVGYIELDLNSGKILESFRPEERFPMMSTFKVLLCGAVLSRVDAGQEQLGRRIHYSQNDLVEYSPVTEKHLTDGMTVRELCSAAITMSDNTAANLLLTTIGGPKELTAFLHNMGDHVTRLDRWEPELNEAIPNDERDTTMPAAMATTLRKLLTGELLTLASRQQLIDWMEADKVAGPLLRSALPAGWFIADKSGAGERGSRGIIAALGPDGKPSRIVVIYTTGSQATMDERNRQIAEIGASLIKHW

Siguiendo el formato de los datos que acabamos de analizar, se pueden obtener fácilmente esa información adicional con pysam:

from pysam import FastaFile
fasta = "P62593.fasta"
# leer archivo FASTA
sequences_object = FastaFile(fasta)

# Creación de una Tabla en MyScale

Antes de continuar, necesitará una credencial válida para iniciar sesión en nuestro motor de base de datos. Consulte la guía detallada sobre el cliente de Python en esta página para aprender cómo iniciar sesión.

Así es como se ve la estructura de la tabla en SQL:

CREATE TABLE esm_protein_indexer
( 
    id UInt64,
    activity Float32,
    seq String, 
    representations Array(Float32),
    CONSTRAINT representations CHECK length(vector) = 768
) 

# Extracción de Características y Rellenar la Base de Datos

El modelo ESM tiene una capacidad de aprendizaje sin etiquetas y se destaca en la extracción de características semánticas de las secuencias de proteínas. Ofrece tanto la extracción de características de una sola proteína como métodos de procesamiento por lotes. El código de implementación se presenta a continuación.

import torch
import esm
# Load ESM-2 model
model, alphabet = esm.pretrained.esm2_t33_650M_UR50D()
batch_converter = alphabet.get_batch_converter()model.eval()  # disables dropout for deterministic results
# Prepare data (first 2 sequences from ESMStructuralSplitDataset superfamily / 4)
data = [
    ("protein1", "MKTVRQERLKSIVRILERSKEPVSGAQLAEELSVSRQVIVQDIAYLRSLGYNIVATPRGYVLAGG"),
    ("protein2", "KALTARQQEVFDLIRDHISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
    ("protein2 with mask","KALTARQQEVFDLIRD<mask>ISQTGMPPTRAEIAQRLGFRSPNAAEEHLKALARKGVIEIVSGASRGIRLLQEE"),
    ("protein3",  "K A <mask> I S Q"),
]
batch_labels, batch_strs, batch_tokens = batch_converter(data)
batch_lens = (batch_tokens != alphabet.padding_idx).sum(1)
# Extract per-residue representations (on CPU)
with torch.no_grad():
    results = model(batch_tokens, repr_layers=[33], return_contacts=True)
    token_representations = results["representations"][33]

También podemos extraer incrustaciones en masa de un archivo FASTA.

python scripts/extract.py esm2_t33_650M_UR50D examples/data/some_proteins.fasta \
  examples/data/some_proteins_emb_esm2 --repr_layers 0 32 33 --include mean per_tok

Ya hemos logrado un pipeline de aprendizaje sin etiquetas con la característica de secuencia de proteínas como clasificador. Hasta ahora, creo que estamos bastante cerca de construir la tabla. Solo queda una pieza en este rompecabezas: insertar datos en MyScale. Así es como se ve:

# Necesita convertir el vector de características en listas de Python
fields = ['id', 'seq','representations','activity']
# solo inserte el vector como SQL normal
client.insert("esm_protein_indexer_768", data, column_names=fields)

Para obtener información detallada sobre el uso de la cláusula INSERT, consulte la Documentación Oficial.

# Búsqueda de Proteínas

Para buscar utilizando las incrustaciones de proteínas obtenidas del modelo ESM, extraemos la incrustación de la secuencia de consulta y utilizamos SQL para localizar las incrustaciones de las cinco secuencias de proteínas más cercanas en MyScale. Luego se devuelve el resultado.

def esm_search(client, model, sequnce, batch_converter, top_k=5):
    data = [("protein1", sequnce)]
    batch_labels, batch_strs, batch_tokens = batch_converter(data)
    with torch.no_grad():
        results = model(batch_tokens, repr_layers=[33], return_contacts=True)
    token_representations = results["representations"][33]
    token_list = token_representations.tolist()[0][0][0]
    query = f"SELECT activity, distance(representations, {token_list}) as dist "
    query += "FROM default.esm_protein_indexer_768"
    query += f" ORDER BY dist LIMIT {top_k}"
    result = client.query(query).named_results()
    result_temp_coords = [i['coords'] for i in result]
    result_temp_seq = [i['seq'] for i in result]
    return result_temp_coords, result_temp_seq

# KNN para la Predicción de la Actividad

El método KNN predice la actividad actual de la proteína utilizando el promedio de las actividades de los 10 vecinos más cercanos. Este enfoque no requiere entrenamiento ni ajuste adicional y tiene una precisión relativamente alta.

Los datos en MyScale contienen:

  • la secuencia de ß-lactamasa mutada, donde se muta un solo residuo (intercambiado por otro aminoácido)
  • el valor objetivo en el último campo del encabezado, que describe el efecto escalado de la mutación

Así es como se ve la función:

def knn_search(client, sequence):
    model, alphabet = esm.pretrained.esm2_t33_650M_UR50D()
    batch_converter = alphabet.get_batch_converter()
    model.eval()
    data = [("protein1", sequence)]
    batch_labels, batch_strs, batch_tokens = batch_converter(data)
    batch_lens = (batch_tokens != alphabet.padding_idx).sum(1)
    with torch.no_grad():
        results = model(batch_tokens, repr_layers=[33], return_contacts=True)
    token_representations = results["representations"][33]
    token_list = token_representations.tolist()[0][0]
    result = client.query(f"SELECT activity, distance(representations, {token_list}) as dist FROM default.esm_protein_indexer ORDER BY dist LIMIT 10").named_results()
    activity_sum = sum(i['activity'] for i in result)
    avg_activity = activity_sum / len(result)
    return avg_activity

# En Resumen

Referencias:

  1. Modelado a Escala Evolutiva: https://github.com/facebookresearch/esm (opens new window)
  2. KNN: https://towardsdatascience.com/machine-learning-basics-with-the-k-nearest-neighbors-algorithm-6a6e71d01761 (opens new window)