# 真实对话记录：预测模型验证不能只看 AUC

> 来源：AI 研伴（OpenScience）同一演示会话；模型：GPT-5.6-sol。
> 数据完全虚构。记录已移除密钥、内部路径、消息标识、成本、隐藏推理和工具输入。

## 第 1 轮 · 用户

在本次新建的独立演示项目中，真实执行一份高质量中文科研案例：小样本预测模型为什么不能只看 AUC——嵌套交叉验证、校准与数据泄漏审计。

面向科研研究生，模拟“研究项目按期完成”的二分类预测任务，不涉及临床决策。请用固定种子生成 240 个完全虚构项目的数据，包含项目规模、团队规模、前期准备、研究领域、资源投入以及相关的冗余特征，明确数据生成机制。不得把模拟结果表述为真实人群证据。所有计算在本项目工作区内完成，不访问其他项目、不读取环境变量或密钥、不访问主机内网、不安装系统服务。仅 CPU 轻量分析，不超过 2 核，不下载大型模型。

比较一个简单基线、正则化 logistic 回归、一个树模型。预处理、特征选择、调参全部在训练折内；采用嵌套分层交叉验证，保留每个样本的折外概率。报告 ROC-AUC、PR-AUC（注明阳性率基线）、Brier 分数、校准图与混淆矩阵。阈值选择只能依赖训练数据或预先固定 0.5。不要把折间 SD 冒充置信区间。给出预测概率与特征的重要性限制，不宣称变量有因果作用。

额外做一个明确隔离、故意错误的数据泄漏示范（用结果派生变量作为输入），以便用户理解虚高表现；错误示范不得混入合法模型选择。报告与图表醒目标注“不正确做法，仅用于教学”。

至少输出 4 张有信息量且审美统一的图：ROC/PR、校准、各模型指标比较、合法与泄漏方案对照；图表中文为主，如无中文字体，寻找容器已有字体或通过公开 HTTPS 下载一个开源中文字体，不要使用方框乱码。输出中文 report.md 和可独立阅读的 report.html、原始模拟数据 CSV/XLSX、折外预测、指标与数据字典、可复现 analysis.py、依赖版本、机器可读 result-summary.json。报告说明实际执行耗时，模型用量由系统另行记录，不编造金额。列出实际验证命令、输出文件和校验结果。

优先使用现有 Python 库。若缺少库，可在项目目录创建虚拟环境安装必要的小型科学计算依赖。先检查工具能否执行，失败时如实停止并报告，禁止伪造成功或结果。正文、Prompt 说明、表格标题与解读均为中文，变量代码可为英文。无需再询问选题，开始实施，全部文件完成并验证后再给最终总结。

工具活动（仅公开名称与状态）：

- `skill`：completed
- `bash`：completed

工具活动（仅公开名称与状态）：

- `skill`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `artifact`：completed

## 第 1 轮 · AI 研伴（GPT-5.6-sol）

已完成并验证本次独立演示项目。所有计算均使用固定种子、CPU 单线程，在本项目工作区内完成；未访问其他项目、环境变量、密钥或主机内网，也未安装系统服务或下载大型模型。

## 主要结果

模拟数据：

- 样本量：240
- 阳性率：47.92%（115/240）
- 固定种子：`20260911`
- 模拟结果完全虚构，不代表真实人群证据，也不用于临床或现实决策
- 实际分析耗时：约 47.4 秒

合法模型采用：

- 外层 5 折分层交叉验证
- 内层 3 折分层交叉验证
- 所有预处理、特征筛选和调参均在训练折内完成
- 保留每个样本的外层折外预测概率
- 阈值固定为 0.5，未利用折外结果调阈值

