Files
MCM-ICM_Toolkit/docs/03-roadmap.md
T
guzhujushi 95f5266563 feat(stats): correlation_matrix 按方案 A 拆成三个函数,收口返回契约(L0 9/12)
用户 2026-10-03 拍板方案 A(见决策 41),由 Codex 落地。

拆成三个函数:
- correlation_matrix  -> 数值系数矩阵(对角线 1.0)
- correlation_pvalues -> 数值 p 值矩阵(对角线 NaN)
- correlation_table   -> 星标字符串表(对角线 1.000 不带星)
三者共用 _check_corr_args 守卫与成对删缺失口径;correlation_table 在最外层调另外两个。
理由: 字符串表做不了后续计算(挑高相关对、喂聚类/PCA、画热力图),反过来随时能格式化;
      一旦返回字符串,数值信息不可逆地丢失。

顺带修掉两处:
- 对角线 p 值由 0.0 改成 NaN —— 写 0 会被下游读成"极显著",而"自己和自己"没有 p 值
- p 值与 r 现在用同一批观测: 先成对 dropna() 再算,并同样尊重 min_periods。
  此前 corr 是成对删缺失、pearsonr 不删,两者样本量不同,r 与 p 对不上
- p 值只算上三角再镜像(成对变量的 p 天然对称),省一半重复计算

tests: test_correlation_matrix_diagonal_is_one 摘掉 xfail 转正;新增 8 条
  (数值性+对称性、非数值列跳过、p 值对照解析式 t = r*sqrt((n-2)/(1-r^2))、
   对角线 NaN、成对删缺失口径、min_periods、对角线无星标、表格与数值输出一致)。
  测试 105 passed / 38 skipped / 1 xfail -> 114 passed / 38 skipped / 0 xfail。

验证: pytest 114 passed / 38 skipped;ruff All checks passed;pyright 0 errors。

docs: STATUS.md(L0 9/12 + 决策 41 + 下一步);CHANGELOG;
      personal-pitfalls 追加第 14 条(把"能看的表"和"能算的表"塞进同一个返回值);
      roadmap 记录 correlation_matrix 的两个伴随函数
2026-10-03 14:53:05 +08:00

