| name | study-note |
| description | analysis リポで、テーマを与えたときに学習者目線のチュートリアル marimo ノートを
`notebooks/tutorials/{NN}_{slug}.py` に作成する。数学・統計に特化(統計検定準1級
〜大学院初年度レベル)。スキル配下の `references/sample_notebook.py` と
`references/statistics_tutorial_style.md` を SSOT として、章立て・表での用語定義・
「結果の読み方」セル・練習問題までを再現性持って書くためのスキル。
トリガー: 「ノート作って」「<テーマ> の解説ノート」「study-note」「$study-note」
「主成分分析のチュートリアル」「<統計手法> を marimo で」など。analysis リポで
テーマ学習・概念整理の依頼を受けた場合は積極的に起動する(過剰起動より起動忘れの方が問題)。
|
study-note — 学習者目線のチュートリアルノート作成スキル
analysis リポ専用スキル。/workspace/analysis/notebooks/tutorials/ 配下に、与えられた
テーマ(主成分分析 / マルコフ連鎖 / ベイズ推論 など)を学習者目線で深く掘り下げる
marimo ノートを作る。
何のためのスキルか
目的: ユーザーが「○○について学びたい」と言ったときに、本スキル配下の
references/sample_notebook.py で実演されている「型」と、
references/statistics_tutorial_style.md のテーマ別
設定例を使い、8〜10 章相当に展開した濃いチュートリアルノートを 再現性を持って 出力する。
ノートの読者像: 統計検定準1級〜大学院初年度レベルの学習者。数式の定義は理解できるが、
「なぜその式になるか」「実装すると何が見えるか」「直感はどうか」を補強したい層。
スキルの境界:
- ✅ 数学・統計テーマ(確率分布、推定、検定、回帰、多変量、確率過程、ベイズ など)
- ✅ marimo ノート 1 本(本スキルのサンプル骨格 ~340 行を 8〜10 章相当に展開した規模)
- ❌ 機械学習工学・MLOps 系(他スキルの守備範囲)
- ❌ 1 ノート内で複数テーマを混ぜる(分割する)
骨格 SSOT — references/sample_notebook.py
本スキルが要求する 章立て / セル構造 / リズム / 数式段階展開 / 図の規約 /
練習問題の書き方 は全て references/sample_notebook.py で実演されている。
スキル起動時に必ず先頭から読み、「型」を頭に入れてから生成に入る。
スタイル SSOT — references/statistics_tutorial_style.md
統計チュートリアルとしての説明順、テーマ別のカノニカル設定、章立ての観点は
references/statistics_tutorial_style.md を参照する。このスキルは 実行時に analysis リポの
study/ ディレクトリや保存済み記事を読みに行かない。リポジトリ側の資料は変わる可能性があるため、
ノート品質を決める参照情報はスキル配下の references/ に閉じる。
marimo 作法 SSOT — ../../../shared/rules/marimo-authoring.md
marimo 固有の実行・表示・セル変数規約は
../../../shared/rules/marimo-authoring.md を SSOT とする。
スキル起動時はサンプル骨格とあわせて必ず読み、ノート生成・修正・レビューで発見した
marimo 固有の落とし穴はこのルールへ追記して知見を蓄積する。
サンプルは「コインの最尤推定」を題材にした 4 章相当の最小構成 (約450 行)。実テーマでは
8〜10 章まで広げ、解析的な答え合わせ・診断・予測まで含めるため、サンプルの 2〜3 倍
規模 (~700〜1000 行) が標準着地点になる。
配置と命名
| 項目 | 規約 |
|---|
| 配置 | /workspace/analysis/notebooks/tutorials/{NN}_{slug}.py |
連番 {NN} | 既存 ls /workspace/analysis/notebooks/tutorials/*.py の最大番号 + 1 (ゼロ埋め 2 桁) |
{slug} | 英語スネークケース(pca, markov_chain, survival_analysis) |
| 言語 | 日本語(変数名・関数名・コメント以外の説明テキストは全て日本語) |
連番は安定識別子。リネームしない。tutorials/ 配下に既にあるノートはユーザーの資産であり、
本スキルは 新規追加のみ を行う(既存ノートを書き換えない)。
参考素材の扱い
参照する素材はスキル配下に置く。通常は references/sample_notebook.py と
references/statistics_tutorial_style.md だけを読む。analysis リポ内の study/ や既存ノートを
「品質判断の SSOT」として読まない。
追加の参考資料が必要な場合は、次の順で扱う:
- ユーザーが明示的に渡した資料だけを読む。
- 外部ソースを使う必要がある場合は一次情報・教科書相当の安定資料を優先し、最終章「参考リンク」に明記する。
- 継続的に使う価値がある知見は、リポジトリ側に散らさず、次回以降のために本スキルの
references/ へ要約として追加する。
ノート構造の章立てテンプレート(8〜10 章)
サンプル骨格を実テーマに展開するときの章立て指針。テーマに応じて取捨選択する。
| 章 | 役割 | 内容のヒント |
|---|
| (前文) | 動機 → カノニカル比喩 → 章一覧 → 前提知識 | 4 要素を順に: ①動機 (この概念がなぜ必要か) → ②ノート全体で反復するカノニカル比喩 → ③章別テーブルで予告 → ④「なお、本稿では○○の知識を仮定します。リンク先を先に参照してください」 |
| 1 | データ生成 / 設定 | 真値を自分で決めて生成する(後で答え合わせできるよう)。登場変数を表で定義 |
| 2 | モデル定義 / 数式 | 数式は段階展開。表でパラメータ意味を定義してから式 |
| 3 | コア概念の数式読み解き | カーネル / 共役性 / 対数尤度などの「裏側」を式変形で見せる |
| 4 | 結果の診断・収束確認 | 数値サマリ + 可視化、各指標の 意味と読み方 を表で |
| 5 | 解析解 / 既知結果との照合 | 答え合わせ。一致しない場合の原因も提示 |
| 6 | 点推定値・要約量 | 平均 / モード / MAP など、定義 → 式 → 数値 の順 |
| 7 | 予測・応用 | 学習成果を 1 つ「外向きに使ってみる」 |
| 8 | アルゴリズムの中身 / 派生形 | MCMC のメトロポリス、共役の他の例など |
| 9 | 練習問題 + 略解 | 2〜3 問、(1)(2)(3) で段階化(基礎 → 応用)。略解は 導出過程・式変形まで丁寧に 書く(答えだけは禁止) |
| 10 | 次のステップ + 参考リンク | 自分で動かす提案 + 関連トピック + 出典 |
8 章で十分なテーマもある(回帰のような単一概念)。10 章まで使うのは過程系(ブラウン運動、
マルコフ連鎖など中身が階層的なテーマ)。テーマに応じて取捨選択するが、前文の比喩 + 章一覧
テーブル、練習問題、次のステップ の 3 つは省略しない。
コードセルと markdown セルの並べ方
各章は概ね次のリズムで進む:
1. 説明セル (mo.md) ← 用語の表 → 段階展開した数式 → コードの読み方
2. コードセル ← 計算 / プロット
3. 「結果の読み方」セル ← @app.cell(hide_code=True) で hide、表で各列・各要素を解説
「結果の読み方」セルは必ず挟む。コードの出力(数値サマリ、プロット、テーブル)が何を
意味するのか、何を確認すれば健全か、駄目な場合のパターンを表で言語化する。これが学習者
目線にする最大のキー。サンプル骨格の各「結果の読み方」セルを参考にする。
文章規律
本スキルは references/statistics_tutorial_style.md の型を反映している。
-
前文に「前提知識・参考リンク」のパラグラフ: ノート冒頭(章立てテーブルの直後)に
「なお、本稿では○○の知識を仮定します。○○については ××(リンク) を先に参照してください」
の形式で、必要な前提を明示する。読者が前提不足のまま進むのを防ぐ。
-
1 ノートに 1 つのカノニカル比喩: 章頭にバラバラの比喩を置くのではなく、ノート全体で
1 つの比喩(マルコフ連鎖=天気、主成分分析=商品の多次元評価、判別分析=スパムメール判別 など)を
選び、複数章で 繰り返し参照 して反復強化する。比喩は前文に最初に提示する。
-
章末ナビゲーション句: 各章の最後に「では、次節では○○を扱います」「ということで、
ここまでで○○が分かりました。続けて△△へ進みます」のような 1〜2 文を必ず置く。流れと現在地を
読者に示す。
-
用語の 3 段階定義: 用語の初出時は「言葉での説明 → 括弧で別名(英語名 / 略語 /
別表記) → 数式定義」の 3 段階で出す。例:
非復元単純無作為抽出(simple random sampling without replacement、SRSWOR、取り出した
標本をもとに戻さずに次の標本を取り出すサンプリング法)を考える。
これに加え、章で扱う変数群は表で再掲する(下記 §5 参照)。
-
変数の表組み: 数式の中の文字を裸出ししない:
| 変数 | 型 | 意味 |
|---|---|---|
| `p_true` | `float` | 真のパラメータ(現実では未知) |
-
2 つの考え方を比較するときは表: 頻度論 vs ベイズ、MLE vs MAP vs Bayes、
旧基準 vs 新基準 など、列で観点を揃えた 2-3 列の比較表 を使う。
-
結論を冒頭、根拠は後(reporting.md §1)。各章の冒頭 1 文で「この章で言いたいこと」を
述べてから展開する。
-
帰納的に進める: 抽象的な定義から入らず、具体例 → 図 → 直感の言語化 → 定義 → 数式
の順で進める。
-
「なぜそうなるか」を必ず書く: 数式の結果だけでなく、その式が出てくる動機(共役性なら
「正規化定数の積分を回避できるから」)を文で書く。
数式規律
- 図 → 言語 → 式 の 3 段階順序: 数式は単独で出さない。図(または具体例)で直感を
作る → 「上の図から分かるように」と言語化 → 数式で形式化 の順序を守る。
- 段階展開: 「尤度 → 対数尤度 → 微分 → 解」のように、1 行で結論にジャンプしない。
サンプル §2-§3 (対数尤度の導出 → 微分して MLE) が範例。
- 記号の意味は直前の表で: $p, \theta, y, n, k$ といった記号を初出時に表で定義。
- 比例式 $\propto$ を使うときは「正規化定数を消した」と必ず明示。
- boxed: 各章の 結論の式 は 1 つだけ
\boxed{...} で囲む(乱用しない)。
- MathJax の二重
$ は段落中で 1 回: 式が長いなら $$ ... $$ ブロックに移す。
marimo コード規律
サンプル骨格 (references/sample_notebook.py) の構造をそのまま踏襲する。要点だけ抜粋。
App 初期化
import marimo
__generated_with = "0.23.5"
app = marimo.App(
width="medium",
css_file="style.css",
html_head_file="head.html",
)
style.css と head.html は生成先ディレクトリ (notebooks/tutorials/) に既存ファイルがあれば
それを参照する。無ければ css_file / html_head_file 引数自体を省く(marimo はオプション扱い)。
これらは analysis リポ側のユーザー資産であり、本スキルは生成・上書きしない。
import セル
@app.cell
def _():
import warnings
warnings.filterwarnings("ignore")
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
from scipy import stats
rng = np.random.default_rng(42)
return np, plt, rng, stats
japanize_matplotlib は 必須(import するだけで日本語フォントが効く。# noqa: F401 必須)。
markdown セルの書き方
- 説明セルは
@app.cell(hide_code=True) でデコレートし、mo.md(r"""...""") で囲う
- raw string (
r""") を使う(\ を含む LaTeX を素直に書ける)
- セル内で
mo を引数に取り、return を空にする
コードセル
- 1 セルに 1 つの目的(計算 or プロット)。混在させない
- 結果は 必ず変数に bind して return(下流の章で再利用するため)
- print は 数値要約用に 1〜3 行まで。可視化は plt で
図の規約
_fig, _ax = plt.subplots(figsize=(8, 4)) で明示的に Figure を作る (_ プレフィックス必須)
_fig.tight_layout() の直後に _fig または _ax / _axes[...] を裸の式として置く
(marimo はセルの最後の式を表示するため)
- 凡例・軸ラベルは日本語、
_ax.legend() を忘れない
- 真値・解析解との比較は色 / 線種で区別(青曲線 + 赤破線 + 緑点線、など)
- セル末尾は figure 変数を return しない。表示用 Figure はセルローカル
_fig のまま、
return の直前に _fig を置く
_ プレフィックスのルール (重要、marimo セル間衝突予防)
marimo は 同名の非 _ グローバル変数を複数セルが定義するとエラー (The variable X was defined by another cell)。_ で始まる変数のみセルローカル扱い。
セル内のみで使う一時変数は 必ず _ プレフィックス を付ける:
| カテゴリ | 例 |
|---|
| 図 / 軸 | _fig, _ax, _axes |
| グリッド / 軸範囲 | _x_grid, _sj_grid, _sh_mean |
| 予測値 / 中間計算 | _pred, _eta_grid, _prob_mle, _lam_hat |
| ループ変数 (zip / for) | _name, _true, _est, _se, _t, _z |
| ヘルパー関数 (セル内のみ) | _logistic, _neg_log_lik, _grad |
| ジッター / 一時 RNG | _jitter, _r |
セル間で受け渡す変数のみ非 _ にして return で渡す (X, beta_ols, passed, mock_count, etc.)。
import セル / データ生成セルなど return される変数群は重複しない ように設計する (同じ n を 2 セルで定義してしまうと衝突)。
フロー
ユーザーから「○○のノート作って」を受けたら、以下を順に実行する。
Step 1. 入口確認
- テーマを 1 文で確認(必要なら復唱)
- 既存連番を
ls /workspace/analysis/notebooks/tutorials/*.py で取得し、次番号と slug を決める
- 同テーマのノートが既にあれば 新規作成ではなく既存改訂か をユーザーに確認する。無ければ自律的に続行する
Step 2. スキル内 references の再読込
references/sample_notebook.py を読む(コードセルとそれぞれの「結果の読み方」セルの
リズムを思い出す)。本スキルが従う 規律の SSOT はサンプルである
references/statistics_tutorial_style.md を読み、対象テーマのカノニカル設定・章立て観点を拾う
Step 3. 参考素材の確認
- 原則としてスキル内 references と教科書知識で章立てを組む
- ユーザーが資料を明示した場合だけ、その資料を追加で読む
- 追加資料から得た再利用価値のある型は、ノート作成後に
references/ へ要約追記する候補として記録する
Step 4. 章立て起案
- 「ノート構造の章立てテンプレート」を基に、テーマに応じて章を取捨選択(8〜10 章)
- 章一覧テーブル(前文に入れる予告版)をユーザーに提示する
- ユーザーが明示的に「確認してから進めて」と言っている場合だけ待機する。通常は章立てを提示した上で、
そのまま実装に進む(章立て無しでコードを書かない)
Step 5. セル単位で実装
- 章ごとに「説明セル → コードセル → 結果の読み方セル」を書く
- 各章を書き終えたら 1 度 marimo で動作確認(レイアウト・figure・テーブルが崩れないか)
- 章をまたいだ変数依存は marimo のセル return で表現する
Step 6. 通し動作確認 (= 全セル成功するまで完了としない)
重要: 「python ast.parse syntax OK」で完了としない。marimo で全セルが run all で成功するまで が完了条件。session ファイル notebooks/tutorials/__marimo__/session/<file>.py.json の error 出力が 0 件 になることを確認する。
6-1. marimo を再起動して該当ノートを開く
gateway --project analysis run marimo.restart
ブラウザで該当ノートを開いて run all。marimo はリアクティブに全セルを評価する。
session JSON は過去実行の残骸が残ることがあるため、修正後は必ず run all をやり直してから次へ進む。
6-2. session JSON を scan してエラー件数を確認
import json
d = json.load(open("notebooks/tutorials/__marimo__/session/<file>.py.json"))
errs = [(i, c["id"], o.get("evalue", ""))
for i, c in enumerate(d["cells"])
for o in c.get("outputs", [])
if isinstance(o, dict) and o.get("type") == "error"]
print(f"errors: {len(errs)}")
for i, eid, ev in errs[:5]:
print(f" cell #{i} id={eid}: {ev[:200]}")
errors: 0 でなければ修正してもう一度 6-1 から。ファイル本体では修正済みに見えるのに
session JSON だけ古いエラーを出す場合は、marimo を restart して run all し直す。
6-3. エラー種別ごとの対処
| エラー | 対処 |
|---|
ModuleNotFoundError: No module named 'X' | §6-5 の image 拡張ルートで X を追加 → restart |
The variable X was defined by another cell | セル内一時変数を _ プレフィックス化 (§marimo コード規律「_ プレフィックスのルール」参照) |
Compilation failed ... Python.h: No such file or directory | PyTensor C++ 拡張のコンパイル失敗。import セル冒頭に os.environ.setdefault("PYTENSOR_FLAGS", "cxx=") (01_getting_started.py の import セルが範例) |
| その他 (TypeError / NameError / IndexError 等) | コードのロジックバグ。修正して 6-1 に戻る |
6-4. 行数 / 構成の最終チェック
- 行数 (サンプル骨格 ~340 行を 8〜10 章相当に展開した規模、~700〜1000 行が目安)
- 練習問題に略解を書いたか、次のステップが書かれているか
- 最新 session JSON で
type=error の出力が 0 件
6-5. marimo image を育てる方針 (不足ライブラリの追加ルート)
不足ライブラリは 必ず追加 する。「動かないまま完了報告」は禁止。2 つのルート:
| ルート | 場所 | 反映方法 | 用途 |
|---|
| 永続的 (推奨) | infra/images/devtools/marimo-requirements.txt | infra リポで PR → merge → image rebuild | 全ノートで恒常的に使う library |
| 一時的 | analysis/notebooks/tutorials/requirements-marimo.txt | gateway --project analysis run marimo.restart で entrypoint が読み込む | このノート限定の試行 |
devtools image には現状以下が入っている (執筆時点):
numpy / scipy / pandas / polars / pyarrow / duckdb / statsmodels / scikit-learn / matplotlib / seaborn / plotly / altair / japanize-matplotlib / pymc / arviz / openpyxl / xlsxwriter / sqlalchemy / requests / beautifulsoup4 / lxml / tqdm / tabulate
これら 以外 を使うときに追加する。infra/images/devtools/marimo-requirements.txt を最新の SSOT として参照し、毎回ここを開いて確認する。
Step 7. 完了報告
- ノートのパス、章数、行数、使ったスキル内 references、実行確認結果を 1 メッセージで報告
- analysis リポでの commit / PR はユーザー判断(本スキルは PR を自動で出さない)
完了条件
ノート 1 本が以下を満たした時点で完了:
アンチパターン
- ❌ 抽象的な定義から始める (帰納的に「具体例 → 図 → 直感 → 定義 → 数式」の順序で書かない)
- ❌ 用語の説明なしに数式を書き始める
- ❌ 用語を初出時に 1 単語 (太字のみ) で済ませる (3 段階定義: 言葉 → 別名括弧 → 数式 を守らない)
- ❌ 数式を裸出しする (図 → 言語 → 式 の順序を踏まない)
- ❌ ベイズの定理を 1 行で「事後 = 尤度 × 事前 / エビデンス」と結論だけ書く(段階展開しない)
- ❌ コードの出力をそのままユーザーに見せる(「結果の読み方」セルがない)
- ❌ 章ごとに別の比喩を投入する (1 ノート 1 カノニカル比喩を反復強化しない)
- ❌ 各章末にナビゲーション句がない (流れと現在地が読者に伝わらない)
- ❌ 前文に前提知識・参考リンクのパラグラフがない
- ❌ 練習問題を 1 問だけにする / 「考えてみよう」で終わらせる (略解がない、(1)(2)(3) 段階化がない)
- ❌ 練習問題の略解を答えだけにする (式変形・導出過程を書かない)
- ❌
japanize_matplotlib を入れずに figure を書く(凡例の日本語が豆腐になる)
- ❌ 外部記事やユーザー資料の文章をコピペする (著作権 + ノートの個性を殺す。型 だけ参考にして
独自の例で書く)
- ❌ 1 ノートに複数テーマ(主成分分析 + 因子分析 など)を詰める(分割する)
- ❌ marimo セルの
figure 変数を return する(余計な変数依存になる)
- ❌ サンプル骨格より章数・密度が大幅に少ないノートで完了を主張する(再設計を検討)
- ❌ analysis リポ既存の特定ノートを SSOT として参照する(本スキルは自己完結が原則。
参照する型はスキル内
references/ のみ)
- ❌ analysis リポの
study/ ディレクトリや保存済み記事を実行時の参考資料として読む
- ❌
marimo で実行確認しないまま完了報告 (Step 6 を syntax check で代替しない、最新 session JSON で error 0 件確認が必須)
- ❌ セル内一時変数を
_ プレフィックス無しで再利用 (fig, ax, ループ変数 name/true/est/se 等が複数セルに跨ると marimo は The variable X was defined by another cell エラーを出す。analysis #5 の事例)
- ❌
ModuleNotFoundError を放置 (不足ライブラリは infra/images/devtools/marimo-requirements.txt か analysis/notebooks/tutorials/requirements-marimo.txt に追加して gateway --project analysis run marimo.restart、Step 6-5 参照)
関連ルール
Skill Pipeline
このスキルは独立完結型:
- 前段: ユーザーの「○○について学びたい」発言、または
$study-note <テーマ> 直接呼び出し
- 内部呼び出し: なし
- 後段: ユーザーが満足したらノートを git commit / PR(本スキル外、ユーザー判断)