| 模型 | ROC-AUC | PR-AUC | Brier 分数 | 准确率 | 敏感度 | 特异度 |
|---|---:|---:|---:|---:|---:|---:|
| 简单基线 | 0.500 | 0.479 | 0.250 | 0.521 | 0.000 | 1.000 |
| 正则化 Logistic 回归 | 0.698 | 0.688 | 0.219 | 0.642 | 0.617 | 0.664 |
| 随机森林 | 0.671 | 0.625 | 0.226 | 0.617 | 0.617 | 0.616 |
| 错误示范：结果派生变量泄漏 | 1.000 | 1.000 | 0.003 | 1.000 | 1.000 | 1.000 |

PR-AUC 的阳性率基线为 0.479。泄漏方案明显虚高，且已明确隔离，没有参与合法模型选择。

## 已生成文件

项目工作区内已生成：

- `analysis.py`：完整可复现分析脚本
- `report.md`：中文科研案例报告
- `report.html`：可独立离线阅读的 HTML 报告
- `simulated-project-data.csv`
- `simulated-project-data.xlsx`
- `oof-predictions.csv`：3 个模型共 720 条折外预测记录
- `metrics.csv`
- `feature-importance.csv`
- `data-dictionary.csv`
- `dependencies.txt`
- `result-summary.json`
- `figure-01-roc-pr.png`
- `figure-02-calibration.png`
- `figure-03-metrics-confusion.png`
- `figure-04-leakage.png`

图表包括：

1. ROC 与 PR 曲线
2. 折外概率校准图
3. 合法模型指标比较
4. 合法方案与泄漏方案对照，并醒目标注“**不正确做法，仅用于教学**”

## 验证结果

已执行：

```bash
python3 analysis.py
```

随后在项目工作区重新执行并检查：

- 所有要求文件均存在
- 原始数据行数：240
- 折外预测行数：720
- `result-summary.json` 可正常读取
- 结果摘要包含随机种子、阳性率、耗时、模型指标及各文件 SHA-256
- 中文报告 SHA-256：

```text
ada9e19778bf65aa554276f4f7dda189013ecbc1567528fc9c558f38cc1cde12
```

最重要的教学结论已写入报告：ROC-AUC 只反映排序区分度，不能替代 PR-AUC、Brier 分数、校准图和阈值下混淆矩阵；此外，结果派生变量会造成极端虚高表现，必须在建模前完成数据泄漏审计。

## 第 2 轮 · 用户

我检查了你刚生成的 4 张 PNG，中文标题、坐标轴和图例全部显示成方框，当前结果不能发布。请继续在同一项目中修复，保留这条反馈和你的回复作为真实对话记录。

要求：
1. 从 Google Noto 官方维护的 GitHub 仓库下载 NotoSansCJKsc-Regular.otf（官方路径：notofonts/noto-cjk/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf），只用于重新渲染；不要使用来历不明的字体。
2. 修改 analysis.py，显式通过 matplotlib.font_manager.FontProperties 指向该字体，确保标题、图例、坐标轴、注释均使用它；负号正常显示。
3. 重新生成 4 张 PNG 和 report.html。对字体路径、图像尺寸、文件非空及所有指标重新验证。
4. 在 result-summary.json 和 report.md 中记录字体名称、官方来源 URL、修复原因与验证结果。
5. 为保持公开案例轻量，验证完成后可以删除本地 OTF，但 analysis.py 必须保留可复现的字体获取说明和清晰失败提示，不得静默退回会产生方框的字体。
6. 最终回复应明确承认首轮视觉验收失败，列出修复后的文件和实际验证；不要声称仅靠代码运行成功就证明视觉无乱码。

工具活动（仅公开名称与状态）：

- `webfetch`：completed

工具活动（仅公开名称与状态）：

- `read`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `apply_patch`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

工具活动（仅公开名称与状态）：

- `bash`：completed

## 第 2 轮 · AI 研伴（GPT-5.6-sol）

已继续在同一独立项目中修复，并保留本轮用户反馈与我的处理回复作为真实对话记录。

## 首先明确承认

首轮视觉验收失败：虽然首轮代码成功运行并生成了 4 张 PNG，但中文标题、坐标轴和图例实际显示为方框，因此首轮结果不能发布。代码运行成功并不能证明图像没有乱码；本轮已针对字体文件、字体绑定和输出文件进行修复与验证。

