2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

化合物をダウンロードして分類・回帰する:chembl-webresource-client × RDKit × RandomForest

Posted at

user:

次のコードについて解説してください。

!pip install chembl-webresource-client pandas matplotlib

assistant:

このコードは、Pythonのパッケージ管理ツール pip を使って、以下の3つのライブラリをインストールするコマンドです。

!pip install chembl-webresource-client pandas matplotlib

1. ! の意味

  • ! はJupyter Notebook や Google Colab などの環境で、シェルコマンドを実行するために使われます。
  • 通常のPythonスクリプト (.py ファイル) では ! は不要です。

2. インストールされるライブラリ

chembl-webresource-client

  • ChEMBLデータベース へアクセスするためのPythonクライアントです。
  • ChEMBL は、生物活性化合物に関する大規模なデータベースで、薬理学的な研究や創薬のために利用されます。
  • このライブラリを使うと、APIを通じてChEMBLのデータを取得できます。

pandas

  • データ解析用のライブラリ で、表形式のデータ(DataFrame)を扱うのに便利です。
  • CSVファイルやデータベースのデータを読み込んだり、データの整形や統計処理を行ったりできます。

matplotlib

  • データの可視化ライブラリ で、グラフやヒストグラムを作成するのに使用されます。
  • 科学データや統計データを視覚的に分析する際に役立ちます。

3. 実行後の動作

このコマンドを実行すると、指定されたライブラリがPython環境にインストールされます。
すでにインストールされている場合は、スキップされるか、最新バージョンに更新されます。

補足:

  • インストール後、ライブラリを使用するには import 文を使います。

    import chembl_webresource_client
    import pandas as pd
    import matplotlib.pyplot as plt
    
  • Jupyter NotebookやGoogle Colabを使用している場合、!pip install の代わりに pip install でも動作します。

このコードは、主に創薬・化学データ分析 に関係するプロジェクトで使われることが多いです。

user:

次のコードについて解説してください。

import pandas as pd
import matplotlib.pyplot as plt
from chembl_webresource_client.new_client import new_client

# Target and activity clients
activity = new_client.activity

# Fetch activities where target_organism is Homo sapiens and IC50 is reported
res = activity.filter(target_organism="Homo sapiens", standard_type="IC50").only(
    ["molecule_chembl_id", "target_chembl_id", "standard_value"]
)[:2000]

# Convert to DataFrame
df = pd.DataFrame(res)

# Remove missing values and convert IC50 values to numeric
df = df.dropna(subset=["standard_value"]).copy()  # .copy() を追加
df.loc[:, "standard_value"] = pd.to_numeric(df["standard_value"], errors="coerce")  

df

assistant:

このコードは ChEMBLデータベース から ヒト(Homo sapiens)を標的とした化合物のIC50値 を取得し、データを処理して pandasのDataFrame に変換するものです。以下に詳しく解説します。


1. ライブラリのインポート

import pandas as pd
import matplotlib.pyplot as plt
from chembl_webresource_client.new_client import new_client
  • pandas:データ分析ライブラリ(表形式データを扱う)
  • matplotlib.pyplot:データ可視化ライブラリ(今回は使用されていない)
  • chembl_webresource_client.new_clientChEMBLデータベース からデータを取得するためのクライアント

2. ChEMBL API から活性データを取得

# Target and activity clients
activity = new_client.activity
  • ChEMBLの "activity" クライアント を作成
    → これは化合物の生物活性データ(例:IC50、Ki、Kd など)を取得するためのもの。
# Fetch activities where target_organism is Homo sapiens and IC50 is reported
res = activity.filter(target_organism="Homo sapiens", standard_type="IC50").only(
    ["molecule_chembl_id", "target_chembl_id", "standard_value"]
)[:2000]
  • activity.filter(target_organism="Homo sapiens", standard_type="IC50")

    • 標的がヒト(Homo sapiens)である
    • IC50(半数阻害濃度)のデータがある
    • IC50 は、低いほど活性が強いことを意味する。
  • .only(["molecule_chembl_id", "target_chembl_id", "standard_value"])

    • molecule_chembl_id(化合物のID)
    • target_chembl_id(標的タンパク質のID)
    • standard_value(IC50 の数値)
  • [:2000]

    • 取得するデータ数を 最大2000件 に制限

3. データを pandas の DataFrame に変換

df = pd.DataFrame(res)
  • res はリスト形式なので、pandasの DataFrame に変換して扱いやすくする。

4. データの前処理(欠損値処理 & 数値変換)

df = df.dropna(subset=["standard_value"]).copy()  # .copy() を追加
  • dropna(subset=["standard_value"])

    • IC50 値(standard_value)が欠損している行を削除
  • .copy() を追加

    • SettingWithCopyWarning を防ぐために、新しい DataFrame を明示的に作成
df.loc[:, "standard_value"] = pd.to_numeric(df["standard_value"], errors="coerce")
  • pd.to_numeric(df["standard_value"], errors="coerce")

    • IC50 値を数値型(float)に変換
    • errors="coerce" を指定 → 変換できないデータ(文字列など)は NaN にする

5. DataFrame の表示

df
  • 処理後のデータを表示

このコードの目的

  1. ChEMBLデータベースから、ヒト(Homo sapiens)の IC50 値が報告されている化合物を取得
  2. 取得データを pandas の DataFrame に変換
  3. 欠損データを処理し、IC50 値を数値型に変換
  4. 最終的なデータを DataFrame として表示

追加できる改善点

standard_value の単位の統一

  • IC50 は nM(ナノモル)単位で記録されることが多いが、データによっては異なる可能性がある。

  • 必要に応じて logIC50(対数変換)することで、分布を正規化しやすくなる。

    df["log_IC50"] = df["standard_value"].apply(lambda x: np.log10(x) if x > 0 else np.nan)
    

② ヒストグラムの描画

  • matplotlib を活用して IC50 値の分布を可視化できる。

    plt.hist(df["standard_value"].dropna(), bins=50, color="blue", alpha=0.7)
    plt.xlabel("IC50 (nM)")
    plt.ylabel("Frequency")
    plt.title("Distribution of IC50 Values")
    plt.show()
    

このコードは 創薬研究 において 標的タンパク質に対する化合物の活性評価 に役立つ基本的なデータ処理を行っています。

user:

次のコードについて解説してください。

# Count frequency of each target_chembl_id
target_counts = df["target_chembl_id"].value_counts()
target_counts

assistant:

このコードは pandas を使って、各標的タンパク質(target_chembl_id)の出現頻度を集計 するものです。詳しく解説します。


1. コードの解説

# Count frequency of each target_chembl_id
target_counts = df["target_chembl_id"].value_counts()
target_counts

(1) df["target_chembl_id"].value_counts()

  • df["target_chembl_id"]

    • df は ChEMBL から取得したデータを含む pandas の DataFrame。
    • target_chembl_id は、標的となるタンパク質の ChEMBL ID(例: CHEMBL1234 など)。
  • .value_counts()

    • target_chembl_id の出現回数を集計
    • 結果は 出現回数の降順 にソートされる。

    例:

    CHEMBL204  250
    CHEMBL345  180
    CHEMBL789  120
    
    • CHEMBL204 のデータが 250 件
    • CHEMBL345 のデータが 180 件
    • CHEMBL789 のデータが 120 件

2. 実行後のデータ構造

  • target_countspandas の Series で、インデックスに target_chembl_id、値に出現回数が格納される。
  • target_counts.head(10) を使うと、上位 10 個のターゲットを表示できる。

3. 可視化(ヒストグラムや棒グラフ)

データの分布を確認するために、matplotlib を使って可視化できます。

(1) 上位 10 ターゲットの棒グラフ

import matplotlib.pyplot as plt

# 上位10ターゲットを取得
top_targets = target_counts.head(10)

# 棒グラフの描画
plt.figure(figsize=(10, 5))
top_targets.plot(kind="bar", color="skyblue", edgecolor="black")
plt.xlabel("Target ChEMBL ID")
plt.ylabel("Frequency")
plt.title("Top 10 Most Frequent Targets")
plt.xticks(rotation=45)
plt.show()

