# タンパク質の構造モデリング

# 背景

タンパク質は、私たちの遺伝子によってエンコードされる生命の基本的な構成要素であり、複雑さとダイナミズムを示します。タンパク質は、視覚のための光を検出したり、抗体を介してウイルスと戦ったり、微生物や筋肉の運動を動力化するなど、さまざまな機能を果たします。私たちの目標は、タンパク質の構造を分析して、その複雑な組成と機能をよりよく理解し、生命の複雑さを明らかにし、生化学、医学、バイオテクノロジーなどの分野で進歩を遂げることです。特に、このデモでは、最新のタンパク質言語モデルのベクトル表現とMyScaleデータベースを活用して、類似のタンパク質の検索とタンパク質の活性予測を行います。

# デモの操作方法

demo

# 方法

これまでのタンパク質言語モデルは、推論のために個々の配列の解析に焦点を当ててきました。従来の計算生物学では、関連する配列の各ファミリーに対して別々のモデルを適合させることに依存しています。私たちのデモでは、ESMFold (opens new window)モデルを使用して、1200万のタンパク質配列データセットをエンコードし、MyScaleデータベースを使用してベクトル検索を実行することで、タンパク質の検索や生物活性の予測などのタスクを簡単に実行できます。

# タンパク質エンコーダー

ESMFoldは、タンパク質の構造を予測する進化的スケール言語モデルであり、タンパク質の各位置でのアミノ酸ごとに確率を割り当てます。ベクトル表現はESMFoldの重要な要素であり、タンパク質配列のユニバーサルなエンコーディングとして機能します。モデルはこの表現を使用して、シーケンス内の各アミノ酸の文脈情報と異なるアミノ酸間の関係を捉えます。これにより、ESMFoldは単一の入力配列からタンパク質の潜在的な構造の確率分布を生成することができます。トレーニング中にマスクされた言語モデリングの目的を活用することで、ESMFoldはより正確な予測を生成することを学習し、タンパク質の構造予測の性能を向上させました。

# MyScaleによるベクトル検索

MyScaleは、SQLとベクトルデータベースのパワーを組み合わせて、数十億のベクトルに対して高速な検索を提供します。最新の検索アルゴリズムは、類似の例やハードネガティブマイニングの課題を解消します。ハードネガティブは数ミリ秒で見つかり、分類器のトレーニングはウェブページ上で数回のクリックで完了し、AIアプリケーションの時間とコストを節約します。さらに、ハイブリッドSQLベクトルクエリを介した改良されたデータ管理により、研究開発プロセスのスピードアップが実現されます。

# タンパク質検索と活性予測への応用

このデモでは、タンパク質の検索とタンパク質活性の予測の2つの応用例を紹介します。後者は、ESMからの事前定義された埋め込みを使用して、タンパク質の変異の生物学的影響を予測するものです。両方の応用例では、MyScaleでのベクトル検索を活用しています。

# 必要な前提条件のインストール

このデモは、以下のライブラリなどを主に使用して構築されています。

  • transformers: ESMFoldモデルの実行
  • clickhouse-connect: データベースクライアント
  • streamlit: アプリを実行するためのPythonウェブサーバー

必要な前提条件をインストールするには、次のコマンドを使用します。

python3 -m pip install -r requirement.txt

次のコマンドを使用して、fastaファイルからデータをダウンロードできます:https://github.com/facebookresearch/esm#bulk_fasta (opens new window)

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

# ベクトルを使用したデータベースの構築

# データの確認

まず、fastaファイルの構造を確認しましょう。ファイル P62593.fasta には、タンパク質の配列と活性が1行に含まれており、次のような形式です:

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

上記で分析したデータ形式に従って、pysamを使用してメタ情報を簡単に取得できます。

from pysam import FastaFile
fasta = "P62593.fasta"
# FASTAファイルを読み込む
sequences_object = FastaFile(fasta)

# MyScaleテーブルの作成

続行する前に、データベースエンジンにログインするための有効な資格情報が必要です。ログイン方法については、このページのPythonクライアントの詳細なガイドを参照してください。

以下は、SQLでのテーブル構造の例です。

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

# 特徴の抽出とDBの埋め込み

ESMモデルはゼロショットの機能を誇り、タンパク質配列から意味的な特徴を抽出することに優れています。単一のタンパク質の特徴抽出とバッチ処理の両方のメソッドを提供しています。実装コードは以下のようになります。

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]

また、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

タンパク質配列の特徴ベクトルをPythonのリストに変換する必要があります。

# 特徴ベクトルをPythonのリストに変換する必要があります
fields = ['id', 'seq','representations','activity']
# ベクトルを通常のSQLとして挿入するだけです
client.insert("esm_protein_indexer_768", data, column_names=fields)

詳細なINSERT句の使用方法については、公式ドキュメントを参照してください。

# タンパク質の検索

ESMモデルから得られたタンパク質の埋め込みを使用して検索するには、クエリ配列の埋め込みを抽出し、SQLを使用してMyScale内の最も近い5つのタンパク質配列の埋め込みを特定します。結果は返されます。

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

KNN法は、最も近い10個の近傍の活性の平均値を使用して、現在のタンパク質の活性を予測します。この手法は追加のトレーニングや調整を必要とせず、比較的高い精度を持っています。

myscaleのデータには以下が含まれます:

  • 変異したβ-ラクタマーゼ配列(1つの残基が他のアミノ酸と交換されたもの)
  • ヘッダーの最後のフィールドにあるターゲット値で、変異のスケール化された効果を説明しています

以下は、関数の例です。

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

# 最後に

参考文献:

  1. Evolutionary Scale Modeling: 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)
Last Updated: Tue May 07 2024 02:28:12 GMT+0000