## 本轮修复

已从 Google Noto 官方维护的 GitHub 仓库下载并使用：

```text
字体：Noto Sans CJK SC
官方来源：
https://raw.githubusercontent.com/notofonts/noto-cjk/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf
```

修改后的 `analysis.py`：

- 显式定义官方字体来源 URL
- 显式要求脚本同目录存在 `NotoSansCJKsc-Regular.otf`
- 使用：

```python
font_manager.fontManager.addfont(str(FONT_PATH))
font_manager.FontProperties(fname=str(FONT_PATH))
```

- 标题、坐标轴标签、图例、刻度标签和图表注释均显式绑定该 `FontProperties`
- 设置：

```python
plt.rcParams["axes.unicode_minus"] = False
```

- 不再静默回退到可能缺少中文 glyph 的字体
- 若字体缺失、为空或字体名称解析不符，脚本会清晰报错并停止

字体文件在重新渲染和验证完成后已按要求删除。由于 `analysis.py` 保留了官方获取命令、来源 URL 和失败提示，因此之后复现时需要先重新下载该官方字体；缺少字体时不会生成可能含方框的图像。

## 已重新生成的文件

以下文件均已更新：

- `figure-01-roc-pr.png`
- `figure-02-calibration.png`
- `figure-03-metrics-confusion.png`
- `figure-04-leakage.png`
- `report.html`
- `report.md`
- `result-summary.json`
- `analysis.py`
- `dependencies.txt`

此外，重新运行同时保留并核验了：

- `metrics.csv`
- `oof-predictions.csv`
- `simulated-project-data.csv`
- `simulated-project-data.xlsx`
- `feature-importance.csv`
- `data-dictionary.csv`

## 实际验证

执行命令：

```bash
python3 analysis.py
```

重新生成后实际得到：

| 图像 | 尺寸 | 文件大小 |
|---|---:|---:|
| `figure-01-roc-pr.png` | 2340 × 900 | 177,348 bytes |
| `figure-02-calibration.png` | 1260 × 900 | 92,069 bytes |
| `figure-03-metrics-confusion.png` | 1980 × 1440 | 121,799 bytes |
| `figure-04-leakage.png` | 2160 × 900 | 79,590 bytes |

文件级验证结果：

- 4 张 PNG 均存在
- 4 张 PNG 均非空
- 图像尺寸均可正常读取
- 字体文件存在且非空时，字体解析名称为 `Noto Sans CJK SC`
- `report.html` 已重新嵌入 4 张更新后的 PNG
- `metrics.csv` 包含 4 行结果
- 原始数据仍为 240 行
- 折外预测仍为 720 行
- 合法模型指标重新计算并与首轮一致：
  - 简单基线 ROC-AUC：0.500
  - 正则化 Logistic 回归 ROC-AUC：0.698
  - 随机森林 ROC-AUC：0.671
  - 独立泄漏教学示范 ROC-AUC：1.000

重新执行后已删除本地字体文件，并额外验证：

```text
otf_exists_after_cleanup False
```

同时确认删除字体后再次运行会失败，而不是静默回退：

```text
exit_code=1
```

这符合“缺少官方字体时清晰失败”的要求。

## 报告中的新增记录

`report.md` 和 `result-summary.json` 已记录：

- 首轮视觉验收失败的原因
- 官方字体名称
- 官方来源 URL
- 字体文件路径和名称验证
- 图像尺寸与非空验证
- 不静默回退字体的设置
- “代码运行成功不等同于视觉无乱码，仍需人工查看图像”的限制说明

需要如实说明：本轮已完成官方字体绑定、字体解析、渲染输出和文件级检查，但我不会把这些检查夸大为人工视觉验收的替代品。最终发布前仍建议直接打开 4 张 PNG 和 `report.html`，确认中文 glyph 在实际查看器中无方框、无截断、无重叠。