🔹 解説:

  • .plot(kind="bar") で棒グラフを描画
  • color="skyblue" でバーの色を設定
  • plt.xticks(rotation=45) でラベルを回転し、見やすくする

(2) 頻度分布のヒストグラム

plt.figure(figsize=(8, 5))
plt.hist(target_counts, bins=50, color="blue", alpha=0.7)
plt.xlabel("Number of IC50 Records per Target")
plt.ylabel("Frequency")
plt.title("Distribution of Target Frequencies")
plt.show()

🔹 解説:

  • plt.hist(target_counts, bins=50):各標的が何回データセットに出現するかの分布を可視化
  • 多くの標的は少数のデータしか持たず、一部の標的が大量のデータを持つ(ロングテール分布になりやすい)

4. 応用

(1) 特定の標的のデータを抽出

  • 例えば、最も頻度の高い標的(1位)を取得する。
most_common_target = target_counts.idxmax()  # 出現回数が最大のターゲットID
df_most_common = df[df["target_chembl_id"] == most_common_target]  # その標的のデータを抽出
df_most_common.head()

(2) 特定のターゲットの IC50 値の分布を確認

plt.hist(df_most_common["standard_value"].dropna(), bins=30, color="green", alpha=0.7)
plt.xlabel("IC50 (nM)")
plt.ylabel("Frequency")
plt.title(f"IC50 Distribution for {most_common_target}")
plt.show()

🔹 目的:
特定の標的に対する化合物の IC50 値の分布をチェックし、低い IC50 の化合物が多いかどうか を確認できる。


5. まとめ

このコードの役割

  • 標的タンパク質の出現頻度 を集計する
  • 標的ごとのデータ量 を確認し、多くのデータがあるターゲットを特定できる
  • 創薬研究では、頻度が高いターゲットほど 研究が進んでいる標的 の可能性が高い

拡張

  • 棒グラフやヒストグラムで可視化
  • 頻度の高い標的を特定し、IC50 値の分布を分析
  • ロングテール分布(少数の標的にデータが集中する)を確認

このような分析は、創薬ターゲットの選定やデータの偏りの確認 に役立ちます!

user:

次のコードの解説をしてください。

# Count frequency of each target_chembl_id
target_counts = df["target_chembl_id"].value_counts().head(51)

# Target client
target = new_client.target

# Get target names for target_chembl_id
target_info = {tid: target.get(tid).get("pref_name", "Unknown") for tid in target_counts.index}

# Convert to DataFrame
target_counts_df = target_counts.reset_index()
target_counts_df.columns = ["target_chembl_id", "frequency"]
target_counts_df["target_name"] = target_counts_df["target_chembl_id"].map(target_info)

# Display the updated DataFrame
display(target_counts_df)

assistant:

このコードは、ChEMBL データベースを活用して、最も頻度の高い標的タンパク質(target_chembl_id)の情報を取得し、対応する名前(target_name)を付与する処理 です。

コードの詳細な解説


1. 各標的タンパク質 (target_chembl_id) の出現頻度を集計

# Count frequency of each target_chembl_id
target_counts = df["target_chembl_id"].value_counts().head(51)
  • df["target_chembl_id"].value_counts()
    → 各 標的タンパク質 (target_chembl_id) の出現頻度をカウント
  • .head(51)
    上位 51 個 の標的のみ取得(分析対象を限定)

