@nahisaho/satori 0.23.0 → 0.24.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 として体系化した **174 個**のスキルを格納しています。Copilot がプロンプトの文脈に応じて適切なスキルを自動ロードし、各実験で確立した解析パターンを再利用します。131 のスキルは [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で 1,200 以上の外部科学データベースツールとも連携可能です。
10
+ このディレクトリには、Exp-01〜13 で蓄積した科学データ解析技法を Agent Skills として体系化した **182 個**のスキルを格納しています。Copilot がプロンプトの文脈に応じて適切なスキルを自動ロードし、各実験で確立した解析パターンを再利用します。131 のスキルは [ToolUniverse](https://github.com/mims-harvard/ToolUniverse) SMCP 経由で 1,200 以上の外部科学データベースツールとも連携可能です。
11
11
 
12
12
  ### パイプラインフロー
13
13
 
@@ -286,10 +286,10 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
286
286
  | 中区分 | スキル数 | 概要 |
287
287
  |---|:---:|---|
288
288
  | A. 基盤・ワークフロー | 17 | パイプライン構築・前処理・データ生成・図表・執筆・仮説立案・批判的レビュー・SI 生成・LaTeX 変換・引用検証・査読対応・改訂追跡・論文品質・系統的レビュー・BioThings ID マッピング・データ投稿・CrossRef メタデータ |
289
- | B. 統計・探索的解析 | 6 | EDA・仮説検定・次元削減・記号数学・欠損データ解析・高度可視化 |
290
- | C. 機械学習・モデリング | 6 | 回帰・分類・特徴量重要度・アクティブラーニング・AutoML・アンサンブル学習 |
289
+ | B. 統計・探索的解析 | 9 | EDA・仮説検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化 |
290
+ | C. 機械学習・モデリング | 9 | 回帰・分類・特徴量重要度・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視 |
291
291
  | D. 実験計画・プロセス最適化 | 2 | DOE・応答曲面法・ベイズ最適化 |
292
- | E. 信号・スペクトル・時系列 | 4 | スペクトル解析・生体信号・時系列分解・神経電気生理学 |
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 化学-タンパク質ネットワーク |
295
295
  | H. 臨床・疫学・メタ科学 | 7 | 生存解析・因果推論・メタアナリシス・臨床試験解析・臨床レポート・バイオバンク大規模コホート・臨床標準用語 |
@@ -298,7 +298,7 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
298
298
  | K. 構造生物学・タンパク質工学 | 7 | PDB/AlphaFold 構造解析・de novo タンパク質設計・PPI ネットワーク・ドメイン/ファミリー・構造プロテオミクス・AlphaFold DB 構造予測・RCSB PDB 構造検索 |
299
299
  | L. 精密医療・臨床意思決定 | 6 | 変異解釈 (ACMG/AMP)・エビデンスベース臨床意思決定・バリアント効果予測・CIViC 臨床エビデンス・gnomAD バリアント・ClinGen キュレーション |
300
300
  | M. 実験室自動化・データ管理 | 3 | 液体ハンドリング・プロトコル管理・ELN/LIMS 連携・ラボデータ管理・CRISPR gRNA 設計 |
301
- | N. 科学プレゼンテーション・図式 | 3 | 科学スライド・ポスター・ワークフロー図・科学図式・インタラクティブダッシュボード |
301
+ | N. 科学プレゼンテーション・図式 | 4 | 科学スライド・ポスター・ワークフロー図・科学図式・インタラクティブダッシュボード・再現可能レポート |
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 ポータル |
@@ -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. 統計・探索的解析(6 種)
343
+ ### B. 統計・探索的解析(9 種)
344
344
 
345
- データの理解・検定・次元削減・記号数学・欠損データ解析・高度可視化を担うスキル群。
345
+ データの理解・検定・次元削減・記号数学・欠損データ解析・高度可視化・データプロファイリング・地理空間解析・ネットワーク可視化を担うスキル群。
346
346
 
347
347
  | # | Skill | 説明 | 参照 Exp |
348
348
  |---|---|---|---|
@@ -352,10 +352,13 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
352
352
  | 105 | [scientific-symbolic-mathematics](scientific-symbolic-mathematics/SKILL.md) | SymPy 解析的微積分・ODE 求解・線形代数・科学モデリング記号計算 | 汎用 |
353
353
  | 172 | [scientific-missing-data-analysis](scientific-missing-data-analysis/SKILL.md) | 欠損パターン診断 (MCAR/MAR/MNAR)・Little's MCAR テスト・MICE 多重代入・KNN/MissForest 補完 | 汎用 |
354
354
  | 173 | [scientific-advanced-visualization](scientific-advanced-visualization/SKILL.md) | Plotly 3D・Altair 宣言的可視化・Parallel Coordinates・出版品質図・アニメーション | 汎用 |
355
+ | 179 | [scientific-data-profiling](scientific-data-profiling/SKILL.md) | ydata-profiling 自動 EDA・データ品質スコア (5 次元)・Great Expectations バリデーション | 汎用 |
356
+ | 180 | [scientific-geospatial-analysis](scientific-geospatial-analysis/SKILL.md) | GeoPandas 地理空間処理・Moran's I/LISA 空間自己相関・Kriging 補間・Folium 地図 | 汎用 |
357
+ | 181 | [scientific-network-visualization](scientific-network-visualization/SKILL.md) | NetworkX グラフ構築・Louvain/Leiden コミュニティ検出・中心性分析・PyVis インタラクティブ | 汎用 |
355
358
 
356
- ### C. 機械学習・モデリング(6 種)
359
+ ### C. 機械学習・モデリング(9 種)
357
360
 
358
- 教師あり学習・特徴量解釈・アクティブラーニング・AutoML・アンサンブル学習を担うスキル群。
361
+ 教師あり学習・特徴量解釈・アクティブラーニング・AutoML・アンサンブル学習・異常検知・因果 ML・モデル監視を担うスキル群。
359
362
 
360
363
  | # | Skill | 説明 | 参照 Exp |
361
364
  |---|---|---|---|
@@ -365,6 +368,9 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
365
368
  | 167 | [scientific-active-learning](scientific-active-learning/SKILL.md) | 不確実性サンプリング・QBC・バッチ AL・能動学習ループ・停止基準 | 汎用 |
366
369
  | 168 | [scientific-automl](scientific-automl/SKILL.md) | Optuna HPO・マルチモデル AutoML・自動特徴量エンジニアリング・AutoML レポート | 汎用 |
367
370
  | 169 | [scientific-ensemble-methods](scientific-ensemble-methods/SKILL.md) | XGBoost/LightGBM/CatBoost 比較・Stacking OOF・Voting・アンサンブル多様性 | 汎用 |
371
+ | 175 | [scientific-anomaly-detection](scientific-anomaly-detection/SKILL.md) | Isolation Forest/LOF/OCSVM アンサンブル異常検知・Autoencoder 異常・SPC 管理図 | 汎用 |
372
+ | 176 | [scientific-causal-ml](scientific-causal-ml/SKILL.md) | DoWhy 因果推論・EconML Double ML/Causal Forest・S/T/X-Learner メタラーナー | 汎用 |
373
+ | 177 | [scientific-model-monitoring](scientific-model-monitoring/SKILL.md) | データドリフト検出 (KS/PSI/Wasserstein)・性能劣化検出・A/B テスト統計 | 汎用 |
368
374
 
369
375
  ### D. 実験計画・プロセス最適化(2 種)
370
376
 
@@ -375,7 +381,7 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
375
381
  | 20 | [scientific-doe](scientific-doe/SKILL.md) | 田口直交表・CCD/Box-Behnken・ANOVA 因子効果・ベイズ最適化 | 汎用 |
376
382
  | 21 | [scientific-process-optimization](scientific-process-optimization/SKILL.md) | 応答曲面法 (ML-RSM)・パレート最適化・プロセスウィンドウ | 12, 13 |
377
383
 
378
- ### E. 信号・スペクトル・時系列(4 種)
384
+ ### E. 信号・スペクトル・時系列(5 種)
379
385
 
380
386
  波形・周波数領域・神経電気生理学の解析を担うスキル群。
381
387
 
@@ -385,6 +391,7 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
385
391
  | 23 | [scientific-biosignal-processing](scientific-biosignal-processing/SKILL.md) | ECG R波/HRV・EEG バンドパワー/ERP・EMG バースト・Poincaré | 08 |
386
392
  | 24 | [scientific-time-series](scientific-time-series/SKILL.md) | STL 分解・SARIMA 予測・変化点検出・FFT 周期解析・Granger 因果 | 汎用 |
387
393
  | 67 | [scientific-neuroscience-electrophysiology](scientific-neuroscience-electrophysiology/SKILL.md) | SpikeInterface/Kilosort4 スパイクソート・MNE EEG/ERP・NeuroKit2 HRV/EDA・脳機能結合 | 汎用 |
394
+ | 178 | [scientific-time-series-forecasting](scientific-time-series-forecasting/SKILL.md) | Prophet/NeuralProphet ML 予測・時系列特徴量エンジニアリング・バックテストフレームワーク | 汎用 |
388
395
 
389
396
  ### F. 生命科学・オミクス(28 種)
390
397
 
@@ -514,15 +521,16 @@ SATORI Skill (方法論・判断) ToolUniverse SMCP (データ取得・
514
521
  | 72 | [scientific-lab-data-management](scientific-lab-data-management/SKILL.md) | Benchling ELN/DNA 設計・DNAnexus PaaS・OMERO バイオイメージング・Protocols.io | 汎用 |
515
522
  | 164 | [scientific-crispr-design](scientific-crispr-design/SKILL.md) | CRISPR gRNA 設計・Cas9/Cas12a PAM 検索・オフターゲットスコアリング・sgRNA ライブラリ構築 | 汎用 |
516
523
 
517
- ### N. 科学プレゼンテーション・図式(3 種)
524
+ ### N. 科学プレゼンテーション・図式(4 種)
518
525
 
519
- 学会発表用スライド・ポスター・科学図式・インタラクティブダッシュボードのデザインを担うスキル群。
526
+ 学会発表用スライド・ポスター・科学図式・インタラクティブダッシュボード・再現可能レポートのデザインを担うスキル群。
520
527
 
521
528
  | # | Skill | 説明 | 参照 Exp |
522
529
  |---|---|---|---|
523
530
  | 45 | [scientific-presentation-design](scientific-presentation-design/SKILL.md) | 15 スライド構成テンプレート・tikzposter・matplotlib ワークフロー図・アクセシビリティ | 汎用 |
524
531
  | 73 | [scientific-scientific-schematics](scientific-scientific-schematics/SKILL.md) | CONSORT フロー図・NN アーキテクチャ図・パスウェイ図・TikZ/SVG | 汎用 |
525
532
  | 174 | [scientific-interactive-dashboard](scientific-interactive-dashboard/SKILL.md) | Streamlit/Dash/Panel 科学データダッシュボード・パラメータ探索 UI・リアルタイム解析 | 汎用 |
533
+ | 182 | [scientific-reproducible-reporting](scientific-reproducible-reporting/SKILL.md) | Quarto 科学文書・Jupyter Book 多章構成・Papermill パラメトリック実行・nbconvert 自動変換 | 汎用 |
526
534
 
527
535
  ### O. 研究計画・グラント・規制(3 種)
528
536
 
@@ -741,7 +749,10 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
741
749
  │ ├── scientific-pca-tsne/
742
750
  │ ├── scientific-symbolic-mathematics/
743
751
  │ ├── scientific-missing-data-analysis/
744
- └── scientific-advanced-visualization/
752
+ ├── scientific-advanced-visualization/
753
+ │ ├── scientific-data-profiling/
754
+ │ ├── scientific-geospatial-analysis/
755
+ │ └── scientific-network-visualization/
745
756
 
746
757
  │── [C] 機械学習・モデリング
747
758
  │ ├── scientific-ml-regression/
@@ -749,7 +760,10 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
749
760
  │ ├── scientific-feature-importance/
750
761
  │ ├── scientific-active-learning/
751
762
  │ ├── scientific-automl/
752
- └── scientific-ensemble-methods/
763
+ ├── scientific-ensemble-methods/
764
+ │ ├── scientific-anomaly-detection/
765
+ │ ├── scientific-causal-ml/
766
+ │ └── scientific-model-monitoring/
753
767
 
754
768
  │── [D] 実験計画・プロセス最適化
755
769
  │ ├── scientific-doe/
@@ -759,7 +773,8 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
759
773
  │ ├── scientific-spectral-signal/
760
774
  │ ├── scientific-biosignal-processing/
761
775
  │ ├── scientific-time-series/
762
- └── scientific-neuroscience-electrophysiology/
776
+ ├── scientific-neuroscience-electrophysiology/
777
+ │ └── scientific-time-series-forecasting/
763
778
 
764
779
  │── [F] 生命科学・オミクス
765
780
  │ ├── scientific-bioinformatics/
@@ -853,7 +868,8 @@ Skills は `.github/skills/` に配置されているため、Copilot が自動
853
868
  ├── [N] 科学プレゼンテーション・図式
854
869
  │ ├── scientific-presentation-design/
855
870
  │ ├── scientific-scientific-schematics/
856
- └── scientific-interactive-dashboard/
871
+ ├── scientific-interactive-dashboard/
872
+ │ └── scientific-reproducible-reporting/
857
873
 
858
874
  └── [O] 研究計画・グラント・規制
859
875
  ├── scientific-grant-writing/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nahisaho/satori",
3
- "version": "0.23.0",
3
+ "version": "0.24.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,296 @@
1
+ ---
2
+ name: scientific-anomaly-detection
3
+ description: |
4
+ 異常検知・外れ値検出スキル。Isolation Forest・LOF・
5
+ One-Class SVM・Autoencoder 異常検知・統計的工程管理 (SPC)・
6
+ 多変量異常検知・異常スコアリング・閾値最適化。
7
+ ---
8
+
9
+ # Scientific Anomaly Detection
10
+
11
+ 科学データにおける異常値・外れ値・異常パターンの検出と
12
+ 統計的工程管理 (SPC) パイプラインを提供する。
13
+
14
+ ## When to Use
15
+
16
+ - 実験データの外れ値を統計的に検出するとき
17
+ - 製造プロセスの異常監視 (SPC) をするとき
18
+ - 多変量データで異常パターンを発見するとき
19
+ - Autoencoder で複雑な異常を検出するとき
20
+ - 異常スコアの閾値を最適化するとき
21
+ - 複数手法のアンサンブル異常検知をするとき
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ## 1. 統計的異常検知アンサンブル
28
+
29
+ ```python
30
+ import numpy as np
31
+ import pandas as pd
32
+ from sklearn.ensemble import IsolationForest
33
+ from sklearn.neighbors import LocalOutlierFactor
34
+ from sklearn.svm import OneClassSVM
35
+ from sklearn.preprocessing import StandardScaler
36
+
37
+
38
+ def anomaly_detection_ensemble(X, contamination=0.05,
39
+ methods=None, threshold_vote=2):
40
+ """
41
+ 複数手法アンサンブル異常検知。
42
+
43
+ Parameters:
44
+ X: np.ndarray | pd.DataFrame — 入力データ
45
+ contamination: float — 想定異常率
46
+ methods: list[str] | None — 使用手法 ("iforest", "lof", "ocsvm")
47
+ threshold_vote: int — 最低投票数 (多数決)
48
+ """
49
+ if methods is None:
50
+ methods = ["iforest", "lof", "ocsvm"]
51
+
52
+ if isinstance(X, pd.DataFrame):
53
+ feature_names = X.columns.tolist()
54
+ X_arr = X.values
55
+ else:
56
+ feature_names = [f"f{i}" for i in range(X.shape[1])]
57
+ X_arr = X
58
+
59
+ scaler = StandardScaler()
60
+ X_scaled = scaler.fit_transform(X_arr)
61
+
62
+ results = {}
63
+ predictions = {}
64
+
65
+ for method in methods:
66
+ if method == "iforest":
67
+ model = IsolationForest(
68
+ contamination=contamination, random_state=42, n_jobs=-1)
69
+ preds = model.fit_predict(X_scaled)
70
+ scores = -model.score_samples(X_scaled)
71
+ elif method == "lof":
72
+ model = LocalOutlierFactor(
73
+ n_neighbors=20, contamination=contamination)
74
+ preds = model.fit_predict(X_scaled)
75
+ scores = -model.negative_outlier_factor_
76
+ elif method == "ocsvm":
77
+ model = OneClassSVM(kernel="rbf", nu=contamination)
78
+ preds = model.fit_predict(X_scaled)
79
+ scores = -model.decision_function(X_scaled)
80
+ else:
81
+ continue
82
+
83
+ is_anomaly = (preds == -1).astype(int)
84
+ predictions[method] = is_anomaly
85
+ results[method] = {
86
+ "n_anomalies": int(is_anomaly.sum()),
87
+ "scores": scores
88
+ }
89
+
90
+ # アンサンブル多数決
91
+ vote_matrix = np.column_stack(list(predictions.values()))
92
+ ensemble_votes = vote_matrix.sum(axis=1)
93
+ ensemble_anomaly = (ensemble_votes >= threshold_vote).astype(int)
94
+
95
+ result_df = pd.DataFrame(X_arr, columns=feature_names)
96
+ for method, preds in predictions.items():
97
+ result_df[f"anomaly_{method}"] = preds
98
+ result_df["ensemble_votes"] = ensemble_votes
99
+ result_df["is_anomaly"] = ensemble_anomaly
100
+
101
+ n_ens = ensemble_anomaly.sum()
102
+ print(f"Anomaly Ensemble ({len(methods)} methods, vote≥{threshold_vote}): "
103
+ f"{n_ens}/{len(X_arr)} anomalies ({n_ens/len(X_arr)*100:.1f}%)")
104
+
105
+ for m, r in results.items():
106
+ print(f" {m}: {r['n_anomalies']} anomalies")
107
+
108
+ return result_df, results
109
+ ```
110
+
111
+ ## 2. Autoencoder 異常検知
112
+
113
+ ```python
114
+ def autoencoder_anomaly(X, encoding_dim=8, epochs=100,
115
+ threshold_percentile=95):
116
+ """
117
+ Autoencoder ベース異常検知。
118
+
119
+ Parameters:
120
+ X: np.ndarray — 入力データ (正常データで学習)
121
+ encoding_dim: int — 潜在次元数
122
+ epochs: int — 学習エポック数
123
+ threshold_percentile: float — 再構成誤差の閾値パーセンタイル
124
+ """
125
+ import torch
126
+ import torch.nn as nn
127
+ from torch.utils.data import DataLoader, TensorDataset
128
+
129
+ scaler = StandardScaler()
130
+ X_scaled = scaler.fit_transform(X)
131
+ n_features = X_scaled.shape[1]
132
+
133
+ # Autoencoder 定義
134
+ class AE(nn.Module):
135
+ def __init__(self):
136
+ super().__init__()
137
+ self.encoder = nn.Sequential(
138
+ nn.Linear(n_features, 64), nn.ReLU(),
139
+ nn.Linear(64, 32), nn.ReLU(),
140
+ nn.Linear(32, encoding_dim))
141
+ self.decoder = nn.Sequential(
142
+ nn.Linear(encoding_dim, 32), nn.ReLU(),
143
+ nn.Linear(32, 64), nn.ReLU(),
144
+ nn.Linear(64, n_features))
145
+
146
+ def forward(self, x):
147
+ z = self.encoder(x)
148
+ return self.decoder(z)
149
+
150
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
151
+ model = AE().to(device)
152
+ optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
153
+ criterion = nn.MSELoss()
154
+
155
+ X_tensor = torch.FloatTensor(X_scaled).to(device)
156
+ dataset = TensorDataset(X_tensor, X_tensor)
157
+ loader = DataLoader(dataset, batch_size=64, shuffle=True)
158
+
159
+ model.train()
160
+ for epoch in range(epochs):
161
+ total_loss = 0
162
+ for batch_x, _ in loader:
163
+ optimizer.zero_grad()
164
+ recon = model(batch_x)
165
+ loss = criterion(recon, batch_x)
166
+ loss.backward()
167
+ optimizer.step()
168
+ total_loss += loss.item()
169
+
170
+ # 再構成誤差
171
+ model.eval()
172
+ with torch.no_grad():
173
+ recon = model(X_tensor).cpu().numpy()
174
+
175
+ recon_errors = np.mean((X_scaled - recon) ** 2, axis=1)
176
+ threshold = np.percentile(recon_errors, threshold_percentile)
177
+ is_anomaly = (recon_errors > threshold).astype(int)
178
+
179
+ print(f"Autoencoder Anomaly: threshold={threshold:.4f} (P{threshold_percentile}), "
180
+ f"{is_anomaly.sum()} anomalies")
181
+ return {"reconstruction_error": recon_errors, "threshold": threshold,
182
+ "is_anomaly": is_anomaly, "model": model}
183
+ ```
184
+
185
+ ## 3. 統計的工程管理 (SPC)
186
+
187
+ ```python
188
+ def spc_control_chart(data, column, subgroup_size=1,
189
+ chart_type="individuals"):
190
+ """
191
+ SPC 管理図 (X-bar, R, Individuals-MR)。
192
+
193
+ Parameters:
194
+ data: pd.DataFrame | pd.Series — 時系列データ
195
+ column: str — 対象カラム名
196
+ subgroup_size: int — サブグループサイズ
197
+ chart_type: str — "individuals" / "xbar_r" / "cusum"
198
+ """
199
+ import matplotlib.pyplot as plt
200
+
201
+ if isinstance(data, pd.DataFrame):
202
+ values = data[column].values
203
+ else:
204
+ values = data.values
205
+
206
+ if chart_type == "individuals":
207
+ x_bar = np.mean(values)
208
+ mr = np.abs(np.diff(values))
209
+ mr_bar = np.mean(mr)
210
+ d2 = 1.128 # d2 for n=2
211
+
212
+ ucl = x_bar + 3 * (mr_bar / d2)
213
+ lcl = x_bar - 3 * (mr_bar / d2)
214
+
215
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True)
216
+
217
+ # Individuals chart
218
+ ax1.plot(values, "b-o", markersize=3)
219
+ ax1.axhline(x_bar, color="g", linestyle="-", label=f"CL={x_bar:.3f}")
220
+ ax1.axhline(ucl, color="r", linestyle="--", label=f"UCL={ucl:.3f}")
221
+ ax1.axhline(lcl, color="r", linestyle="--", label=f"LCL={lcl:.3f}")
222
+
223
+ # OOC points
224
+ ooc = np.where((values > ucl) | (values < lcl))[0]
225
+ if len(ooc) > 0:
226
+ ax1.scatter(ooc, values[ooc], c="red", s=50, zorder=5,
227
+ label=f"OOC ({len(ooc)})")
228
+ ax1.set_title("Individuals Chart")
229
+ ax1.legend(fontsize=8)
230
+
231
+ # Moving Range chart
232
+ mr_ucl = 3.267 * mr_bar
233
+ ax2.plot(mr, "b-o", markersize=3)
234
+ ax2.axhline(mr_bar, color="g", linestyle="-")
235
+ ax2.axhline(mr_ucl, color="r", linestyle="--")
236
+ ax2.set_title("Moving Range Chart")
237
+
238
+ plt.tight_layout()
239
+ path = "spc_control_chart.png"
240
+ plt.savefig(path, dpi=150, bbox_inches="tight")
241
+ plt.close()
242
+
243
+ print(f"SPC Individuals: CL={x_bar:.3f}, UCL={ucl:.3f}, "
244
+ f"LCL={lcl:.3f}, OOC={len(ooc)}")
245
+ return {"cl": x_bar, "ucl": ucl, "lcl": lcl,
246
+ "ooc_indices": ooc, "fig": path}
247
+
248
+ elif chart_type == "cusum":
249
+ target = np.mean(values)
250
+ se = np.std(values)
251
+ k = 0.5 * se
252
+ h = 5 * se
253
+
254
+ cusum_pos = np.zeros(len(values))
255
+ cusum_neg = np.zeros(len(values))
256
+
257
+ for i in range(1, len(values)):
258
+ cusum_pos[i] = max(0, cusum_pos[i-1] + (values[i] - target) - k)
259
+ cusum_neg[i] = min(0, cusum_neg[i-1] + (values[i] - target) + k)
260
+
261
+ fig, ax = plt.subplots(figsize=(12, 5))
262
+ ax.plot(cusum_pos, "b-", label="CUSUM+")
263
+ ax.plot(cusum_neg, "r-", label="CUSUM-")
264
+ ax.axhline(h, color="b", linestyle="--", alpha=0.5)
265
+ ax.axhline(-h, color="r", linestyle="--", alpha=0.5)
266
+ ax.set_title("CUSUM Control Chart")
267
+ ax.legend()
268
+
269
+ path = "cusum_chart.png"
270
+ plt.savefig(path, dpi=150, bbox_inches="tight")
271
+ plt.close()
272
+
273
+ print(f"CUSUM: target={target:.3f}, k={k:.3f}, h={h:.3f}")
274
+ return {"target": target, "k": k, "h": h,
275
+ "cusum_pos": cusum_pos, "cusum_neg": cusum_neg, "fig": path}
276
+ ```
277
+
278
+ ---
279
+
280
+ ## パイプライン統合
281
+
282
+ ```
283
+ eda-correlation → anomaly-detection → ml-classification
284
+ (探索的解析) (外れ値検出) (モデリング)
285
+ │ │ ↓
286
+ data-profiling ────────┘ model-monitoring
287
+ (データ品質) (モデル監視)
288
+ ```
289
+
290
+ ## パイプライン出力
291
+
292
+ | ファイル | 説明 | 次スキル |
293
+ |---------|------|---------|
294
+ | `anomaly_ensemble.csv` | アンサンブル異常検知結果 | → EDA |
295
+ | `autoencoder_anomaly.json` | AE 異常スコア | → reporting |
296
+ | `spc_control_chart.png` | SPC 管理図 | → process-optimization |