Skip to main contentscientific-graph-neural-networks
グラフニューラルネットワーク (GNN) スキル。PyTorch Geometric・TorchDrug・
DeepChem を活用し、分子特性予測・タンパク質モデリング・知識グラフ推論・
ノード/グラフ分類を支援。
「GNN で分子特性を予測して」「グラフ分類して」「ナレッジグラフ推論して」で発火。
الانتقال إلى التثبيت التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/nahisaho/satori --skill scientific-graph-neural-networksيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
المهن ذات الصلةSOC
استنادا إلى تصنيف SOC المهني
| name | scientific-graph-neural-networks |
| description | グラフニューラルネットワーク (GNN) スキル。PyTorch Geometric・TorchDrug・
DeepChem を活用し、分子特性予測・タンパク質モデリング・知識グラフ推論・
ノード/グラフ分類を支援。
「GNN で分子特性を予測して」「グラフ分類して」「ナレッジグラフ推論して」で発火。
|
Scientific Graph Neural Networks
グラフニューラルネットワーク (GNN) のための解析スキル。
分子グラフ、タンパク質構造、知識グラフなどの構造化データに対する
深層学習を支援する。
When to Use
- 分子特性予測(溶解度・毒性・ADMET・活性)
- タンパク質機能予測・相互作用予測
- 知識グラフ埋め込み・リンク予測
- ノード分類・グラフ分類・グラフ回帰
- 分子生成・レトロシンセシス計画
- ソーシャル/バイオネットワーク解析
Quick Start
GNN パイプライン
Phase 1: Graph Construction
- 分子 SMILES → 分子グラフ変換
- タンパク質 PDB → 接触マップグラフ
- ノード/エッジ特徴量設計
↓
Phase 2: Model Selection
- GCN / GAT / GIN / GraphSAGE / SchNet
- Message Passing 方式選択
- プーリング戦略 (mean, sum, attention)
↓
Phase 3: Training
- データ分割 (scaffold split 推奨)
- ミニバッチローダー設定
- 学習率スケジューラ
↓
Phase 4: Evaluation
- ROC-AUC / RMSE / MAE
- 5-fold CV or scaffold split
- MoleculeNet ベンチマーク比較
↓
Phase 5: Interpretation
- GNNExplainer / Attention 可視化
- 分子部分構造の寄与分析
- SHAP for graphs
↓
Phase 6: Deployment
- モデルエクスポート (ONNX)
- バッチ推論パイプライン
- 予測レポート生成
Workflow
1. PyTorch Geometric: 分子特性予測
import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv, GATConv, GINConv, global_mean_pool
from torch_geometric.data import Data, DataLoader
from torch_geometric.datasets import MoleculeNet
from rdkit import Chem
import numpy as np
():
mol = Chem.MolFromSmiles(smiles)
mol :
atom_features = []
atom mol.GetAtoms():
features = [
atom.GetAtomicNum(),
atom.GetDegree(),
atom.GetFormalCharge(),
(atom.GetHybridization()),
(atom.GetIsAromatic()),
atom.GetTotalNumHs(),
atom.GetNumRadicalElectrons(),
]
atom_features.append(features)
x = torch.tensor(atom_features, dtype=torch.)
edge_index = []
bond mol.GetBonds():
i, j = bond.GetBeginAtomIdx(), bond.GetEndAtomIdx()
edge_index.extend([[i, j], [j, i]])
edge_index = torch.tensor(edge_index, dtype=torch.long).t().contiguous()
Data(x=x, edge_index=edge_index)
(torch.nn.Module):
():
().__init__()
.convs = torch.nn.ModuleList()
.convs.append(GCNConv(in_channels, hidden_channels))
_ (n_layers - ):
.convs.append(GCNConv(hidden_channels, hidden_channels))
.convs.append(GCNConv(hidden_channels, hidden_channels))
.lin = torch.nn.Linear(hidden_channels, out_channels)
():
conv .convs:
x = conv(x, edge_index)
x = F.relu(x)
x = F.dropout(x, p=, training=.training)
x = global_mean_pool(x, batch)
x = .lin(x)
x
(torch.nn.Module):
():
().__init__()
.conv1 = GATConv(in_channels, hidden_channels, heads=heads, dropout=)
.conv2 = GATConv(hidden_channels * heads, hidden_channels, heads=, dropout=)
.lin = torch.nn.Linear(hidden_channels, out_channels)
():
x = F.elu(.conv1(x, edge_index))
x = F.elu(.conv2(x, edge_index))
x = global_mean_pool(x, batch)
x = .lin(x)
x
def
smiles_to_graph
smiles
"""SMILES → PyG Data オブジェクト"""
if
is
None
return
None
for
in
int
int
float
for
in
return
class
MolGCN
def
__init__
self, in_channels, hidden_channels, out_channels, n_layers=3
super
self
self
for
in
range
2
self
self
self
def
forward
self, x, edge_index, batch
for
in
self
0.2
self
self
return
class
MolGAT
def
__init__
self, in_channels, hidden_channels, out_channels, heads=4
super
self
0.3
self
1
0.3
self
def
forward
self, x, edge_index, batch
self
self
self
return
2. GIN (Graph Isomorphism Network)
from torch_geometric.nn import GINConv, global_add_pool
class MolGIN(torch.nn.Module):
"""GIN: 最大表現力を持つ GNN (WL test 等価)"""
def __init__(self, in_channels, hidden_channels, out_channels, n_layers=5):
super().__init__()
self.convs = torch.nn.ModuleList()
self.batch_norms = torch.nn.ModuleList()
for i in range(n_layers):
in_ch = in_channels if i == 0 else hidden_channels
mlp = torch.nn.Sequential(
torch.nn.Linear(in_ch, hidden_channels),
torch.nn.BatchNorm1d(hidden_channels),
torch.nn.ReLU(),
torch.nn.Linear(hidden_channels, hidden_channels),
)
self.convs.append(GINConv(mlp, train_eps=True))
self.batch_norms.append(torch.nn.BatchNorm1d(hidden_channels))
self.lin1 = torch.nn.Linear(hidden_channels, hidden_channels)
self.lin2 = torch.nn.Linear(hidden_channels, out_channels)
def forward(self, x, edge_index, batch):
for conv, bn in zip(self.convs, self.batch_norms):
x = conv(x, edge_index)
x = bn(x)
x = F.relu(x)
x = global_add_pool(x, batch)
x = F.relu(self.lin1(x))
x = F.dropout(x, p=0.5, training=self.training)
x = self.lin2(x)
return x
3. TorchDrug: 分子特性予測
import torchdrug
from torchdrug import datasets, models, tasks, core
dataset = datasets.BBBP("data/bbbp/", atom_feature="default", bond_feature="default")
train_set, valid_set, test_set = dataset.split(ratios=[0.8, 0.1, 0.1])
model = models.GIN(
input_dim=dataset.node_feature_dim,
hidden_dims=[256, 256, 256, 256],
batch_norm=True,
short_cut=True,
readout="mean",
)
task = tasks.PropertyPrediction(
model,
task=dataset.tasks,
criterion="bce",
metric=("auprc", "auroc"),
)
optimizer = torch.optim.Adam(task.parameters(), lr=1e-3)
solver = core.Engine(
task,
train_set, valid_set, test_set,
optimizer,
batch_size=128,
gpus=[0],
)
solver.train(num_epoch=100)
solver.evaluate("valid")
4. 知識グラフ推論
from torchdrug import datasets as td_datasets, models as td_models, tasks as td_tasks
class KGEModel:
"""Knowledge Graph Embedding wrapper"""
MODELS = {
"transe": {"embedding_dim": 256, "margin": 6.0},
"rotate": {"embedding_dim": 256},
"complex": {"embedding_dim": 256},
}
def __init__(self, model_name, num_entities, num_relations):
self.model_name = model_name
self.num_entities = num_entities
self.num_relations = num_relations
def train_and_evaluate(self, train_triples, valid_triples, test_triples):
"""KGE トレーニングと評価"""
pass
def predict_links(self, head, relation, top_k=10):
"""リンク予測: (h, r, ?) → top-k tail entities"""
pass
def drug_repurposing_candidates(self, disease_entity, treats_relation):
"""薬物リポジショニング候補のスコアリング"""
pass
5. トレーニング・評価ループ
from sklearn.metrics import roc_auc_score, mean_squared_error
from torch_geometric.loader import DataLoader
def train_gnn(model, train_loader, optimizer, criterion, device="cpu"):
"""GNN トレーニング 1 エポック"""
model.train()
total_loss = 0
for batch in train_loader:
batch = batch.to(device)
optimizer.zero_grad()
out = model(batch.x, batch.edge_index, batch.batch)
loss = criterion(out.squeeze(), batch.y.float())
loss.backward()
optimizer.step()
total_loss += loss.item() * batch.num_graphs
return total_loss / len(train_loader.dataset)
@torch.no_grad()
def evaluate_gnn(model, loader, device="cpu"):
"""GNN 評価"""
model.eval()
y_true, y_pred = [], []
for batch in loader:
batch = batch.to(device)
out = model(batch.x, batch.edge_index, batch.batch)
y_true.extend(batch.y.cpu().numpy())
y_pred.extend(out.squeeze().cpu().numpy())
y_true = np.array(y_true)
y_pred = np.array(y_pred)
if len(np.unique(y_true)) == 2:
auc = roc_auc_score(y_true, y_pred)
return {"auroc": round(auc, 4)}
else:
rmse = np.sqrt(mean_squared_error(y_true, y_pred))
return {"rmse": round(rmse, 4)}
def scaffold_split(dataset, train_ratio=0.8, val_ratio=0.1):
"""
Scaffold Split: 化学構造の Murcko scaffold ベースでデータ分割。
train/val/test が異なる scaffold を持つことを保証。
"""
from rdkit.Chem.Scaffolds.MurckoScaffold import MurckoScaffoldSmiles
scaffolds = {}
for idx, data in enumerate(dataset):
smiles = data.smiles if hasattr(data, "smiles") else ""
scaffold = MurckoScaffoldSmiles(smiles=smiles) if smiles else str(idx)
scaffolds.setdefault(scaffold, []).append(idx)
scaffold_sets = sorted(scaffolds.values(), key=len, reverse=True)
train_idx, val_idx, test_idx = [], [], []
n = len(dataset)
for s in scaffold_sets:
if len(train_idx) / n < train_ratio:
train_idx.extend(s)
elif len(val_idx) / n < val_ratio:
val_idx.extend(s)
else:
test_idx.extend(s)
return train_idx, val_idx, test_idx
Best Practices
- Scaffold Split 必須: 分子タスクでは random split ではなく scaffold split を使用
- Message Passing 層数: 3-5 層が最適。深すぎると over-smoothing
- Readout 関数: 分類→mean pool、検出→sum pool、注意→attention pool
- ノード特徴量: 原子番号・次数・芳香族性・形式電荷・混成軌道を含める
- 3D 情報活用: SchNet/DimeNet で 3D 座標を持つ分子は距離情報を活用
- MoleculeNet ベンチマーク: 新手法は BBBP/BACE/HIV/Tox21 での比較を報告
- GNNExplainer: 予測根拠の可視化により化学的解釈性を担保
Completeness Checklist
References
Output Files
| ファイル | 形式 | 生成タイミング |
|---|
results/gnn_predictions.json | GNN 予測結果(JSON) | 推論完了時 |
results/gnn_benchmark.json | ベンチマーク比較(JSON) | 評価完了時 |
figures/gnn_training_curve.png | 学習曲線プロット | トレーニング完了時 |
figures/gnn_explanation.png | GNNExplainer 可視化 | 解釈性分析時 |
利用可能ツール
| カテゴリ | 主要ツール | 用途 |
|---|
| PubChem | PubChem_get_compound_properties_by_CID | 分子物性取得 |
| ChEMBL | ChEMBL_get_molecule | 分子情報取得 |
| ChEMBL | ChEMBL_get_activity | バイオアッセイデータ |
| UniProt | UniProt_get_entry_by_accession | タンパク質グラフ構築用 |
| BindingDB | BindingDB_get_ligands_by_uniprot | リガンド-ターゲットデータ |
参照スキル
| スキル | 連携 |
|---|
scientific-cheminformatics | ← SMILES 前処理・分子記述子 |
scientific-drug-target-profiling | → 標的予測・活性予測の GNN 応用 |
scientific-admet-pharmacokinetics | → ADMET 予測モデル |
scientific-network-analysis | ← グラフ構造解析 |
scientific-deep-learning | ← NN アーキテクチャ設計・トレーニング手法 |
scientific-explainable-ai | → GNN 予測の説明可能性 |
scientific-protein-structure-analysis | ← タンパク質グラフの構築 |