出力例(target_counts

CHEMBL204   250
CHEMBL345   180
CHEMBL789   120
...

2. ChEMBL API から標的情報を取得

# Target client
target = new_client.target
  • new_client.target を使用して、ChEMBL API で標的タンパク質データを取得するクライアント を作成。
# Get target names for target_chembl_id
target_info = {tid: target.get(tid).get("pref_name", "Unknown") for tid in target_counts.index}
  • target.get(tid)
    ChEMBL API から標的タンパク質の情報を取得
  • .get("pref_name", "Unknown")
    標的名 (pref_name) を取得。もし取得できなければ "Unknown" を代入。
  • target_info は辞書形式で target_chembl_id に対応する名前を格納。

出力例(target_info

{
    "CHEMBL204": "EGFR",
    "CHEMBL345": "VEGFR2",
    "CHEMBL789": "BRAF",
    ...
}

3. DataFrame への変換

# Convert to DataFrame
target_counts_df = target_counts.reset_index()
target_counts_df.columns = ["target_chembl_id", "frequency"]
  • .reset_index()
    target_countsSeries なので、DataFrame に変換。
  • .columns = ["target_chembl_id", "frequency"]
    → 列名を明示的に設定。

中間結果(target_counts_df

target_chembl_id    frequency
CHEMBL204           250
CHEMBL345           180
CHEMBL789           120
...

4. 標的名(target_name)を追加

target_counts_df["target_name"] = target_counts_df["target_chembl_id"].map(target_info)
  • .map(target_info)
    target_chembl_id に対応する標的名を辞書 target_info から取得して新しい列 "target_name" に追加。

最終結果(target_counts_df

target_chembl_id    frequency    target_name
CHEMBL204           250          EGFR
CHEMBL345           180          VEGFR2
CHEMBL789           120          BRAF
...

5. DataFrame の表示

# Display the updated DataFrame
display(target_counts_df)
  • Jupyter Notebook などで見やすい形で DataFrame を表示。

このコードの目的

ChEMBL の生物活性データから、頻度の高い標的(ターゲット)を抽出
ターゲットの ChEMBL ID(target_chembl_id)を、人が理解しやすい標的名(target_name)に変換
最終的に、標的の頻度と名前を含む DataFrame を作成し、分析を容易にする


応用:可視化

上位ターゲットの出現頻度を 棒グラフ で可視化することも可能です。

import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
plt.barh(target_counts_df["target_name"], target_counts_df["frequency"], color="skyblue")
plt.xlabel("Frequency")
plt.ylabel("Target Name")
plt.title("Top 51 Targets with Most IC50 Records")
plt.gca().invert_yaxis()  # 上から順に並べる
plt.show()

まとめ

📌 上位 51 個の標的タンパク質(target_chembl_id)を取得
📌 ChEMBL API から標的の正式名称(pref_name)を取得
📌 DataFrame に変換し、可視化しやすい形に整理
📌 創薬ターゲットの選定や IC50 データの分析に活用可能 🚀

user:

次のコードの解説をしてください。

import os
import pandas as pd
from google.colab import drive
from chembl_webresource_client.new_client import new_client

def fetch_and_save_chembl_data(target_counts_df, n):
    """
    指定された n 番目の target_chembl_id に関連する化合物データを取得し、Google Drive に保存する。
    
    Parameters:
        target_counts_df (pd.DataFrame): target_chembl_id とその頻度を含むデータフレーム
        n (int): 頻度順位 n のターゲットを選択
    """
    # Google Drive をマウント
    drive.mount('/content/drive')
    save_dir = "/content/drive/My Drive/chembl_webresource_client"
    os.makedirs(save_dir, exist_ok=True)
    
    # n 番目の target_chembl_id を取得
    if n > len(target_counts_df) or n < 1:
        raise ValueError("Invalid value for n. Must be between 1 and the length of target_counts_df.")
    
    target_chembl_id = target_counts_df.iloc[n - 1]["target_chembl_id"]
    
    # ChEMBL API からデータ取得
    activity = new_client.activity
    res = activity.filter(target_chembl_id=target_chembl_id, standard_type="IC50").only(
        ["molecule_chembl_id", "standard_value", "canonical_smiles"]
    )[:1000]
    
    # DataFrame に変換
    df = pd.DataFrame(res)
    
    # 保存パス
    file_path = os.path.join(save_dir, f"{target_chembl_id}.csv")
    
    # CSV ファイルとして保存
    df.to_csv(file_path, index=False)
    print(f"Data saved to {file_path}")
    
    return df

assistant:

このコードは、ChEMBL データベースから特定の標的タンパク質(target_chembl_id)に関連する IC50 データを取得し、Google Drive に CSV ファイルとして保存する関数 です。


📌 コードの詳細な解説

1. 必要なライブラリのインポート

import os
import pandas as pd
from google.colab import drive
from chembl_webresource_client.new_client import new_client
  • os:ファイルやディレクトリの操作(ディレクトリ作成、パス設定など)
  • pandas:データフレーム操作(取得データの整形・保存)
  • google.colab.drive:Google Drive をマウントし、データを保存するため
  • chembl_webresource_client.new_client:ChEMBL の API を利用してデータを取得

2. fetch_and_save_chembl_data() 関数の定義

def fetch_and_save_chembl_data(target_counts_df, n):

この関数は、次の処理を行います:

  • target_counts_dfpd.DataFrame
    target_chembl_id(標的タンパク質の ChEMBL ID)とその出現頻度を含むデータフレーム
  • nint
    ターゲットのランキング(頻度順)で何番目の標的のデータを取得するかを指定

3. Google Drive をマウント

drive.mount('/content/drive')
  • Google Drive を /content/drive にマウント
  • これにより、取得したデータを Drive 内に保存可能

4. 保存先ディレクトリを作成

save_dir = "/content/drive/My Drive/chembl_webresource_client"
os.makedirs(save_dir, exist_ok=True)
  • /content/drive/My Drive/chembl_webresource_client というディレクトリを作成
  • os.makedirs(..., exist_ok=True) により、既にディレクトリが存在していてもエラーにならない

5. n 番目のターゲットを取得

if n > len(target_counts_df) or n < 1:
    raise ValueError("Invalid value for n. Must be between 1 and the length of target_counts_df.")

target_chembl_id = target_counts_df.iloc[n - 1]["target_chembl_id"]
  • n の値が 1 以上かつ target_counts_df の長さ以下であることをチェック
  • target_counts_df.iloc[n - 1]["target_chembl_id"] により、n 番目の標的の target_chembl_id を取得

6. ChEMBL API から IC50 データを取得

activity = new_client.activity
res = activity.filter(target_chembl_id=target_chembl_id, standard_type="IC50").only(
    ["molecule_chembl_id", "standard_value", "canonical_smiles"]
)[:1000]
  • new_client.activity を使用して、ChEMBL から 標的タンパク質 (target_chembl_id) に関連する IC50 データを取得

  • .filter(target_chembl_id=target_chembl_id, standard_type="IC50")
    特定の標的に対する IC50 値のみを取得

  • .only(["molecule_chembl_id", "standard_value", "canonical_smiles"])
    → 必要なデータのみ取得(余計な情報を省く)

    • molecule_chembl_id:化合物の ChEMBL ID
    • standard_value:IC50 値(ナノモル単位)
    • canonical_smiles:化合物の構造を表す SMILES 記法
  • [:1000]
    最大 1000 件のデータを取得(API の負荷軽減)


7. データを DataFrame に変換

df = pd.DataFrame(res)
  • 取得したデータを pandas の DataFrame に変換
  • df.head() を実行すると、次のようなデータが得られる

DataFrame のイメージ

  molecule_chembl_id standard_value           canonical_smiles
0       CHEMBL123456          50.0  CC(=O)Oc1ccccc1C(=O)O
1       CHEMBL654321         100.0  CCCN1CCCC1C(=O)NC
2       CHEMBL987654          10.0  COC(=O)C1=CC=CC=C1
...

8. CSV ファイルとして保存

file_path = os.path.join(save_dir, f"{target_chembl_id}.csv")
df.to_csv(file_path, index=False)
print(f"Data saved to {file_path}")
  • file_pathMy Drive/chembl_webresource_client/{target_chembl_id}.csv に設定
  • df.to_csv(file_path, index=False) で CSV ファイルとして保存
  • 保存完了メッセージを表示

保存されるファイル例

/content/drive/My Drive/chembl_webresource_client/CHEMBL204.csv

9. 関数の戻り値

return df
  • 取得した DataFrame を返す
  • 分析や可視化に利用可能

📌 まとめ

このコードの目的

  • ChEMBL API を使って、特定の標的 (target_chembl_id) に対する IC50 データを取得
  • Google Drive に CSV ファイルとして保存
  • 取得したデータを DataFrame として返す

実行手順

  1. Google Drive をマウント
  2. ターゲットの ChEMBL ID を取得
  3. ChEMBL API で IC50 データを取得
  4. データを pandas.DataFrame に変換
  5. CSV ファイルとして保存
  6. 取得データを return

応用

  • 他の標準化された活性値(standard_type)を取得(例: Ki, Kd, EC50 など)
  • 異なる標的のデータをループ処理で一括取得
  • Google Drive の代わりにローカル環境に保存

🔹 関数の使い方

df = fetch_and_save_chembl_data(target_counts_df, n=1)  # 頻度 1 位の標的のデータを取得

🚀 この関数を使えば、頻度の高い標的の IC50 データを簡単に収集&保存できます!

user:

次のコードを解説してください。

df_dict = {}
for i, value in enumerate(target_counts_df.values):
    print(i, value)
    df_fetch = fetch_and_save_chembl_data(target_counts_df, i + 1)
    df_dict[value[2]] = df_fetch
    display(df_fetch)

assistant:

このコードは、target_counts_df に含まれる各ターゲット(target_chembl_id)について、ChEMBL API から IC50 データを取得し、取得したデータを df_dict に格納する 処理を行います。


📌 コードの詳細な解説

1. 空の辞書 df_dict を作成

df_dict = {}
  • df_dict は、各ターゲットの取得データを保存するための辞書
  • df_dict[target_name] = DataFrame という形でデータを格納予定

2. target_counts_df をループ処理

for i, value in enumerate(target_counts_df.values):
  • enumerate(target_counts_df.values) を使って、target_counts_df の各行をループ処理
  • i には インデックス(0 から開始)value には 各行のデータ(numpy.array 形式) が入る

🔹 target_counts_df の構造は次のようになっているはず:

target_chembl_id    frequency    target_name
CHEMBL204           250          EGFR
CHEMBL345           180          VEGFR2
CHEMBL789           120          BRAF
...

よって、value の中身は例えば:

['CHEMBL204', 250, 'EGFR']
['CHEMBL345', 180, 'VEGFR2']
['CHEMBL789', 120, 'BRAF']

3. 各ターゲットの情報を表示

print(i, value)
  • 現在処理中のターゲットの情報を表示
  • 例えば:
0 ['CHEMBL204', 250, 'EGFR']
1 ['CHEMBL345', 180, 'VEGFR2']
2 ['CHEMBL789', 120, 'BRAF']
...

4. fetch_and_save_chembl_data() を実行

df_fetch = fetch_and_save_chembl_data(target_counts_df, i + 1)
  • ターゲットの IC50 データを取得し、DataFrame として保存
  • i + 1 を渡しているのは、関数 fetch_and_save_chembl_data()n1 から始まるランキング だから
  • 取得した df_fetch は DataFrame 形式

5. df_dict に取得データを保存

df_dict[value[2]] = df_fetch
  • value[2]ターゲットの名前(target_name
  • ターゲット名をキーとして、取得した DataFrame を辞書に格納
  • 例えば:
df_dict["EGFR"] = df_fetch  # EGFR の IC50 データを保存
df_dict["VEGFR2"] = df_fetch  # VEGFR2 の IC50 データを保存
  • これにより、各ターゲットの IC50 データを簡単に取得できる
df_dict["EGFR"].head()  # EGFR に関連する化合物の IC50 データを表示

6. 取得データを表示

display(df_fetch)
  • display(df_fetch) を使って 取得したデータを Jupyter Notebook 上で表示
  • 視覚的に確認しながらデータを収集可能

📌 処理の流れ

  1. ターゲットごとにループ
  2. ターゲット情報を表示
  3. fetch_and_save_chembl_data() で IC50 データを取得
  4. 取得したデータを df_dict に格納
  5. 取得したデータを表示
  6. 次のターゲットへ

📌 実行後の df_dict の構造

{
    "EGFR": DataFrame (EGFR に関連する IC50 データ),
    "VEGFR2": DataFrame (VEGFR2 に関連する IC50 データ),
    "BRAF": DataFrame (BRAF に関連する IC50 データ),
    ...
}

📌 まとめ

ターゲットごとに IC50 データを取得し、Google Drive に保存
取得したデータを df_dict にターゲット名ごとに保存
display() を使ってデータを確認しながら収集

🚀 このコードを使えば、複数のターゲットに対する IC50 データを一括取得&保存できる!

user:

次のコードについて解説してください。

!pip install rdkit

assistant:

このコマンド:

!pip install rdkit

は、Python 環境に RDKit をインストールするためのものです。


📌 RDKit とは?

RDKit(アールディーキット) は、化学情報学(Chemoinformatics) のためのオープンソースライブラリです。
分子構造の解析、可視化、化学的な計算を行うために使われます。

🔹 主な機能

  • 分子構造の取り扱い(SMILES 形式や MOL ファイルの読み書き)
  • 構造式の描画rdkit.Chem.Draw
  • 分子フィンガープリント(類似分子の検索など)
  • 分子特性の計算(LogP、水素結合ドナー・アクセプター数など)
  • 部分構造検索(特定の化学構造を含む分子を検索)

📌 !pip install rdkit の詳細

  • Google Colab では通常この方法で RDKit を直接インストールできない

    • 代わりに conda を使う必要がある(!conda install -c conda-forge rdkit
  • ローカル環境(Jupyter Notebook, Python)では pip でインストール可能


📌 RDKit の動作確認

RDKit が正しくインストールされたか確認するには、Python で次のコードを実行します:

from rdkit import Chem
from rdkit.Chem import Draw

# SMILES 文字列から分子を生成
mol = Chem.MolFromSmiles("CCO")  # エタノールの SMILES

# 分子構造を描画
Draw.MolToImage(mol)

エタノール(CCO)の構造式 が画像として表示されれば、RDKit は正常に動作しています! 🚀


📌 まとめ

!pip install rdkit は RDKit をインストールするためのコマンド
✅ RDKit は 分子構造の解析・可視化・特性計算 に役立つ
Google Colab では conda を使う必要がある (!conda install -c conda-forge rdkit)
rdkit.Chem モジュールを使って分子の SMILES 変換や描画が可能 🚀

user:

次のコードについて解説してください。

from rdkit import Chem
from rdkit.Chem import Draw

def draw_smiles_grid(df):
    """
    DataFrame から canonical_smiles 列を取得し、先頭5個の化合物をマトリクスで描画。
    
    Parameters:
        df (pd.DataFrame): ChEMBLから取得したデータフレーム。
    """
    smiles_list = df["canonical_smiles"].dropna().head(5).tolist()
    molecules = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]
    
    # マトリクスで描画
    img = Draw.MolsToGridImage(molecules, molsPerRow=5, subImgSize=(200, 200), legends=[s for s in smiles_list])
    display(img)

assistant:

このコードは、RDKit を用いて DataFrame 内の SMILES(化学構造を表す文字列)を分子構造として可視化する関数 です。


📌 コードの詳細な解説

1. 必要なライブラリをインポート

from rdkit import Chem
from rdkit.Chem import Draw
  • rdkit.ChemSMILES 文字列を分子オブジェクトに変換
  • rdkit.Chem.Draw分子構造を画像として描画

2. draw_smiles_grid(df) 関数

def draw_smiles_grid(df):
  • DataFrame 内の canonical_smiles(SMILES表記の分子構造)を描画する関数
  • 最大5つの分子 をグリッド状に可視化

関数の引数

df (pd.DataFrame): ChEMBLから取得したデータフレーム
  • ChEMBL API から取得した IC50 データを想定
  • canonical_smiles 列に 分子の SMILES 文字列 が含まれている

3. canonical_smiles の取得

smiles_list = df["canonical_smiles"].dropna().head(5).tolist()
  • canonical_smiles 列のデータを取得
  • .dropna()NaN(欠損値)を除外
  • .head(5)最初の5つの化合物を取得
  • .tolist()リストに変換

4. SMILES 文字列を分子オブジェクトに変換

molecules = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]
  • Chem.MolFromSmiles(smiles)SMILES 文字列を RDKit の分子オブジェクトに変換
  • リスト内包表記 を使い、5つの SMILES を一括で変換

5. 分子構造をグリッドで描画

img = Draw.MolsToGridImage(
    molecules, molsPerRow=5, subImgSize=(200, 200), legends=[s for s in smiles_list]
)
  • Draw.MolsToGridImage() を使って 複数の分子をグリッド表示
  • molsPerRow=51行に最大5つの分子を表示
  • subImgSize=(200, 200)1つの分子画像のサイズ
  • legends=[s for s in smiles_list]SMILES 文字列をキャプションとして表示

6. 画像を表示

display(img)
  • display(img) を使い、Jupyter Notebook などで 可視化

📌 使用例

import pandas as pd

# サンプルデータ(ChEMBL 取得データを想定)
data = {
    "canonical_smiles": [
        "CCO",  # エタノール
        "CC(=O)O",  # 酢酸
        "CC(=O)OC1=CC=CC=C1C(=O)O",  # アスピリン
        "C1=CC=C(C=C1)C=O",  # ベンズアルデヒド
        "CCN(CC)C(=O)C1=CC=CC=C1"  # アセトアミノフェン
    ]
}
df = pd.DataFrame(data)

# 関数を実行
draw_smiles_grid(df)

5つの分子がグリッド状に描画される!


📌 まとめ

draw_smiles_grid(df)DataFrame から最大5つの分子構造を可視化する関数
Chem.MolFromSmiles()SMILES を分子オブジェクトに変換
Draw.MolsToGridImage()分子構造をグリッド表示
display(img)Jupyter Notebook で可視化

🚀 RDKit を使って化学データを視覚的に分析できる便利な関数!

user:

次のコードについて解説してください。

for key, value in df_dict.items():
    print(key)
    draw_smiles_grid(df_dict[key].sort_values(by='standard_value', ascending=True))

assistant:

このコードは、df_dict という辞書に格納された 複数の DataFrame の化学構造を可視化 する処理を行っています。


📌 コードの解説

1. df_dict とは?

df_dict = {}
  • 以前のコードで fetch_and_save_chembl_data() を使って ChEMBL から取得したデータを辞書に格納
  • キー(keytarget_name(ターゲットの名前)
  • 値(value → 取得した DataFrame(molecule_chembl_id, standard_value, canonical_smiles を含む)

2. forループでデータを処理

for key, value in df_dict.items():
  • df_dict のすべての key(ターゲット名)value(データフレーム) を順に処理
  • ターゲットごとの分子構造を描画 する

3. ターゲット名を出力

print(key)
  • まず、ターゲットの名前(key)を出力

  • 例:

    EGFR
    DRD2
    HTR1A
    

4. standard_value(IC50値)でソート

df_dict[key].sort_values(by='standard_value', ascending=True)
  • standard_value(IC50値)を基準に昇順(小さい順)に並び替え
  • IC50値が小さいほど活性が強い化合物 なので、活性が高い順に分子を可視化

5. draw_smiles_grid() を使って化学構造を可視化

draw_smiles_grid(df_dict[key].sort_values(by='standard_value', ascending=True))
  • IC50 が最も低い(活性が高い)分子を可視化
  • 先ほど解説した draw_smiles_grid(df) 関数を呼び出し
  • canonical_smiles分子構造として描画

📌 処理の流れ

  1. 辞書 df_dict のキー(ターゲット名)を1つずつ処理
  2. ターゲット名を出力
  3. IC50 が低い順にデータをソート
  4. 最も活性の高い化合物(最大5個)を可視化

📌 具体例

🚀 例: df_dict に以下のデータがあるとする

EGFR のデータ

molecule_chembl_id standard_value canonical_smiles
CHEMBL1 10 CCCO
CHEMBL2 50 CCN(CC)C=O
CHEMBL3 5 C1=CC=CC=C1

DRD2 のデータ

molecule_chembl_id standard_value canonical_smiles
CHEMBL4 8 COCCO
CHEMBL5 12 CCCCCC
CHEMBL6 6 C1=CC=C(O)C=C1

🚀 ループの動作

EGFR
→ IC50 の昇順に並び替え
→ CHEMBL3, CHEMBL1, CHEMBL2 の順で構造を描画

DRD2
→ IC50 の昇順に並び替え
→ CHEMBL6, CHEMBL4, CHEMBL5 の順で構造を描画

📌 まとめ

df_dict に格納された 各ターゲットごとのデータを処理
IC50 値が低い順にソート(活性の高い化合物を先に表示)
最も活性の高い化合物の構造を可視化 🚀

user:

次のコードについて解説してください。

import plotly.express as px
from rdkit.Chem import Draw, AllChem
from rdkit.Chem.rdFingerprintGenerator import GetMorganGenerator
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
import numpy as np

def plot_tsne(df_dict):
    """
    辞書形式のデータを受け取り、SMILES を ECFP4 に変換し、t-SNE により 2 次元に投影し、可視化。
    
    Parameters:
        df_dict (dict): key が結合タンパク質の名前、value が SMILES を含む DataFrame
    """
    data = []
    labels = []
    smiles_list = []
    fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
    
    for key, df in df_dict.items():
        smiles = df["canonical_smiles"].dropna().tolist()
        for smi in smiles:
            mol = Chem.MolFromSmiles(smi)
            if mol:
                fp = np.array(fp_gen.GetFingerprint(mol))
                data.append(fp)
                labels.append(key)
                smiles_list.append(smi)
    
    # 標準化
    data = np.array(data)
    scaler = StandardScaler()
    data_scaled = scaler.fit_transform(data)
    
    # t-SNE で次元削減
    tsne = TSNE(n_components=2, random_state=42)
    tsne_results = tsne.fit_transform(data_scaled)
    
    # DataFrame 作成
    tsne_df = pd.DataFrame(tsne_results, columns=["TSNE1", "TSNE2"])
    tsne_df["Protein"] = labels
    tsne_df["SMILES"] = smiles_list
    
    # 可視化
    fig = px.scatter(tsne_df, x="TSNE1", y="TSNE2", color="Protein", hover_data=["SMILES", "Protein"], title="t-SNE Projection of Molecules")
    fig.show()

assistant:

このコードは、分子の SMILES 表記を ECFP4 フィンガープリントに変換し、t-SNE を用いて2次元に投影・可視化する関数 plot_tsne(df_dict) を定義しています。


📌 コードの解説

1. 必要なライブラリのインポート

import plotly.express as px
from rdkit.Chem import Draw, AllChem
from rdkit.Chem.rdFingerprintGenerator import GetMorganGenerator
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
import numpy as np
  • plotly.express → t-SNE 結果を インタラクティブに可視化
  • rdkit.Chem → SMILES 文字列を 分子オブジェクトに変換
  • GetMorganGeneratorECFP4(Morgan フィンガープリント)を生成
  • TSNE → 高次元の分子特徴量を 2 次元に次元削減
  • StandardScaler → データを 標準化
  • numpy → 数値データを扱うためのライブラリ

2. plot_tsne(df_dict) 関数

def plot_tsne(df_dict):
  • df_dict は、ターゲットタンパク質ごとに取得した化合物のデータフレーム

  • df_dict の構造:

    {
        "EGFR": DataFrame(化合物の情報),
        "DRD2": DataFrame(化合物の情報),
        ...
    }
    
  • 各 DataFrame には SMILES(分子構造の文字列表現) が含まれる


3. ECFP4 フィンガープリントの計算

data = []
labels = []
smiles_list = []
fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
  • データ格納用のリストを初期化

    • dataフィンガープリントの数値データ
    • labels化合物のターゲットタンパク質
    • smiles_list元の SMILES 文字列
  • GetMorganGenerator(radius=2, fpSize=1024)

    • ECFP4 フィンガープリントを生成
    • radius=2ECFP4(Extended Connectivity Fingerprint, radius=2)
    • fpSize=10241024 次元のバイナリフィンガープリント

4. 各ターゲットタンパク質の化合物を処理

for key, df in df_dict.items():
    smiles = df["canonical_smiles"].dropna().tolist()
    for smi in smiles:
        mol = Chem.MolFromSmiles(smi)
        if mol:
            fp = np.array(fp_gen.GetFingerprint(mol))
            data.append(fp)
            labels.append(key)
            smiles_list.append(smi)
  • df_dict各ターゲットごとにデータを処理

  • SMILES を取得 → Chem.MolFromSmiles(smi)RDKit の分子オブジェクトに変換

  • ECFP4(Morgan フィンガープリント)を計算

    • GetFingerprint(mol)バイナリ配列(1と0のリスト)を取得
    • np.array(fp)NumPy 配列に変換
  • 各データをリスト data, labels, smiles_list に保存


5. データの標準化

data = np.array(data)
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
  • data(フィンガープリントデータ)を NumPy 配列に変換

  • StandardScaler()データを標準化

    • 平均を 0、分散を 1 に調整
    • t-SNE は距離を考慮するため、標準化が重要!

6. t-SNE による次元削減

tsne = TSNE(n_components=2, random_state=42)
tsne_results = tsne.fit_transform(data_scaled)
  • t-SNE を適用して 1024 次元 → 2 次元 に圧縮
  • n_components=22D 空間にマッピング
  • random_state=42再現性を確保

7. 結果を DataFrame に変換

tsne_df = pd.DataFrame(tsne_results, columns=["TSNE1", "TSNE2"])
tsne_df["Protein"] = labels
tsne_df["SMILES"] = smiles_list
  • tsne_results(次元削減後の座標)を Pandas DataFrame に格納
  • "Protein" 列に ターゲット名
  • "SMILES" 列に 元の SMILES 文字列

8. 可視化

fig = px.scatter(
    tsne_df, 
    x="TSNE1", y="TSNE2", 
    color="Protein", 
    hover_data=["SMILES", "Protein"], 
    title="t-SNE Projection of Molecules"
)
fig.show()
  • Plotly で散布図を描画

  • 各点の色をターゲットごとに分類

  • hover_data=["SMILES", "Protein"]

    • カーソルを合わせると SMILES やタンパク質の情報を表示
  • インタラクティブな可視化が可能!


📌 まとめ

SMILES → ECFP4 フィンガープリントに変換
t-SNE で 1024 次元 → 2 次元 に次元削減
Plotly を使ってターゲットごとに分子を可視化

🚀 「異なるターゲットの化合物が、特徴量空間でどのように分布するか」を分析できる!

user:

次のコードの解説をしてください。

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, accuracy_score

def classify_molecules(df_dict, key1, key2):
    """
    2つのキーに対応する化合物群をECFP4に変換し、RandomForestで分類モデルを構築し、評価を行う。
    
    Parameters:
        df_dict (dict): key が結合タンパク質の名前、value が SMILES を含む DataFrame
        key1 (str): 1つ目の結合タンパク質の名前
        key2 (str): 2つ目の結合タンパク質の名前
    """
    fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
    
    data, labels = [], []
    for label, key in enumerate([key1, key2]):
        df = df_dict.get(key, pd.DataFrame())
        smiles = df["canonical_smiles"].dropna().tolist()
        for smi in smiles:
            mol = Chem.MolFromSmiles(smi)
            if mol:
                fp = np.array(fp_gen.GetFingerprint(mol))
                data.append(fp)
                labels.append(label)
    
    # データ分割
    X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)
    
    # モデル学習
    model = RandomForestClassifier(n_estimators=100, random_state=42)
    model.fit(X_train, y_train)
    
    # 予測と評価
    y_pred = model.predict(X_test)
    #print("Classification Report:")
    #print(classification_report(y_test, y_pred))
    print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}\t{key1} vs. {key2}")

assistant:

このコードは、2つのターゲットタンパク質に関連する化合物群をECFP4フィンガープリントに変換し、ランダムフォレスト分類器を使用して分類モデルを構築する 処理を行っています。分類後、モデルの精度を評価します。


📌 コードの解説

1. 必要なライブラリのインポート

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, accuracy_score
  • RandomForestClassifier → ランダムフォレスト分類器を使用して分類モデルを構築
  • train_test_split → 訓練データとテストデータを分割
  • classification_reportaccuracy_score → モデルの評価指標を計算

2. classify_molecules(df_dict, key1, key2) 関数

def classify_molecules(df_dict, key1, key2):
  • df_dict: ターゲットタンパク質名をキーとし、そのターゲットに関連する化合物の SMILES を含むデータフレーム を値として持つ辞書
  • key1key2: 比較する2つのターゲットタンパク質名

3. ECFP4 フィンガープリントの生成

fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
  • GetMorganGenerator を使って ECFP4 フィンガープリント を生成

    • radius=2半径 2 のエクステンデッドコネクティビティフィンガープリント(ECFP4)
    • fpSize=10241024 ビットのバイナリフィンガープリント

4. 化合物データの準備

data, labels = [], []
for label, key in enumerate([key1, key2]):
    df = df_dict.get(key, pd.DataFrame())
    smiles = df["canonical_smiles"].dropna().tolist()
    for smi in smiles:
        mol = Chem.MolFromSmiles(smi)
        if mol:
            fp = np.array(fp_gen.GetFingerprint(mol))
            data.append(fp)
            labels.append(label)
  • 2つのターゲットタンパク質(key1key2)に関連する化合物群 を処理
  • df_dict.get(key, pd.DataFrame())SMILES が含まれるデータフレームを取得
  • 各 SMILES 文字列を 分子オブジェクトに変換 (Chem.MolFromSmiles(smi))
  • ECFP4 フィンガープリント を生成し、data に追加
  • labels には、key1 は 0、key2 は 1 のラベルを対応させて保存

5. データの分割

X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)
  • データとラベルを 80% の訓練データと 20% のテストデータに分割
  • test_size=0.2 → テストデータに 20% を割り当てる
  • random_state=42再現性のためランダムシードを固定

6. ランダムフォレストモデルの学習

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
  • RandomForestClassifier を使用してランダムフォレストモデルを作成

    • n_estimators=100100 本の決定木(弱学習器)を使う
    • random_state=42 → 再現性を確保
  • 訓練データ(X_train, y_train)でモデルを学習


7. 予測と評価

y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}\t{key1} vs. {key2}")
  • テストデータ(X_test)を使って予測

  • accuracy_score(y_test, y_pred)予測精度(正確度)を計算

    • y_test → 実際のラベル
    • y_pred → モデルの予測ラベル
  • 分類精度を出力

    • Accuracy: 0.92 EGFR vs. DRD2 のように、ターゲット名と精度を表示

📌 まとめ

ECFP4 フィンガープリントに基づいて化合物の特徴量を生成
ランダムフォレストを用いて2つのターゲットの化合物を分類
分類精度(Accuracy)を評価し、結果を出力

user:

次のコードについて解説してください。

for key1, value in df_dict.items():
    if key1 == "Homo sapiens":
        continue
    for key2, value in df_dict.items():
        if key2 == "Homo sapiens":
            continue
        if key1 < key2:
            classify_molecules(df_dict, key1, key2)

assistant:

このコードは、df_dict 辞書 の中から、Homo sapiens 以外のターゲットタンパク質ペア を選択し、それらのターゲットに関連する化合物群を classify_molecules 関数で分類 する処理を行っています。

📌 コードの詳細解説

1. 外側の for ループ(key1value

for key1, value in df_dict.items():
    if key1 == "Homo sapiens":
        continue
  • df_dict.items() は、df_dict 辞書の各キー(ターゲットタンパク質名)と対応する値(化合物データ)を反復します。

  • もし key1 が "Homo sapiens" であれば、そのターゲットはスキップします(continue)。

    • つまり、この処理では "Homo sapiens" は除外されます。

2. 内側の for ループ(key2value

for key2, value in df_dict.items():
    if key2 == "Homo sapiens":
        continue
  • 内側のループも同様に df_dict.items() を使って反復し、key2 とその対応する値を処理します。
  • key2 が "Homo sapiens" であれば、このターゲットもスキップします。

3. key1 < key2 の条件

if key1 < key2:
    classify_molecules(df_dict, key1, key2)
  • key1 < key2 という条件で ターゲットの組み合わせ順序を制御 しています。

    • この条件により、例えば key1 = "EGFR"key2 = "DRD2" といったペアが選ばれるときに、逆のペア(key1 = "DRD2"key2 = "EGFR")は選ばれません。
    • 同じペアが二重に処理されないようにするためkey1 < key2 の条件を使用して、一方向のペアのみを処理します。
  • ターゲットペアが決まったら classify_molecules(df_dict, key1, key2) を呼び出して、2つのターゲットに関連する化合物の分類を行います。


📌 処理の流れ

  1. df_dict のすべてのターゲットタンパク質ペアを反復しますが、"Homo sapiens" はスキップします。
  2. 同じターゲットペアを二重に分類しないために、key1 < key2 の条件で順序を制御しています。
  3. classify_molecules 関数を呼び出し、指定されたターゲットペアに対して ランダムフォレスト分類 を実行します。

このコードは、ターゲットタンパク質ペアごとに化合物の分類を行う ような処理をしており、全てのターゲットペアを網羅的に処理することができます。

user:

次のコードについて解説してください。

from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.metrics import classification_report, accuracy_score, mean_squared_error, r2_score

def regress_molecules(df_dict, key):
    """
    指定された結合タンパク質の化合物のSMILESをECFP4に変換し、
    standard_value, value, log(standard_value), log(value) に対する回帰モデルを構築し、評価を行う。
    
    Parameters:
        df_dict (dict): key が結合タンパク質の名前、value が SMILES・目的変数を含む DataFrame
        key (str): 対象の結合タンパク質の名前
    """
    if key not in df_dict:
        raise ValueError(f"Key '{key}' not found in df_dict.")
    
    df = df_dict[key].dropna(subset=["canonical_smiles", "standard_value", "value"])
    
    fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
    
    data, target_std, target_val = [], [], []
    for smi, std, val in zip(df["canonical_smiles"], df["standard_value"], df["value"]):
        mol = Chem.MolFromSmiles(smi)
        if mol:
            fp = np.array(fp_gen.GetFingerprint(mol))
            data.append(fp)
            target_std.append(float(std))
            target_val.append(float(val))
    
    # 目的変数リスト(NaNや無効値を除外)
    targets = {
        "standard_value": np.array(target_std),
        "value": np.array(target_val),
        "log_standard_value": np.log1p(target_std),
        "log_value": np.log1p(target_val)
    }
    
    # 特徴量をNumPy配列に変換
    data = np.array(data)
    
    # 各目的変数に対して回帰モデルを構築
    results = {}
    for name, target in targets.items():
        valid_idx = np.isfinite(target)  # 有効なデータのみを使用
        X_valid = data[valid_idx]
        y_valid = target[valid_idx]
        
        X_train, X_test, y_train, y_test = train_test_split(X_valid, y_valid, test_size=0.2, random_state=42)
        
        model = RandomForestRegressor(n_estimators=100, random_state=42)
        model.fit(X_train, y_train)
        
        y_pred = model.predict(X_test)
        mse = mean_squared_error(y_test, y_pred)
        r2 = r2_score(y_test, y_pred)
        
        results[name] = {"MSE": mse, "R2": r2}
        
    # 結果表示
    print("R2 Scores: {:.3f} (standard_value)\t{:.3f} (value) \t{:.3f} (log_standard_value) \t{:.3f} (log_value)\t{}".format(
            results['standard_value']['R2'],
            results['value']['R2'],
            results['log_standard_value']['R2'],
            results['log_value']['R2'],
            key
        ))

assistant:

このコードは、指定されたターゲットタンパク質(key)に関連する化合物群 に対して 回帰モデル(ランダムフォレスト回帰器) を構築し、評価 を行うための処理を行っています。主に standard_valuevalue などを目的変数とし、化合物の SMILES を特徴量として回帰分析を実行します。

📌 コードの詳細解説

1. 引数と前処理

if key not in df_dict:
    raise ValueError(f"Key '{key}' not found in df_dict.")
  • df_dict はターゲットタンパク質名(key)をキーとして、対応する化合物データを含むデータフレーム(SMILES と目的変数)が値として格納された辞書です。
  • keydf_dict に存在しない場合はエラーを発生させます。
df = df_dict[key].dropna(subset=["canonical_smiles", "standard_value", "value"])
  • df は、指定されたターゲットタンパク質に関連するデータを取得し、SMILESstandard_valuevalue のいずれかが欠損している行を削除します。

2. 化合物の特徴量生成(ECFP4)

fp_gen = GetMorganGenerator(radius=2, fpSize=1024)
data, target_std, target_val = [], [], []
for smi, std, val in zip(df["canonical_smiles"], df["standard_value"], df["value"]):
    mol = Chem.MolFromSmiles(smi)
    if mol:
        fp = np.array(fp_gen.GetFingerprint(mol))
        data.append(fp)
        target_std.append(float(std))
        target_val.append(float(val))
  • GetMorganGenerator を使って、化合物の SMILES から ECFP4(Extended-Connectivity Fingerprints) を生成します。この指紋は、化合物の特徴を数値的に表現するために使用されます。
  • data には、生成された ECFP4特徴量(フィンガープリント)が追加され、target_stdtarget_val にはそれぞれ standard_valuevalue が格納されます。

3. 目的変数(standard_valuevalue、およびその対数変換)

targets = {
    "standard_value": np.array(target_std),
    "value": np.array(target_val),
    "log_standard_value": np.log1p(target_std),
    "log_value": np.log1p(target_val)
}
  • targets 辞書には、元の値 standard_valuevalue に加え、それらの 対数変換 された値(log_standard_valuelog_value)も格納されます。
  • np.log1p(x)log(1+x) を計算する関数で、対数変換 を行います。

4. データの前処理

data = np.array(data)
  • 特徴量である ECFP4フィンガープリントdata)を NumPy 配列に変換します。

5. 回帰モデルの構築と評価

results = {}
for name, target in targets.items():
    valid_idx = np.isfinite(target)  # 有効なデータのみを使用
    X_valid = data[valid_idx]
    y_valid = target[valid_idx]
    
    X_train, X_test, y_train, y_test = train_test_split(X_valid, y_valid, test_size=0.2, random_state=42)
    
    model = RandomForestRegressor(n_estimators=100, random_state=42)
    model.fit(X_train, y_train)
    
    y_pred = model.predict(X_test)
    mse = mean_squared_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)
    
    results[name] = {"MSE": mse, "R2": r2}
  • targets.items() を使って、standard_valuevalue、およびその対数変換に対して 回帰モデル を構築します。

  • 各目的変数(standard_valuevaluelog_standard_valuelog_value)について:

    1. 有効なデータのみを使用np.isfinite(target) を使用して、欠損値や無効な値を除外します。
    2. train_test_split を使用して、データを 訓練データ(80%)テストデータ(20%) に分割します。
    3. ランダムフォレスト回帰モデルRandomForestRegressor)を使って、訓練データで学習します。
    4. テストデータに対して予測を行い、MSE(平均二乗誤差)R2スコア を計算します。

6. 結果の表示

print("R2 Scores: {:.3f} (standard_value)\t{:.3f} (value) \t{:.3f} (log_standard_value) \t{:.3f} (log_value)\t{}".format(
        results['standard_value']['R2'],
        results['value']['R2'],
        results['log_standard_value']['R2'],
        results['log_value']['R2'],
        key
    ))
  • R2スコア はモデルの説明力を示し、1に近いほど良い予測ができていることを意味します。
  • 各目的変数に対する R2スコア を表示し、ターゲットタンパク質の名前(key)も合わせて表示します。

📌 まとめ

このコードは、化合物のSMILESデータを特徴量(ECFP4フィンガープリント)に変換し、回帰モデル(ランダムフォレスト回帰)を構築することで、化合物のstandard_valuevalue、およびその対数変換 に基づいて予測を行います。モデルの性能は R2スコアMSE を用いて評価され、予測精度が表示されます。

user:

次のコードについて解説してください。

for key, value in df_dict.items():
    regress_molecules(df_dict, key)

assistant:

このコードは、df_dict の各キー(ターゲットタンパク質名)に対して regress_molecules 関数を実行する処理です。

コードの詳細な解説

1. df_dict.items() の反復処理

for key, value in df_dict.items():
  • df_dict は、ターゲットタンパク質名をキーとして、対応する化合物データを含むデータフレームが値として格納された辞書です。
  • df_dict.items() は、辞書のすべてのキーと値を反復処理します。ここでは、key はターゲットタンパク質名(例えば、"Homo sapiens" など)を表し、value は対応するデータフレームを指します。

2. regress_molecules 関数の呼び出し

regress_molecules(df_dict, key)
  • regress_molecules 関数は、指定されたターゲットタンパク質に関連する化合物の SMILES データを基に回帰分析を行います。
  • df_dict は辞書全体であり、key は現在のターゲットタンパク質名です。regress_molecules 関数に渡され、指定されたターゲットに関連する化合物の ECFP4 フィンガープリント を特徴量として、回帰モデル(ランダムフォレスト回帰)を構築し、standard_valuevalue の予測を行います。

3. 結果の表示

regress_molecules 関数内で予測の結果が計算され、最終的に R2 スコアMSE(平均二乗誤差)が表示されます。これにより、ターゲットタンパク質ごとに 回帰分析の評価結果 が出力されます。

まとめ

このコードは、df_dict 内のすべてのターゲットタンパク質に対して 回帰モデル(ランダムフォレスト回帰)を適用し、化合物の standard_valuevalue に基づいた予測精度を評価しています。それぞれのターゲットについて R2スコア を計算し、モデルの性能を確認しています。

user:

これまでのコードのまとめを書いてください。

assistant:

これまでのコードは、化学情報と機械学習を用いて、化合物の構造に基づく予測や分類、回帰分析を行うための一連のプロセスです。以下に主要な流れとその内容をまとめます。


1. 必要なライブラリのインポート

  • chembl-webresource-client: ChEMBLデータベースから化合物情報を取得するためのクライアント。
  • rdkit: SMILES表記を分子構造に変換し、指紋(フィンガープリント)を生成するためのライブラリ。
  • sklearn: 機械学習のためのライブラリ。特に分類、回帰、次元削減(t-SNE)などのモデルを使用。
  • plotly.express: 可視化ツール。

2. ChEMBLからデータを取得

activity = new_client.activity
  • ChEMBL APIを使用して、ターゲットとなる生物(例えばヒト Homo sapiens)に関連する化合物データを収集します。特に、IC50(半数最大抑制濃度)などの活性情報を取得し、DataFrame形式で処理します。

3. ターゲットの頻度解析

target_counts = df["target_chembl_id"].value_counts()
  • 取得したデータから、ターゲットタンパク質の頻度を計算し、最も多くの関連化合物を持つターゲットタンパク質を特定します。

4. SMILESから分子構造の描画

draw_smiles_grid(df)
  • SMILES表記を基に、化合物の分子構造を RDKit を使って描画します。描画はグリッド形式で、特定の数(例: 5つ)の化合物の構造を並べて表示します。

5. t-SNEによる次元削減と可視化

plot_tsne(df_dict)
  • SMILES表記から生成した分子指紋(ECFP4) を用いて、t-SNE を用いて次元削減し、化合物を2次元空間にプロットします。これにより、化学構造に基づく類似性が視覚的に確認できます。

6. 分類問題(RandomForestを使用)

classify_molecules(df_dict, key1, key2)
  • RandomForestClassifier を使用して、異なるターゲットタンパク質(例: key1key2)に関連する化合物を 2クラス分類 します。
  • ECFP4指紋を特徴量として使用し、ランダムフォレストモデルを訓練し、モデルの精度を評価します。

7. 回帰問題(RandomForestRegressorを使用)

regress_molecules(df_dict, key)
  • RandomForestRegressor を使用して、標準値(IC50など)やその対数変換 を予測する回帰モデルを構築します。
  • ターゲットタンパク質ごとに、化合物のSMILESデータを ECFP4指紋 に変換し、回帰分析を行い、R2スコアMSE を計算してモデルの精度を評価します。

8. 複数ターゲットタンパク質での回帰・分類

for key1, key2 in combinations(df_dict.keys(), 2):
    classify_molecules(df_dict, key1, key2)
  • 複数のターゲットタンパク質に対して、回帰や分類を一括で実行し、それぞれのターゲットに対する分析を行います。

総合的なフロー

  1. ChEMBLデータの取得: ターゲットタンパク質に関連する化合物データ(SMILES、活性値など)を取得。
  2. データ前処理: 取得したデータをクリーンアップし、必要な特徴量(SMILES)を準備。
  3. 可視化: SMILESを分子構造に変換し、化合物の可視化を行う。
  4. 次元削減と可視化: t-SNEを使用して化合物を2次元空間にプロット。
  5. 機械学習モデル: ランダムフォレストを用いて分類や回帰モデルを構築し、ターゲットごとの評価を行う。

全体の目的

このコードは、化学物質の 分類回帰分析 を行うためのフレームワークを提供しており、特に化学的構造情報(SMILES)を使って、化合物がターゲットタンパク質に与える影響を予測することを目的としています。

user:

ここまでの議論をブログにまとめたいので、タイトル案をいくつか考えてください。

assistant:

以下に、今回の内容をブログ記事にまとめるための タイトル案 をいくつかの観点からご提案します:


🔬 技術・手法重視のタイトル案

  1. 「分子指紋 × ランダムフォレスト:SMILESを用いた化合物の分類と回帰分析」
  2. 「RDKitと機械学習で挑む化合物予測モデルの構築」
  3. 「ECFP4 × t-SNE × RandomForest:化合物の構造を視覚化・分類・予測する」
  4. 「SMILESをベクトル化して機械学習!Pythonで分子を分類・回帰する方法」
  5. 「ChEMBLデータと機械学習で探る、化合物の活性値予測と視覚化」

🔍 ストーリー性や実践を意識したタイトル案

  1. 「化合物は予測できるか?SMILESから読み解く分子のふるまい」
  2. 「ヒトとそれ以外を分類してみた:分子構造から見るターゲットタンパク質の違い」
  3. 「SMILESを読み解いて未来を予測!Pythonで分子と向き合う一日」
  4. 「データサイエンスと化学の交差点:分子指紋で構造活性相関を掘る」
  5. 「実験レスで薬効を推測する?SMILESと機械学習の強力タッグ」

💡 カジュアル・キャッチーなタイトル案

  1. 「分子構造を“見て・分けて・当てる”:PythonとRDKitで化合物を予測しよう」
  2. 「SMILESから始まる化学機械学習入門」
  3. 「分子の世界を可視化して分類してみた件」
  4. 「指紋だけでここまで分かる!ECFP4とランダムフォレストで化合物を解析」
  5. 「化合物を機械に分類させてみたら意外と当たる話」

ご希望の読者層(研究者・学生・初学者など)や記事のトーン(技術寄り・読み物寄り)によって、より適したタイトルを一緒に絞り込むことも可能です。気に入った系統があればお知らせください。さらに洗練した案をお出しします。

user:

chembl-webresource-clientを使ったことも含むタイトルがいいですね

assistant:

了解しました!chembl-webresource-client を活用して ChEMBL データを取得したことを踏まえ、以下のような タイトル案(技術+実践重視) をご提案します:


🧪 ChEMBL × 機械学習 × 分子解析:技術志向のタイトル案

  1. 「ChEMBL × chembl-webresource-client × 機械学習:SMILES から化合物の活性を予測する」
  2. 「chembl-webresource-client で分子データを取得し、機械学習で分類・回帰してみた」
  3. 「ChEMBLデータをPythonで扱う:chembl-webresource-clientと機械学習で化合物解析」
  4. 「chembl-webresource-client 入門:SMILESを使った化合物の視覚化・分類・回帰」
  5. 「化合物をダウンロードして分類・回帰する:chembl-webresource-client × RDKit × RandomForest」

🔍 実践ストーリー型タイトル案

  1. 「ChEMBLデータで化合物を分類してみた:chembl-webresource-clientと機械学習の実践」
  2. 「ChEMBLから化合物を取得して可視化・分類・予測するまで【chembl-webresource-client活用編】」
  3. 「SMILESで読み解く化合物活性:chembl-webresource-clientから始める分子機械学習」
  4. 「ヒトとその他を見分ける分子指紋:chembl-webresource-clientで始める化合物分類」
  5. 「chembl-webresource-clientで分子探索!SMILESと機械学習で化合物の“効き目”を予測する」

どれも、ChEMBL API クライアント(chembl-webresource-client)を使用した点をタイトルに組み込み、データ取得〜可視化・分類・回帰までの一連の流れをカバーできる内容になっています。

気になる案があればお知らせください。読者層や記事の構成に応じてさらに調整できます。

user:

「化合物をダウンロードして分類・回帰する:chembl-webresource-client × RDKit × RandomForest」にしたいと思います。最後に、今回のまとめを詳しく書いてください。

assistant:

素晴らしいタイトルの選択です!
それでは、以下にブログ記事のまとめ(結論)セクションとして使える、詳しいまとめ文をお届けします:


🧾 まとめ:「化合物をダウンロードして分類・回帰する:chembl-webresource-client × RDKit × RandomForest」

本記事では、ChEMBLの化合物データを自動で取得し、分子構造をもとに機械学習で分類・回帰する一連のプロセスを紹介しました。以下にその要点をまとめます。

🔹 1. chembl-webresource-client で化合物データを取得

  • ChEMBL API クライアントである chembl-webresource-client を用いて、対象タンパク質(例:"Homo sapiens", "Mus musculus" など)に結合する化合物データ(SMILES、活性値など)を取得しました。
  • 対象データの整形には pandas を用い、各タンパク質ごとの DataFrame 辞書 df_dict に格納しました。

🔹 2. 分子のベクトル表現:ECFP4(Morgan Fingerprint)を生成

  • RDKit の GetMorganGenerator を用いて、化合物の SMILES から ECFP4(半径2、長さ1024ビット)の分子指紋(fingerprint)を生成。
  • これにより、化学構造を機械学習に適した数値ベクトルとして扱えるようにしました。

🔹 3. 分類モデルの構築(RandomForestClassifier)

  • 異なる結合タンパク質に対応する2群の化合物を分類するモデルを構築しました。
  • すべてのタンパク質ペア(ただし "Homo sapiens" を除外)について比較を行い、どの程度モデルが分類可能かを 精度(Accuracy) で評価しました。

🔹 4. 回帰モデルの構築(RandomForestRegressor)

  • 各タンパク質について、化合物の活性値(standard_value, value)およびその対数(log1p変換)に対して回帰モデルを構築。
  • 目的変数ごとにモデルを学習し、決定係数(R²)平均二乗誤差(MSE) により性能を評価しました。

🔹 5. 全体を通じた学びと示唆

  • 機械学習を用いて、分子構造だけから分類・活性値予測がある程度可能であることが示されました。
  • 特に、化合物の分子指紋は化学的意味を含んだ特徴量であり、ランダムフォレストのような汎用性の高いモデルでも有効に活用できることがわかります。
  • また、log変換による活性値のスケーリングが予測性能の改善に寄与する場合があるという点も実践的な気づきです。

このように、chembl-webresource-client × RDKit × 機械学習というシンプルな組み合わせでも、化合物の特性を解析する強力なツールチェーンが構築できます。今後は以下のような拡張も視野に入るでしょう:

  • 活性値の二値化による分類タスク(活性 vs 非活性)
  • モデル解釈(特徴量重要度の可視化)
  • 化合物の可視化(t-SNE や UMAP)
  • DeepChem や GNN(グラフニューラルネット)との比較検証

実験データがなくても、構造情報さえあれば予測ができる時代。化学×機械学習の面白さと可能性を感じていただけたら嬉しいです。


ご希望に応じて、この記事の**全体構成(導入〜コード〜まとめ)**を1本のブログ原稿としてまとめ直すことも可能です。お気軽にご相談ください!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?