@nahisaho/satori 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Overview
9
9
 
10
- このディレクトリには、Exp-01〜13 で蓄積した科学データ解析技法を Agent Skills として体系化した **182 個**のスキルを格納しています。Copilot がプロンプトの文脈に応じて適切なスキルを自動ロードし、各実験で確立した解析パターンを再利用します。131 のスキルは [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で 1,200 以上の外部科学データベースツールとも連携可能です。
10
+ このディレクトリには、Exp-01〜13 で蓄積した科学データ解析技法を Agent Skills として体系化した **190 個**のスキルを格納しています。Copilot がプロンプトの文脈に応じて適切なスキルを自動ロードし、各実験で確立した解析パターンを再利用します。131 のスキルは [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で 1,200 以上の外部科学データベースツールとも連携可能です。
11
11
 
12
12
  ### パイプラインフロー
13
13
 
@@ -286,9 +286,9 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
286
286
  | 中区分 | スキル数 | 概要 |
287
287
  |---|:---:|---|
288
288
  | A. 基盤・ワークフロー | 17 | パイプライン構築・前処理・データ生成・図表・執筆・仮説立案・批判的レビュー・SI 生成・LaTeX 変換・引用検証・査読対応・改訂追跡・論文品質・系統的レビュー・BioThings ID マッピング・データ投稿・CrossRef メタデータ |
289
- | B. 統計・探索的解析 | 9 | EDA・仮説検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化 |
290
- | C. 機械学習・モデリング | 9 | 回帰・分類・特徴量重要度・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視 |
291
- | D. 実験計画・プロセス最適化 | 2 | DOE・応答曲面法・ベイズ最適化 |
289
+ | B. 統計・探索的解析 | 11 | EDA・仮説検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化・統計シミュレーション・ストリーミング解析 |
290
+ | C. 機械学習・モデリング | 11 | 回帰・分類・特徴量重要度・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視・半教師あり学習・マルチタスク学習 |
291
+ | D. 実験計画・プロセス最適化 | 3 | DOE・応答曲面法・ベイズ最適化・適応的実験計画 |
292
292
  | E. 信号・スペクトル・時系列 | 5 | スペクトル解析・生体信号・時系列分解・神経電気生理学・ML 時系列予測 |
293
293
  | F. 生命科学・オミクス | 28 | バイオインフォ・メタボロ・ゲノム配列・マルチオミクス・ネットワーク・プロテオミクス・トランスクリプトミクス・パスウェイ濃縮・代謝物 DB・HPA・ゲノム配列ツール・非コード RNA・オントロジー・EBI DB 群・Ensembl ゲノミクス・STRING/BioGRID PPI・発現比較・モデル生物 DB・GEO 発現プロファイル・寄生虫ゲノミクス・ArrayExpress 発現アーカイブ・GTEx 組織発現・UniProt プロテオーム・Reactome パスウェイ・HGNC 命名法・代謝ネットワーク・糖鎖解析・リピドミクス |
294
294
  | G. 化学・材料・イメージング | 9 | ケモインフォ・材料特性評価・画像形態解析・計算材料科学・ChEMBL アッセイマイニング・MD シミュレーション・高度イメージング・深層化学・STITCH 化学-タンパク質ネットワーク |
@@ -302,8 +302,8 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
302
302
  | O. 研究計画・グラント・規制 | 3 | 助成金申請書・研究方法論・倫理審査・規制科学 |
303
303
  | P. ファーマコビジランス・薬理ゲノミクス | 4 | FAERS 不均衡分析・MedDRA 階層・安全性シグナル検出・PGx 代謝型・PharmGKB 臨床アノテーション・臨床薬理学 PopPK/PBPK |
304
304
  | Q. 腫瘍学・疾患研究 | 10 | 精密腫瘍学 (CIViC/OncoKB)・疾患-遺伝子関連 (GWAS/Orphanet)・がんゲノミクス (COSMIC/DepMap)・希少疾患遺伝学・細胞株リソース・ICGC がんゲノムデータ・Open Targets 遺伝学・DepMap 依存性・Monarch オントロジー・GDC ポータル |
305
- | R. 量子・先端計算 | 9 | 量子計算・GNN・ベイズ統計・説明可能 AI・深層学習・ヘルスケア AI・強化学習・転移学習・不確実性定量化 |
306
- | S. 医用イメージング | 1 | DICOM/NIfTI・WSI 病理画像・Radiomics・MONAI |
305
+ | R. 量子・先端計算 | 11 | 量子計算・GNN・ベイズ統計・説明可能 AI・深層学習・ヘルスケア AI・強化学習・転移学習・不確実性定量化・連合学習・NAS |
306
+ | S. 医用イメージング | 2 | DICOM/NIfTI・WSI 病理画像・Radiomics・MONAI・放射線診断支援 AI |
307
307
  | T. シングルセル・空間・エピゲノミクス | 13 | scRNA-seq・Visium・MERFISH・CELLxGENE・RNA velocity・エピゲノミクス・レギュラトリーゲノミクス・摂動解析・scVI 統合・scATAC-seq/Signac・GPU シングルセル・ENCODE/SCREEN・Human Cell Atlas・高度 Squidpy 空間解析・空間マルチオミクス・CELLxGENE Census |
308
308
  | U. 免疫・感染症 | 2 | 免疫情報学・MHC 結合予測・病原体ゲノミクス・AMR・IEDB |
309
309
  | V. マイクロバイオーム・環境 | 9 | 16S/メタゲノム・α/β 多様性・SDM・OBIS・GBIF・系統解析・rRNA 分類学・植物バイオロジー・海洋生態学・環境地理空間データ・古生物学・MAG 再構築 |
@@ -340,9 +340,9 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
340
340
  | 119 | [scientific-data-submission](scientific-data-submission/SKILL.md) | GenBank/SRA/GEO/BioProject/BioSample データ投稿・FAIR 原則準拠 | 汎用 |
341
341
  | 139 | [scientific-crossref-metadata](scientific-crossref-metadata/SKILL.md) | CrossRef REST API DOI 解決・論文メタデータ・引用数・ジャーナル情報 | 汎用 |
342
342
 
343
- ### B. 統計・探索的解析(9 種)
343
+ ### B. 統計・探索的解析(11 種)
344
344
 
345
- データの理解・検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化を担うスキル群。
345
+ データの理解・検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化・統計シミュレーション・ストリーミング解析を担うスキル群。
346
346
 
347
347
  | # | Skill | 説明 | 参照 Exp |
348
348
  |---|---|---|---|
@@ -355,10 +355,12 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
355
355
  | 179 | [scientific-data-profiling](scientific-data-profiling/SKILL.md) | ydata-profiling 自動 EDA・データ品質スコア (5 次元)・Great Expectations バリデーション | 汎用 |
356
356
  | 180 | [scientific-geospatial-analysis](scientific-geospatial-analysis/SKILL.md) | GeoPandas 地理空間処理・Moran's I/LISA 空間自己相関・Kriging 補間・Folium 地図 | 汎用 |
357
357
  | 181 | [scientific-network-visualization](scientific-network-visualization/SKILL.md) | NetworkX グラフ構築・Louvain/Leiden コミュニティ検出・中心性分析・PyVis インタラクティブ | 汎用 |
358
+ | 187 | [scientific-statistical-simulation](scientific-statistical-simulation/SKILL.md) | Monte Carlo シミュレーション・Bootstrap 推論 (BCa)・Permutation Test・検出力分析 | 汎用 |
359
+ | 188 | [scientific-streaming-analytics](scientific-streaming-analytics/SKILL.md) | River オンライン学習・ストリーミング異常検知・概念ドリフト検出 (ADWIN/DDM) | 汎用 |
358
360
 
359
- ### C. 機械学習・モデリング(9 種)
361
+ ### C. 機械学習・モデリング(11 種)
360
362
 
361
- 教師あり学習・特徴量解釈・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視を担うスキル群。
363
+ 教師あり学習・特徴量解釈・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視・半教師あり学習・マルチタスク学習を担うスキル群。
362
364
 
363
365
  | # | Skill | 説明 | 参照 Exp |
364
366
  |---|---|---|---|
@@ -371,15 +373,18 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
371
373
  | 175 | [scientific-anomaly-detection](scientific-anomaly-detection/SKILL.md) | Isolation Forest/LOF/OCSVM アンサンブル異常検知・Autoencoder 異常・SPC 管理図 | 汎用 |
372
374
  | 176 | [scientific-causal-ml](scientific-causal-ml/SKILL.md) | DoWhy 因果推論・EconML Double ML/Causal Forest・S/T/X-Learner メタラーナー | 汎用 |
373
375
  | 177 | [scientific-model-monitoring](scientific-model-monitoring/SKILL.md) | データドリフト検出 (KS/PSI/Wasserstein)・性能劣化検出・A/B テスト統計 | 汎用 |
376
+ | 185 | [scientific-semi-supervised-learning](scientific-semi-supervised-learning/SKILL.md) | Self-Training・Label Propagation・Pseudo-Labeling 品質評価・ラベル効率化 | 汎用 |
377
+ | 186 | [scientific-multi-task-learning](scientific-multi-task-learning/SKILL.md) | Hard/Soft Parameter Sharing MTL・GradNorm 動的タスクバランシング・PCGrad | 汎用 |
374
378
 
375
- ### D. 実験計画・プロセス最適化(2 種)
379
+ ### D. 実験計画・プロセス最適化(3 種)
376
380
 
377
- 実験設計と応答曲面最適化を担うスキル群。
381
+ 実験設計・応答曲面最適化・適応的実験計画を担うスキル群。
378
382
 
379
383
  | # | Skill | 説明 | 参照 Exp |
380
384
  |---|---|---|---|
381
385
  | 20 | [scientific-doe](scientific-doe/SKILL.md) | 田口直交表・CCD/Box-Behnken・ANOVA 因子効果・ベイズ最適化 | 汎用 |
382
386
  | 21 | [scientific-process-optimization](scientific-process-optimization/SKILL.md) | 応答曲面法 (ML-RSM)・パレート最適化・プロセスウィンドウ | 12, 13 |
387
+ | 190 | [scientific-adaptive-experiments](scientific-adaptive-experiments/SKILL.md) | Thompson Sampling/UCB バンディット・SPRT 逐次検定・ベイズ適応用量探索 | 汎用 |
383
388
 
384
389
  ### E. 信号・スペクトル・時系列(5 種)
385
390
 
@@ -570,9 +575,9 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
570
575
  | 149 | [scientific-monarch-ontology](scientific-monarch-ontology/SKILL.md) | Monarch Initiative 疾患-遺伝子-表現型オントロジー・HPO・エンティティ検索 | 汎用 |
571
576
  | 150 | [scientific-gdc-portal](scientific-gdc-portal/SKILL.md) | NCI Genomic Data Commons REST API・プロジェクト/ケース/SSM 検索 | 汎用 |
572
577
 
573
- ### R. 量子・先端計算(9 種)
578
+ ### R. 量子・先端計算(11 種)
574
579
 
575
- 量子計算・GNN・ベイズ統計・XAI・深層学習・ヘルスケア AI・強化学習・転移学習・不確実性定量化など次世代計算手法を担うスキル群。
580
+ 量子計算・GNN・ベイズ統計・XAI・深層学習・ヘルスケア AI・強化学習・転移学習・不確実性定量化・連合学習・NAS など次世代計算手法を担うスキル群。
576
581
 
577
582
  | # | Skill | 説明 | 参照 Exp |
578
583
  |---|---|---|---|
@@ -585,14 +590,17 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
585
590
  | 104 | [scientific-reinforcement-learning](scientific-reinforcement-learning/SKILL.md) | Stable-Baselines3/PufferLib RL エージェント訓練・分子設計/実験最適化 RL | 汎用 |
586
591
  | 170 | [scientific-transfer-learning](scientific-transfer-learning/SKILL.md) | Vision/NLP ファインチューニング・Few-shot・知識蒸留・ドメイン適応 | 汎用 |
587
592
  | 171 | [scientific-uncertainty-quantification](scientific-uncertainty-quantification/SKILL.md) | Conformal Prediction・MC Dropout・深層アンサンブル・Calibration・ECE | 汎用 |
593
+ | 183 | [scientific-federated-learning](scientific-federated-learning/SKILL.md) | Flower FL パイプライン・FedAvg/FedProx 集約・DP-SGD 差分プライバシー・非 IID 分割 | 汎用 |
594
+ | 184 | [scientific-neural-architecture-search](scientific-neural-architecture-search/SKILL.md) | Optuna NAS・Pareto 多目的探索 (精度 vs サイズ)・探索空間定義・枝刈り | 汎用 |
588
595
 
589
- ### S. 医用イメージング(1 種)
596
+ ### S. 医用イメージング(2 種)
590
597
 
591
- DICOM・WSI 等の医用画像の解析・セグメンテーションを担うスキル。
598
+ DICOM・WSI 等の医用画像解析・セグメンテーション・放射線診断支援 AI を担うスキル群。
592
599
 
593
600
  | # | Skill | 説明 | 参照 Exp |
594
601
  |---|---|---|---|
595
602
  | 56 | [scientific-medical-imaging](scientific-medical-imaging/SKILL.md) | DICOM/NIfTI 処理・MONAI U-Net/SwinUNETR・WSI パッチ抽出・Radiomics・3D 可視化 | 汎用 |
603
+ | 189 | [scientific-radiology-ai](scientific-radiology-ai/SKILL.md) | MONAI CADe/CADx パイプライン・CT/MRI 分類・Grad-CAM 説明可能性・構造化レポート | 汎用 |
596
604
 
597
605
  ### T. シングルセル・空間・エピゲノミクス(13 種)
598
606
 
@@ -752,7 +760,9 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
752
760
  │ ├── scientific-advanced-visualization/
753
761
  │ ├── scientific-data-profiling/
754
762
  │ ├── scientific-geospatial-analysis/
755
- └── scientific-network-visualization/
763
+ ├── scientific-network-visualization/
764
+ │ ├── scientific-statistical-simulation/
765
+ │ └── scientific-streaming-analytics/
756
766
 
757
767
  │── [C] 機械学習・モデリング
758
768
  │ ├── scientific-ml-regression/
@@ -763,11 +773,14 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
763
773
  │ ├── scientific-ensemble-methods/
764
774
  │ ├── scientific-anomaly-detection/
765
775
  │ ├── scientific-causal-ml/
766
- └── scientific-model-monitoring/
776
+ ├── scientific-model-monitoring/
777
+ │ ├── scientific-semi-supervised-learning/
778
+ │ └── scientific-multi-task-learning/
767
779
 
768
780
  │── [D] 実験計画・プロセス最適化
769
781
  │ ├── scientific-doe/
770
- └── scientific-process-optimization/
782
+ ├── scientific-process-optimization/
783
+ │ └── scientific-adaptive-experiments/
771
784
 
772
785
  │── [E] 信号・スペクトル・時系列
773
786
  │ ├── scientific-spectral-signal/
@@ -903,10 +916,13 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
903
916
  │ ├── scientific-healthcare-ai/
904
917
  │ ├── scientific-reinforcement-learning/
905
918
  │ ├── scientific-transfer-learning/
906
- └── scientific-uncertainty-quantification/
919
+ ├── scientific-uncertainty-quantification/
920
+ │ ├── scientific-federated-learning/
921
+ │ └── scientific-neural-architecture-search/
907
922
 
908
- └── [S] 医用イメージング
909
- └── scientific-medical-imaging/
923
+ ├── [S] 医用イメージング
924
+ │ ├── scientific-medical-imaging/
925
+ │ └── scientific-radiology-ai/
910
926
 
911
927
  │── [T] シングルセル・空間・エピゲノミクス
912
928
  │ ├── scientific-single-cell-genomics/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nahisaho/satori",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "SATORI — Agent Skills for Science. GitHub Copilot Agent Skills collection for scientific data analysis.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -0,0 +1,287 @@
1
+ ---
2
+ name: scientific-adaptive-experiments
3
+ description: |
4
+ 適応的実験計画スキル。多腕バンディット (Thompson Sampling/UCB)・
5
+ ベイズ適応設計・逐次検定 (SPRT)・
6
+ Response-Adaptive Randomization・早期停止規則。
7
+ ---
8
+
9
+ # Scientific Adaptive Experiments
10
+
11
+ 実験中のデータに基づいて動的に実験計画を修正する
12
+ 適応的実験設計パイプラインを提供する。
13
+
14
+ ## When to Use
15
+
16
+ - A/B テストの適応的割り当てを行うとき
17
+ - 多腕バンディットで探索と活用を最適化するとき
18
+ - 逐次解析で早期停止判定を行うとき
19
+ - ベイズ適応設計で用量探索するとき
20
+ - Response-Adaptive Randomization で臨床試験を設計するとき
21
+
22
+ ---
23
+
24
+ ## Quick Start
25
+
26
+ ## 1. 多腕バンディット
27
+
28
+ ```python
29
+ import numpy as np
30
+ import pandas as pd
31
+ from typing import List, Dict
32
+
33
+
34
+ class ThompsonSamplingBandit:
35
+ """
36
+ Thompson Sampling ベータ-ベルヌーイバンディット。
37
+ """
38
+
39
+ def __init__(self, n_arms, prior_alpha=1.0, prior_beta=1.0):
40
+ """
41
+ Parameters:
42
+ n_arms: int — アーム数
43
+ prior_alpha: float — Beta 事前分布の α
44
+ prior_beta: float — Beta 事前分布の β
45
+ """
46
+ self.n_arms = n_arms
47
+ self.alphas = np.full(n_arms, prior_alpha)
48
+ self.betas = np.full(n_arms, prior_beta)
49
+ self.history = []
50
+
51
+ def select_arm(self):
52
+ samples = np.array([
53
+ np.random.beta(a, b)
54
+ for a, b in zip(self.alphas, self.betas)])
55
+ return int(np.argmax(samples))
56
+
57
+ def update(self, arm, reward):
58
+ if reward > 0:
59
+ self.alphas[arm] += 1
60
+ else:
61
+ self.betas[arm] += 1
62
+ self.history.append({"arm": arm, "reward": reward})
63
+
64
+ def get_summary(self):
65
+ records = []
66
+ for i in range(self.n_arms):
67
+ a, b = self.alphas[i], self.betas[i]
68
+ records.append({
69
+ "arm": i,
70
+ "alpha": a, "beta": b,
71
+ "mean": a / (a + b),
72
+ "n_pulls": int(a + b - 2),
73
+ "95%_lower": float(np.percentile(
74
+ np.random.beta(a, b, 10000), 2.5)),
75
+ })
76
+ return pd.DataFrame(records)
77
+
78
+
79
+ def run_bandit_experiment(true_rates, n_rounds=1000,
80
+ algorithm="thompson", seed=42):
81
+ """
82
+ バンディット実験シミュレーション。
83
+
84
+ Parameters:
85
+ true_rates: list[float] — 各アームの真の成功率
86
+ n_rounds: int — ラウンド数
87
+ algorithm: str — "thompson" / "ucb" / "epsilon_greedy"
88
+ seed: int — 乱数シード
89
+ """
90
+ rng = np.random.default_rng(seed)
91
+ n_arms = len(true_rates)
92
+
93
+ if algorithm == "thompson":
94
+ bandit = ThompsonSamplingBandit(n_arms)
95
+ for t in range(n_rounds):
96
+ arm = bandit.select_arm()
97
+ reward = int(rng.random() < true_rates[arm])
98
+ bandit.update(arm, reward)
99
+ elif algorithm == "ucb":
100
+ counts = np.zeros(n_arms)
101
+ values = np.zeros(n_arms)
102
+ history = []
103
+ for t in range(n_rounds):
104
+ if t < n_arms:
105
+ arm = t
106
+ else:
107
+ ucb = values + np.sqrt(2 * np.log(t) / (counts + 1e-10))
108
+ arm = int(np.argmax(ucb))
109
+ reward = int(rng.random() < true_rates[arm])
110
+ counts[arm] += 1
111
+ values[arm] += (reward - values[arm]) / counts[arm]
112
+ history.append({"arm": arm, "reward": reward})
113
+ bandit = type("UCB", (), {
114
+ "history": history,
115
+ "get_summary": lambda self: pd.DataFrame([
116
+ {"arm": i, "n_pulls": int(counts[i]),
117
+ "mean": values[i]} for i in range(n_arms)])
118
+ })()
119
+ else: # epsilon_greedy
120
+ epsilon = 0.1
121
+ counts = np.zeros(n_arms)
122
+ values = np.zeros(n_arms)
123
+ history = []
124
+ for t in range(n_rounds):
125
+ if rng.random() < epsilon:
126
+ arm = rng.integers(n_arms)
127
+ else:
128
+ arm = int(np.argmax(values))
129
+ reward = int(rng.random() < true_rates[arm])
130
+ counts[arm] += 1
131
+ values[arm] += (reward - values[arm]) / counts[arm]
132
+ history.append({"arm": arm, "reward": reward})
133
+ bandit = type("EG", (), {
134
+ "history": history,
135
+ "get_summary": lambda self: pd.DataFrame([
136
+ {"arm": i, "n_pulls": int(counts[i]),
137
+ "mean": values[i]} for i in range(n_arms)])
138
+ })()
139
+
140
+ summary = bandit.get_summary()
141
+ best_arm = summary.loc[summary["mean"].idxmax(), "arm"]
142
+ print(f"Bandit ({algorithm}, {n_rounds} rounds):")
143
+ print(f" Best arm: {best_arm} (est. rate={summary.loc[summary['arm']==best_arm, 'mean'].values[0]:.3f})")
144
+ print(f" True best: {np.argmax(true_rates)} (rate={max(true_rates):.3f})")
145
+ return bandit, summary
146
+ ```
147
+
148
+ ## 2. 逐次検定 (SPRT)
149
+
150
+ ```python
151
+ def sequential_probability_ratio_test(data_stream,
152
+ h0_rate=0.5,
153
+ h1_rate=0.6,
154
+ alpha=0.05, beta=0.2):
155
+ """
156
+ Wald の逐次確率比検定 (SPRT)。
157
+
158
+ Parameters:
159
+ data_stream: iterable — 逐次観測データ (0/1)
160
+ h0_rate: float — 帰無仮説下の成功率
161
+ h1_rate: float — 対立仮説下の成功率
162
+ alpha: float — 第 1 種の過誤確率
163
+ beta: float — 第 2 種の過誤確率
164
+ """
165
+ A = np.log((1 - beta) / alpha) # H1 採択境界
166
+ B = np.log(beta / (1 - alpha)) # H0 採択境界
167
+
168
+ log_lr = 0.0
169
+ history = []
170
+
171
+ for i, x in enumerate(data_stream):
172
+ # 対数尤度比の更新
173
+ if x == 1:
174
+ log_lr += np.log(h1_rate / h0_rate)
175
+ else:
176
+ log_lr += np.log((1 - h1_rate) / (1 - h0_rate))
177
+
178
+ decision = None
179
+ if log_lr >= A:
180
+ decision = "reject_H0"
181
+ elif log_lr <= B:
182
+ decision = "accept_H0"
183
+
184
+ history.append({
185
+ "step": i + 1, "observation": x,
186
+ "log_lr": log_lr,
187
+ "upper_bound": A, "lower_bound": B,
188
+ "decision": decision,
189
+ })
190
+
191
+ if decision is not None:
192
+ print(f"SPRT: {decision} at step {i+1} "
193
+ f"(log_LR={log_lr:.3f})")
194
+ break
195
+
196
+ df = pd.DataFrame(history)
197
+ if df["decision"].iloc[-1] is None:
198
+ print(f"SPRT: Inconclusive after {len(df)} observations")
199
+ return df
200
+ ```
201
+
202
+ ## 3. ベイズ適応用量探索
203
+
204
+ ```python
205
+ def bayesian_adaptive_dose_finding(dose_levels, n_patients=30,
206
+ target_toxicity=0.33,
207
+ prior_alpha=1.0,
208
+ prior_beta=1.0, seed=42):
209
+ """
210
+ ベイズ適応用量探索 (CRM 簡易版)。
211
+
212
+ Parameters:
213
+ dose_levels: list[float] — 用量レベル
214
+ n_patients: int — 患者数
215
+ target_toxicity: float — 目標毒性率
216
+ prior_alpha: float — Beta 事前分布 α
217
+ prior_beta: float — Beta 事前分布 β
218
+ seed: int — 乱数シード
219
+ """
220
+ rng = np.random.default_rng(seed)
221
+ n_doses = len(dose_levels)
222
+ alphas = np.full(n_doses, prior_alpha)
223
+ betas = np.full(n_doses, prior_beta)
224
+ history = []
225
+
226
+ # 真の毒性率 (シミュレーション用)
227
+ true_tox = np.linspace(0.05, 0.60, n_doses)
228
+
229
+ current_dose = 0
230
+ for patient in range(n_patients):
231
+ toxicity = int(rng.random() < true_tox[current_dose])
232
+
233
+ if toxicity:
234
+ alphas[current_dose] += 1
235
+ else:
236
+ betas[current_dose] += 1
237
+
238
+ history.append({
239
+ "patient": patient + 1,
240
+ "dose_level": current_dose,
241
+ "dose_value": dose_levels[current_dose],
242
+ "toxicity": toxicity,
243
+ })
244
+
245
+ # 次の用量選択 (最も target に近い推定毒性率)
246
+ means = alphas / (alphas + betas)
247
+ distances = np.abs(means - target_toxicity)
248
+ current_dose = int(np.argmin(distances))
249
+
250
+ # MTD 推定
251
+ final_means = alphas / (alphas + betas)
252
+ mtd_idx = int(np.argmin(np.abs(final_means - target_toxicity)))
253
+
254
+ summary = pd.DataFrame({
255
+ "dose_level": range(n_doses),
256
+ "dose_value": dose_levels,
257
+ "est_toxicity": final_means,
258
+ "n_treated": [sum(1 for h in history
259
+ if h["dose_level"] == i)
260
+ for i in range(n_doses)],
261
+ })
262
+
263
+ print(f"Bayesian adaptive: MTD = dose {mtd_idx} "
264
+ f"(value={dose_levels[mtd_idx]}, "
265
+ f"est_tox={final_means[mtd_idx]:.3f})")
266
+ return summary, pd.DataFrame(history)
267
+ ```
268
+
269
+ ---
270
+
271
+ ## パイプライン統合
272
+
273
+ ```
274
+ [実験目的] → adaptive-experiments → statistical-testing
275
+ (適応設計) (最終解析)
276
+
277
+ doe ← statistical-simulation
278
+ (古典計画) (検出力分析)
279
+ ```
280
+
281
+ ## パイプライン出力
282
+
283
+ | ファイル | 説明 | 次スキル |
284
+ |---------|------|---------|
285
+ | `bandit_summary.csv` | バンディット結果 | → 最適アーム |
286
+ | `sprt_history.csv` | SPRT 検定履歴 | → 判定結果 |
287
+ | `dose_finding.csv` | 用量探索結果 | → MTD 推定 |