"""stats 包测试。 原则(见 docs/02-architecture.md §5):**测已知解析解,不测实现细节**。 """ from __future__ import annotations import numpy as np import pytest pytestmark = pytest.mark.skip(reason="未实现:见 docs/03-roadmap.md L1") def test_bootstrap_ci_matches_normal_theory_on_large_n(rng): """大样本下 bootstrap 百分位区间应逼近正态解析区间(±10% 容差)。""" from mcm_toolkit.stats import bootstrap_ci x = rng.normal(10, 2, size=5000) r = bootstrap_ci(x, statistic=np.mean, confidence=0.95, n_resamples=5000, random_state=0) se = x.std(ddof=1) / np.sqrt(x.size) assert abs((r.params["high"] - r.params["low"]) - 2 * 1.96 * se) < 0.1 * 2 * 1.96 * se def test_bootstrap_ci_works_for_arbitrary_statistic(rng): """bootstrap 的核心价值:任意统计量都能给区间(这里用中位数)。""" from mcm_toolkit.stats import bootstrap_ci x = rng.lognormal(0, 1, size=2000) r = bootstrap_ci(x, statistic=np.median, random_state=0) assert r.params["low"] < r.params["high"] assert r.params["low"] < np.median(x) < r.params["high"] def test_bootstrap_ci_is_reproducible(rng): from mcm_toolkit.stats import bootstrap_ci x = rng.normal(size=500) a = bootstrap_ci(x, statistic=np.mean, random_state=123) b = bootstrap_ci(x, statistic=np.mean, random_state=123) assert a.params["low"] == b.params["low"] def test_confidence_interval_matches_scipy(rng): from scipy import stats from mcm_toolkit.stats import confidence_interval x = rng.normal(5, 1, size=50) lo, hi = confidence_interval(x, confidence=0.95, method="t") ref = stats.t.interval(0.95, len(x) - 1, loc=x.mean(), scale=stats.sem(x)) assert np.allclose([lo, hi], ref, rtol=1e-6) def test_correlation_matrix_diagonal_is_one(rng): from mcm_toolkit.stats import correlation_matrix x = rng.normal(size=(200, 4)) c = correlation_matrix(x) assert np.allclose(np.diag(np.asarray(c)), 1.0) def test_describe_reports_expected_keys(rng): from mcm_toolkit.stats import describe table = describe(rng.normal(size=(100, 3))) for key in ["mean", "std", "min", "max", "median"]: assert key in table.index