117 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 路线图与开发纪律
> 依据:`01-suggestion-review.md` §6–§8。
> 进度看根目录 `STATUS.md`,本文件只定义"做什么、做到什么程度、什么不做"。
---
## 一、功能清单分级
### L0 —— 第一周必做(12 个)
没有这 12 个,工具箱根本跑不起来;有了这 12 个,已经能应付大部分题目。
| 函数 | 所在模块 | 档位 |
|---|---|---|
| `Result` | `core/result.py` | A |
| `get_rng` / `set_seed` | `core/random.py` | A |
| `load_table` | `data/io.py` | A |
| `clean_missing` | `data/clean.py` | A |
| `detect_outliers` | `data/clean.py` | **S** |
| `normalize` | `data/transform.py` | A |
| `standardize` | `data/transform.py` | A |
| `describe` | `stats/descriptive.py` | A |
| `correlation_matrix` | `stats/inference.py` | A |
| `bootstrap_ci` | `stats/bootstrap.py` | **S** |
| `monte_carlo` | `solve/simulate.py` | **S** |
| `save_figure` | `viz/export.py` | A |
> `correlation_matrix` 有两个**伴随函数**(决策 41):`correlation_pvalues` 给 p 值矩阵、
> `correlation_table` 给"系数 + 星标"的论文表格。三者共用同一套入参守卫与**成对删缺失**口径。
### L1 —— v0.1(共约 40 个)
在 L0 基础上补齐:
| 模块 | 函数 |
|---|---|
| `core` | `check_array` `check_same_length` `check_probability` `check_square_matrix` |
| `data` | `impute_missing` `winsorize` `log_transform` `one_hot_encode` `train_test_split` `kfold_split` `bootstrap_sample` |
| `stats` | `zscore` `coefficient_of_variation` `confidence_interval` `t_test` `anova` `chi_square_test` `fit_distribution` `goodness_of_fit` `bootstrap_statistic` |
| `models` | `rmse` `mae` `mape` `smape` `r2_score` `adjusted_r2` `compare_models` `fit_linear` `fit_polynomial` `fit_nonlinear` `predict` `exponential_smoothing` `fit_arima` `forecast` `fit_forest` `fit_logistic` `kmeans` `pca` `cross_validate` |
| `solve` | `minimize` `linear_program` `integer_program` `dynamic_programming` `knapsack_dp` `simulated_annealing` `pareto_front` `monte_carlo_probability` `monte_carlo_integral` `random_walk` `markov_simulate` `markov_steady_state` `mm1_metrics` `local_sensitivity` `one_at_a_time` `parameter_sweep` `robustness_test` `sobol_analyze` `morris_analyze` |
| `decision` | `equal_weights` `entropy_weights` `critic_weights` `ahp_weights` `ahp_consistency_ratio` `topsis` `grey_relational_analysis` `gm11_fit_predict` |
| `viz` | `mcm_style` `plot` `plot_correlation_matrix` `plot_residuals` `plot_convergence` `save_table` |
### L2 —— v0.2
- `solve/graph.py`:`build_graph` `shortest_path` `min_spanning_tree` `betweenness_centrality` `pagerank` `max_flow` `community_detection`
- `solve/dynamics.py`:`solve_ode` `solve_system` `find_equilibrium` `local_stability`
**触发条件**:在真题里真的用到了,或者要为 MCM A / ICM D 备赛时再写。
---
## 二、永久不做(防膨胀清单)
> 原文用"建议不要",这里写成**硬规则**。往这个清单里加东西,必须先改这份文档。
- 不重写 SciPy 的优化器、`scipy.stats` 的分布、`scipy.integrate` 的积分器
- 不重写 sklearn 的 estimator(`fit/predict` 之外一律不做)
- 不重写 statsmodels 的时间序列框架
- 不重写 NetworkX 的图算法
- 不重写 SALib 的 Sobol / Morris / FAST
- 不实现 NSGA-II / SPEA2 等完整多目标进化算法(用 pymoo)
- 不实现符号计算引擎(用 SymPy)
- 不实现完整离散事件仿真引擎(`simulate_queue` 那种)
- 不做深度学习 / PyTorch 相关任何东西
- 不做 GUI、不做 Web 界面、不做 CLI 之外的产品化
- 不做自动微分、不做 GPU 后端
- 不为"完整性"补函数——**没在真题里用过三次的函数不写**
---
## 三、开发纪律
### 3.1 文档两档制
**S 档**(招牌算法,自实现):完整函数卡片,模板见 `dev/function-card-template.md`。
覆盖:`detect_outliers` `bootstrap_ci` `monte_carlo` `monte_carlo_probability`
`monte_carlo_integral` `dynamic_programming` `knapsack_dp` `simulated_annealing`
`local_sensitivity` `sobol_analyze` `entropy_weights` `topsis` `ahp_weights`
`gm11_fit_predict`。约 15 个。
**A 档**(薄封装):docstring 里一句话数学含义 + 一句话什么时候用 + 一条 pytest。
判断标准:**我会不会去改它的内部实现?** 会 → S 档。
### 3.2 每写一个函数
1. 先想"这道题里它替代了哪段手写代码"——想不出来就先不写。
2. 先在 `tests/` 里写一条会失败的断言(测已知解析解,不测实现细节)。
- 参数类型注解按 `02-architecture.md` §4.7 写全;非法类型抛 `TypeError`,不静默兜底。
3. 实现到测试通过。
4. 在 `examples/` 里加一行最小用法。
5. 更新 `STATUS.md`。
### 3.3 提交前
```powershell
.venv\Scripts\python.exe -m pytest -q
.venv\Scripts\python.exe -m ruff check src tests
```
---
## 四、时间盒
| 周 | 目标 | 完成标志 |
|---|---|---|
| 1 | `core` + `data` + `stats`;S 档先写 `bootstrap_ci` `monte_carlo` `detect_outliers` | L0 全部通过测试 |
| 2–3 | `models` + `solve/optimize` + `solve/simulate` | `compare_models` 出对比表 |
| 4 | `solve/sensitivity` + `decision` + `viz` | 一条端到端 example |
| 5–6 | 用一道真题走完整流程,反向补函数 | `problems/<年份>_<题号>/` 完成 |
| 之后 | 每做一题沉淀 1~3 个函数 + 对应 test | 仓库自然长大 |
**核心原则:先跑通一条完整链路,再补宽度。**