ワンクリックで
statistical-analysis
Hypothesis testing, power analysis, ablation design, and multiple comparison corrections for ML experiment evaluation.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Hypothesis testing, power analysis, ablation design, and multiple comparison corrections for ML experiment evaluation.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
回顾最近 N 天的 Claude Code 使用记录——扫描原始会话数据,按主题分组汇总"我都做了什么",并从个人操作系统视角输出模式、风险与增删建议。当用户说 /recap、"看看我这几天做了什么"、"回顾一下我最近的会话"、"这两天我用 claude 干了啥"、"活动回顾" 时使用。
Wenn es um /anpassen in diesem Spezialbereich geht: prüft Frist, Form, Zuständigkeit, Rechtsweg und Sofortmaßnahmen; liefert eine Fristen- und Risikoampel mit Sofortschritten.
Use when wiring up or switching between China-domestic LLM providers (DeepSeek, Doubao/Volc Ark, Qwen/DashScope, MiniMax). Provides OpenAI-compatible adapter pattern, env-var contracts, fallback strategy, cost guardrails, and minimum verifications before declaring integration done.
Consult an independent GPT-5.6 reviewer (Terra by default; Sol on request, for a stronger but costlier review), matched to your current reasoning-effort level. Use before committing to an interpretation or a substantial piece of writing/analysis, when stuck (recurring errors, a non-converging approach, results that do not fit), when considering a change of approach, or when you believe a task is complete and want a check before finalizing. Not a co-implementer — read-only advisory only, does not edit files.
QA the omo Codex Light edition (lazycodex / packages/omo-codex) itself, in strict isolation so ONLY our plugin is exercised, never the user's real ~/.codex. The first-party method drives the real `codex app-server` against an isolated CODEX_HOME plus a LOCAL mock model (no real API call), and proves a plugin hook fired by asserting hook/started + hook/completed notifications. Also: isolated install verification, per-component hook probes, a tmux TUI smoke, and runtime log observation (RUST_LOG / logs SQLite / /debug-config). Ships tested helper scripts each with a --self-test. Use whenever someone changes anything under packages/omo-codex or wants to QA, smoke-test, verify, or debug the Codex plugin, its hooks/components, the installer/config.toml, the app-server flow, or the Codex TUI. Triggers: codex qa, qa codex, codex-qa, test codex plugin, verify codex hook, codex app-server, lazycodex qa, isolated CODEX_HOME, prove codex hook fired, codex tui test.
MANDATORY for every coding agent (Claude Code, Codex, or any other) on every change-set — every applicable source file the agent creates or updates MUST start with the project's copyright/authorship header (file overview + exact author line). Use automatically whenever writing a new file or editing an existing one; do not wait to be asked. Covers JS/TS/TSX/CJS/MJS, Python, shell, and CSS. Includes the audit script to verify repo-wide compliance.
| name | statistical-analysis |
| description | Hypothesis testing, power analysis, ablation design, and multiple comparison corrections for ML experiment evaluation. |
| Scenario | Test | Assumptions | When to Use |
|---|---|---|---|
| Compare 2 models, paired runs | Paired permutation test | None (non-parametric) | Default choice for ML |
| Compare 2 models, unpaired | Mann-Whitney U | Independent samples | Different datasets/splits |
| Compare 2 means, normal data | Paired t-test | Normality, paired | Large N (>30) runs |
| Compare >2 models | Friedman test | Paired, ordinal | Ranking across datasets |
| Post-hoc after Friedman | Nemenyi test | Same as Friedman | Pairwise model comparison |
| Compare proportions | McNemar's test | Paired binary | Classification correct/incorrect |
| Correlation of metrics | Spearman's rho | Monotonic relationship | Rank-based, robust to outliers |
| Effect of hyperparameters | ANOVA / Kruskal-Wallis | See specific test | Factorial ablation design |
| Situation | Method | N Seeds |
|---|---|---|
| Metric approximately normal | t-interval | >= 5 |
| Unknown distribution | Bootstrap percentile | >= 10 |
| Small N, heavy tails | BCa bootstrap | >= 15 |
| Proportion (accuracy) | Wilson interval | Any |
import numpy as np
from scipy import stats
def bootstrap_ci(
data: np.ndarray,
statistic=np.mean,
n_bootstrap: int = 10_000,
confidence: float = 0.95,
method: str = "percentile",
seed: int = 42,
) -> tuple[float, float, float]:
"""Compute bootstrap confidence interval.
Args:
data: 1D array of observations (e.g., accuracy per seed).
statistic: Function to compute on each resample.
method: 'percentile' or 'bca'.
Returns:
(point_estimate, lower, upper)
"""
rng = np.random.default_rng(seed)
observed = statistic(data)
n = len(data)
boot_stats = np.array([
statistic(rng.choice(data, size=n, replace=True))
for _ in range(n_bootstrap)
])
alpha = 1 - confidence
if method == "percentile":
lower = np.percentile(boot_stats, 100 * alpha / 2)
upper = np.percentile(boot_stats, 100 * (1 - alpha / 2))
elif method == "bca":
# Bias-correction
z0 = stats.norm.ppf(np.mean(boot_stats < observed))
# Acceleration (jackknife)
jackknife = np.array([
statistic(np.delete(data, i)) for i in range(n)
])
jack_mean = jackknife.mean()
acc = np.sum((jack_mean - jackknife) ** 3) / (
6 * np.sum((jack_mean - jackknife) ** 2) ** 1.5
)
# Adjusted percentiles
z_alpha = stats.norm.ppf(alpha / 2)
z_1alpha = stats.norm.ppf(1 - alpha / 2)
p_lower = stats.norm.cdf(z0 + (z0 + z_alpha) / (1 - acc * (z0 + z_alpha)))
p_upper = stats.norm.cdf(z0 + (z0 + z_1alpha) / (1 - acc * (z0 + z_1alpha)))
lower = np.percentile(boot_stats, 100 * p_lower)
upper = np.percentile(boot_stats, 100 * p_upper)
else:
raise ValueError(f"Unknown method: {method}")
return observed, lower, upper
# Usage
accuracies = np.array([92.1, 92.5, 91.8, 92.3, 92.0, 91.9, 92.4, 92.2, 92.6, 91.7])
point, lo, hi = bootstrap_ci(accuracies, method="bca")
print(f"Accuracy: {point:.2f} [{lo:.2f}, {hi:.2f}] (95% BCa CI)")
def paired_permutation_test(
scores_a: np.ndarray,
scores_b: np.ndarray,
n_permutations: int = 100_000,
seed: int = 42,
) -> tuple[float, float]:
"""Two-sided paired permutation test.
Returns:
(observed_diff, p_value) where diff = mean(a) - mean(b).
"""
rng = np.random.default_rng(seed)
diffs = scores_a - scores_b
observed = np.mean(diffs)
count = 0
for _ in range(n_permutations):
signs = rng.choice([-1, 1], size=len(diffs))
perm_diff = np.mean(diffs * signs)
if abs(perm_diff) >= abs(observed):
count += 1
p_value = count / n_permutations
return observed, p_value
# Usage
model_a = np.array([92.1, 92.5, 91.8, 92.3, 92.0])
model_b = np.array([91.5, 91.8, 91.2, 91.9, 91.4])
diff, p = paired_permutation_test(model_a, model_b)
print(f"Mean diff: {diff:.2f}, p-value: {p:.4f}")
| Scenario | Correct? | Method |
|---|---|---|
| Single primary metric, 2 models | No | Single test suffices |
| 1 model vs 5 baselines | Yes | Holm-Bonferroni |
| 5 metrics, 1 comparison | Yes | Holm-Bonferroni |
| Exploratory ablation (many combos) | Yes | Benjamini-Hochberg (FDR) |
| Pre-registered single comparison | No | Pre-registration controls |
from statsmodels.stats.multitest import multipletests
def correct_pvalues(
p_values: list[float],
method: str = "holm", # 'bonferroni', 'holm', 'fdr_bh'
alpha: float = 0.05,
) -> dict:
"""Apply multiple comparison correction.
Methods:
'bonferroni': Conservative. alpha/n per test.
'holm': Step-down Bonferroni. Less conservative, controls FWER.
'fdr_bh': Benjamini-Hochberg. Controls false discovery rate.
"""
reject, corrected, _, _ = multipletests(p_values, alpha=alpha, method=method)
return {
"reject": reject.tolist(),
"corrected_p": corrected.tolist(),
"method": method,
}
# Usage: comparing model against 4 baselines
raw_p = [0.01, 0.04, 0.03, 0.08]
result = correct_pvalues(raw_p, method="holm")
# result['reject'] -> [True, True, True, False]
# result['corrected_p'] -> [0.04, 0.08, 0.09, 0.08]
from statsmodels.stats.power import TTestPower
def compute_required_seeds(
effect_size: float,
alpha: float = 0.05,
power: float = 0.8,
) -> int:
"""How many seeds needed to detect a given effect size.
effect_size: Cohen's d = (mean_a - mean_b) / pooled_std
Small: 0.2, Medium: 0.5, Large: 0.8
Typical ML scenario:
If accuracy diff ~0.5% and std ~0.3%, d = 0.5/0.3 = 1.67 (large).
If accuracy diff ~0.2% and std ~0.3%, d = 0.2/0.3 = 0.67 (medium).
"""
analysis = TTestPower()
n = analysis.solve_power(
effect_size=effect_size,
alpha=alpha,
power=power,
alternative="two-sided",
)
return int(np.ceil(n))
# How many seeds to detect 0.5% accuracy diff with 0.3% std?
d = 0.5 / 0.3 # ~1.67
n_seeds = compute_required_seeds(d)
print(f"Need {n_seeds} seeds per model") # ~5
# Smaller effect: 0.2% diff, 0.3% std
d_small = 0.2 / 0.3 # ~0.67
n_seeds_small = compute_required_seeds(d_small)
print(f"Need {n_seeds_small} seeds per model") # ~20
| Component Removed | Accuracy | Delta | p-value |
|---|---|---|---|
| None (full model) | 92.3 +/- 0.3 | -- | -- |
| - Attention | 90.1 +/- 0.4 | -2.2 | 0.001 |
| - Residual | 91.8 +/- 0.3 | -0.5 | 0.032 |
| - Dropout | 92.1 +/- 0.3 | -0.2 | 0.241 |