Week 08:统计机器学习项目收尾、复现与报告打磨

发布于 2026-07-26 08:00 4941 字 25 min read

Week 08:统计机器学习项目收尾、复现与报告打磨。fish-first 终端教学,面向 CachyOS、VS Code、uv 和 Python 学习路线。
Oh My Pi / weekly tutorial / week08-stat-ml-project-finish
miku@cachyos:~/Code/python-learning$ omp teach week08-stat-ml-project-finish --fish-first --step-by-step
source610 行教学文档
weekWeek 08
shellfish-first 命令版
backlink20 周计划

Week 08:统计机器学习项目收尾、复现与报告打磨

返回主线计划:USTC 统计学:AI / 量化金融 20 周终端式成长计划

Week 07 你已经启动了一个统计机器学习项目:有项目骨架、数据卡、baseline 脚本、结果报告和错误分析。Week 08 的任务是把它整理成“可以给老师、导师、实习面试官或未来的自己看的项目”。

收尾不是美化封面,而是让项目可理解、可复现、可验证、可继续改进。命令默认 fish shell。

0. 本周详细教学:语法、规范、验收

本节不是追加在尾部的复习,而是本周正文的入口。先读这里,再做后面的命令和项目。

0.1 本周真正要学会什么

维度要求
知识点实验表、误差分析、局限性、README
代码语法能从空文件写出本周核心脚本,而不是只复制运行
程序规范函数拆分、路径清楚、输入输出明确、错误能解释
交付物reports/error_analysis.md
验收方式从 fish 终端运行命令,得到可复查的文件或指标

0.2 代码语法精讲

下面的代码不是最终答案,而是本周必须理解的最小骨架:

omppython
errors = valid_df.assign(y_true=y_valid, y_pred=pred)
errors = errors[errors.y_true != errors.y_pred]
print(errors.head(10))
print(errors.groupby("y_true").size())

读代码时按四步检查:输入从哪里来;中间变量的类型和 shape 是什么;函数或脚本输出什么;哪些错误应该显式报出来。

0.3 本周程序规范

  • 所有路径用相对路径或 `pathlib.Path`,不要写死 `/home/miku/...`。
  • 核心逻辑进 `src/`,notebook 只做探索和解释。
  • 每个脚本能从 fish 终端运行,并在 README 写出命令。
  • 输出必须落盘到 `reports/`、`figures/` 或 `outputs/`,不能只在屏幕上看。

0.4 本周练习分层

层级任务不合格表现合格验收
最小练习手写上面的最小骨架只在 notebook 里运行终端运行成功
标准练习把逻辑拆成函数/模块一个大脚本从头写到尾至少 2 个函数,职责清楚
项目练习生成本周交付物 reports/error_analysis.md只有屏幕输出文件落盘,可复查
复盘练习写 3 个错误和修复只写“已解决”写清报错、原因、修复、预防

0.5 本周和主线的连接

1. 本周目标

完成一个干净的项目版本:

  • README 清楚说明问题、数据、方法、实验、结果、限制和运行方式。
  • reports/final_report.md 形成完整实验报告。
  • 结果表可复现,指标和 Week 07 报告一致。
  • 运行命令从空环境开始可执行。
  • Git 提交历史清楚,不提交 .venv/、缓存、大文件或隐私数据。
  • 写下下一步改进,而不是假装项目完美。

本周核心标准:

ompprompt
别人克隆项目后,按 README 执行命令,能得到同类结果。
别人读 final_report 后,能理解你做了什么、为什么做、结果说明什么。

2. 前置条件

你应该已有 Week 07 项目:

ompprompt
projects/stat-ml-baseline/
├── README.md
├── docs/data_card.md
├── reports/baseline_results.md
├── reports/error_analysis.md
└── src/train_baseline.py

进入项目并激活环境:

ompfish
cd ~/Code/python-learning/projects/stat-ml-baseline
source .venv/bin/activate.fish

检查 baseline 是否还能跑:

ompfish
python src/train_baseline.py

如果这一步失败,不要先写报告。先修复脚本或环境,因为 Week 08 的报告必须建立在可复现实验上。

3. 本周文件布局

Week 08 结束时建议结构:

ompprompt
stat-ml-baseline/
├── data/
│   ├── raw/
│   ├── interim/
│   └── processed/
├── docs/
│   └── data_card.md
├── notebooks/
│   └── 01_eda.ipynb
├── reports/
│   ├── baseline_results.md
│   ├── error_analysis.md
│   └── final_report.md
├── src/
│   ├── make_dataset.py
│   └── train_baseline.py
├── .gitignore
├── README.md
├── pyproject.toml
└── uv.lock

不要求每个项目都必须有 notebook,但 README 里提到的文件必须真实存在。不要写“见 reports/final_report.md”,结果文件却不存在。

4. 做一次复现前体检

先从项目根目录看关键文件:

ompfish
pwd
ls
ls src
ls reports
ls docs

检查依赖文件:

ompfish
test -f pyproject.toml; and echo "pyproject exists"
test -f uv.lock; and echo "uv lock exists"
test -f src/train_baseline.py; and echo "training script exists"

检查 Git 状态:

ompfish
git status --short

如果看到 .venv/__pycache__/.ipynb_checkpoints/,说明 .gitignore 需要修正。

5. 整理 .gitignore

打开或创建 .gitignore

ompfish
code .gitignore

建议包含:

ompprompt
.venv/
__pycache__/
*.pyc
.ipynb_checkpoints/
.DS_Store
.cache/

Local large or restricted data archives

data/raw/.zip data/raw/.tar.gz data/raw/*.7z

Optional generated artifacts

reports/*.html

是否忽略 CSV 要看数据许可:

  • 如果数据公开、小、允许再分发,可以提交一份小样本或完整 CSV。
  • 如果数据大、需要登录下载、包含敏感信息,不要提交原始 CSV。README 必须说明如何取得数据、放到哪里。

不要把 .venv/ 提交到 Git。虚拟环境是本机生成物,不是项目源代码。

6. 确认可复现命令

README 的 How to Run 部分必须从克隆后的项目根目录开始。

推荐命令:

ompfish
uv venv
source .venv/bin/activate.fish
uv sync
python src/train_baseline.py

逐句解释:

命令 作用
uv venv 创建项目本地 .venv
source .venv/bin/activate.fish 用 fish 激活环境
uv sync 根据 pyproject.tomluv.lock 安装依赖
python src/train_baseline.py 重新生成 baseline 报告

如果数据不能提交,README 在运行命令之前必须加上:

ompprompt
Download the dataset from ... and place it at data/raw/train.csv.

否则别人按照命令运行会直接找不到文件。

7. README 最终模板

打开 README:

ompfish
code README.md

建议改成下面结构:

ompmarkdown
# Statistical Machine Learning Baseline

Problem

State the prediction problem in 3-5 sentences. Explain the unit of observation, target variable, and why this task matters.

Data

  • Source:
  • Download date:
  • Rows:
  • Columns:
  • Target:
  • License or usage condition:

See docs/data_card.md for field-level details.

Method

Describe preprocessing, train/test split, cross validation, baseline models, and selection metric.

Experiments

ModelValidation MetricTest MetricNotes
Logistic Regressionscaled numeric features
Random Foresttree baseline

Results

Summarize the chosen model and what the metric means. Do not exaggerate the result.

Error Analysis

Summarize the main error types and link to reports/error_analysis.md.

Limitations

List data, modeling, validation, and interpretation limitations.

How to Run

uv venv
source .venv/bin/activate.fish
uv sync
python src/train_baseline.py
</code></pre></div>
<h2>Project Structure</h2>
<p>Explain the key directories.</p>
<h2>Next Steps</h2>
<p>List realistic improvements.</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code>
README 里不要只写“使用机器学习预测”。要写清楚预测对象和指标选择原因。

## 8. 写最终报告

创建:

```fish
code reports/final_report.md
</code></pre></div>
<p>建议结构:</p>
<div class="omp-code-frame" data-lang="markdown"><div class="omp-code-bar"><span>omp</span><span>markdown</span></div><pre><code class="language-markdown"># Final Report: Statistical Machine Learning Baseline

## 1. Problem

Define the task.

## 2. Data

Summarize source, rows, columns, target, missingness, and limitations.

## 3. Experimental Design

Explain train/test split, cross validation, preprocessing pipeline, and metric choice.

## 4. Models

Describe naive baseline and sklearn baselines.

## 5. Results

Include the result table from `reports/baseline_results.md`.

## 6. Error Analysis

Summarize errors from `reports/error_analysis.md`.

## 7. Limitations

State what this project cannot prove.

## 8. Next Steps

List concrete improvements.
</code></pre></div>
<p>最终报告和 README 的区别:</p>
<table>
<thead>
<tr>
<th>文件</th>
<th>读者目的</th>
</tr>
</thead>
<tbody><tr>
<td>README</td>
<td>快速了解项目、运行项目、判断项目结构</td>
</tr>
<tr>
<td>final_report</td>
<td>详细理解实验设计、结果、错误分析、限制</td>
</tr>
</tbody></table>
<p>README 可以短,报告要完整。</p>
<h2>9. 把 Week 07 的结果表转成可展示表格</h2>
<p>打开 Week 07 生成的报告:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">code reports/baseline_results.md
</code></pre></div>
<p>把关键结果复制到 README 和 <code>reports/final_report.md</code>。表格建议包含:</p>
<div class="omp-code-frame" data-lang="markdown"><div class="omp-code-bar"><span>omp</span><span>markdown</span></div><pre><code class="language-markdown">| Model | CV F1 Mean | CV F1 Std | Test F1 | Test ROC AUC | Notes |
|---|---:|---:|---:|---:|---|
| Naive baseline | ... | ... | ... | ... | majority class |
| Logistic Regression | ... | ... | ... | ... | scaled features |
| Random Forest | ... | ... | ... | ... | tree ensemble |
</code></pre></div>
<p>如果你没有 naive baseline,本周补上。一个没有 naive baseline 的项目,很难说明模型到底是否有价值。</p>
<h2>10. 检查指标叙述是否诚实</h2>
<p>不要写:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">The model performs very well.
</code></pre></div>
<p>应该写:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">The selected model reaches a test F1 of 0.XX on the current holdout split. This suggests it improves over the naive baseline, but the estimate may be optimistic because the dataset is small and only one final holdout split is used.
</code></pre></div>
<p>统计学项目尤其要避免过度宣称。你可以说“在当前数据和划分下表现更好”,不要说“证明该方法一定有效”。</p>
<h2>11. 复现测试:从干净环境重跑</h2>
<p>在当前项目里,先确认虚拟环境能用:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">source .venv/bin/activate.fish
uv sync
python src/train_baseline.py
</code></pre></div>
<p>如果想模拟新机器,不要删除项目文件,只移除本地虚拟环境后重建:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">rm -rf .venv
uv venv
source .venv/bin/activate.fish
uv sync
python src/train_baseline.py
</code></pre></div>
<p>注意:<code>rm -rf .venv</code> 只删除虚拟环境,不能删除 <code>data/</code><code>src/</code><code>reports/</code>。执行前用 <code>pwd</code> 确认你在项目根目录。</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">pwd
</code></pre></div>
<p>运行成功后,报告时间或数值可能重新生成,但主要结果应一致。</p>
<h2>12. 数据路径检查</h2>
<p>常见复现失败来自路径写死。脚本里不要写:</p>
<div class="omp-code-frame" data-lang="python"><div class="omp-code-bar"><span>omp</span><span>python</span></div><pre><code class="language-python">pd.read_csv(&quot;/home/miku/Downloads/train.csv&quot;)
</code></pre></div>
<p>应该写项目相对路径:</p>
<div class="omp-code-frame" data-lang="python"><div class="omp-code-bar"><span>omp</span><span>python</span></div><pre><code class="language-python">pd.read_csv(&quot;data/raw/train.csv&quot;)
</code></pre></div>
<p>如果你担心从不同目录运行脚本,可以用文件所在位置推导项目根目录:</p>
<div class="omp-code-frame" data-lang="python"><div class="omp-code-bar"><span>omp</span><span>python</span></div><pre><code class="language-python">from pathlib import Path

PROJECT_ROOT = Path(__file__).resolve().parents[1]
DATA_PATH = PROJECT_ROOT / &quot;data&quot; / &quot;raw&quot; / &quot;train.csv&quot;
</code></pre></div>
<p>这样从项目根目录运行更稳定。</p>
<h2>13. 报告中的错误分析要具体</h2>
<p>不要写:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">Some samples are predicted incorrectly.
</code></pre></div>
<p>应写:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">False negatives are more concerning for this task because missing a positive case has higher cost. In the wrong-prediction preview, several false negatives have feature values near the decision boundary, suggesting that a calibrated probability threshold or additional domain features may be useful.
</code></pre></div>
<p>错误分析至少包含:</p>
<ul>
<li>主要错误类型。</li>
<li>错误的可能原因。</li>
<li>这些错误对任务有什么影响。</li>
<li>下一步如何验证改进。</li>
</ul>
<h2>14. 清理 notebook 与临时文件</h2>
<p>Notebook 可以保留,但不要让它成为唯一入口。检查临时文件:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">find notebooks -maxdepth 2 -type f
find reports -maxdepth 2 -type f
find src -maxdepth 2 -type f
</code></pre></div>
<p>如果你有很多临时图、草稿 CSV、旧报告,决定:</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>处理</th>
</tr>
</thead>
<tbody><tr>
<td>最终报告需要引用的图</td>
<td>放在 <code>reports/figures/</code> 并在报告中链接</td>
</tr>
<tr>
<td>notebook 自动缓存</td>
<td>加入 <code>.gitignore</code></td>
</tr>
<tr>
<td>临时实验输出</td>
<td>删除或移到明确命名目录</td>
</tr>
<tr>
<td>旧版本报告</td>
<td>如果不再引用,删除,避免读者混淆</td>
</tr>
</tbody></table>
<p>不要为了“看起来文件多”保留无用文件。项目越清晰越专业。</p>
<h2>15. Git 提交卫生</h2>
<p>先看状态:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git status --short
</code></pre></div>
<p>查看将要提交的文件:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git diff --stat
</code></pre></div>
<p>如果发现 <code>.venv/</code> 或缓存文件,先修 <code>.gitignore</code>。然后提交:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git add README.md docs reports src pyproject.toml uv.lock .gitignore
git commit -m &quot;Finish statistical machine learning baseline project&quot;
</code></pre></div>
<p>提交信息要说明结果,不要写:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">update
final
fix
123
</code></pre></div>
<p>更好的提交信息:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">Add reproducible baseline report
Document data card and error analysis
Finish statistical ML project README
</code></pre></div>
<h2>16. 如果提交前发现大文件</h2>
<p>检查 Git 追踪文件大小可以用:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git status --short
</code></pre></div>
<p>如果还没提交,但 <code>git status</code> 显示大数据文件被加入暂存区,可以取消暂存:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git restore --staged data/raw/large_file.csv
</code></pre></div>
<p>然后把它加入 <code>.gitignore</code>,并在 README 写清楚下载方式。</p>
<p>如果数据已经提交过,处理历史会更复杂。初学阶段先养成提交前检查的习惯。</p>
<h2>17. 最终验收清单</h2>
<p>在项目根目录执行:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">source .venv/bin/activate.fish
uv sync
python src/train_baseline.py
test -f README.md; and echo &quot;README exists&quot;
test -f docs/data_card.md; and echo &quot;data card exists&quot;
test -f reports/final_report.md; and echo &quot;final report exists&quot;
test -f reports/error_analysis.md; and echo &quot;error analysis exists&quot;
</code></pre></div>
<p>人工检查 README:</p>
<ul>
<li>Problem 清楚。</li>
<li>Data 来源明确。</li>
<li>Method 说明了预处理、模型、验证方式。</li>
<li>Experiments 有结果表。</li>
<li>Results 没有夸大。</li>
<li>Error Analysis 有具体观察。</li>
<li>Limitations 诚实。</li>
<li>How to Run 可复制执行。</li>
<li>Project Structure 解释主要目录。</li>
</ul>
<p>人工检查报告:</p>
<ul>
<li>有数据说明。</li>
<li>有实验设计。</li>
<li>有 baseline 和至少一个 sklearn 模型。</li>
<li>有指标选择理由。</li>
<li>有结果表。</li>
<li>有错误分析。</li>
<li>有限制和下一步。</li>
</ul>
<p>人工检查 Git:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">git status --short
</code></pre></div>
<p>理想状态是没有未提交变更,或只剩你明确不想提交的数据文件。</p>
<h2>18. 常见错误</h2>
<h3>错误 1:README 的运行命令不完整</h3>
<p>只写 <code>python src/train_baseline.py</code> 不够。别人还需要知道如何创建环境、安装依赖、放置数据。</p>
<p>最低限度写:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">uv venv
source .venv/bin/activate.fish
uv sync
python src/train_baseline.py
</code></pre></div>
<h3>错误 2:报告和代码结果不一致</h3>
<p>如果你重新运行脚本后结果变了,README 和 final_report 也要更新。不要让报告写旧结果。</p>
<h3>错误 3:没有说明数据限制</h3>
<p>所有数据都有偏差。限制可以包括样本量、时间范围、采样方式、缺失值、标签噪声、不可观测变量。</p>
<h3>错误 4:把 notebook 当成最终交付</h3>
<p>Notebook 可以展示探索过程,但最终复现入口应是脚本。面试官更希望看到清楚的项目结构和可运行命令。</p>
<h3>错误 5:提交了虚拟环境</h3>
<p><code>.venv/</code> 可能包含成千上万个文件,只属于你的机器。提交它会让仓库巨大且不可维护。</p>
<p>修复:</p>
<div class="omp-code-frame" data-lang="fish"><div class="omp-code-bar"><span>omp</span><span>fish</span></div><pre><code class="language-fish">code .gitignore
git status --short
</code></pre></div>
<p>确认 <code>.gitignore</code> 有:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">.venv/
</code></pre></div>
<h3>错误 6:过度美化结论</h3>
<p>不要把一次课程项目写成工业级系统。诚实说明“这是 baseline 项目”,反而更专业。</p>
<h2>19. 面向老师或面试官的项目摘要</h2>
<p>你可以在 README 顶部或简历中写 3-4 行摘要:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">Built a reproducible statistical machine learning baseline for a tabular prediction task using Python, pandas, and scikit-learn. Designed a leakage-safe validation workflow with cross validation, compared interpretable baseline models, and documented error analysis and limitations. Packaged the project with uv environment management, clear README instructions, and Git-tracked reports.
</code></pre></div>
<p>如果是中文场景:</p>
<div class="omp-code-frame" data-lang="prompt"><div class="omp-code-bar"><span>omp</span><span>prompt</span></div><pre><code class="language-text">使用 Python、pandas 与 scikit-learn 完成一个可复现的表格数据预测 baseline 项目;设计了防止数据泄漏的验证流程,比较多个经典模型,并整理数据卡、实验结果、错误分析与项目复现说明。
</code></pre></div>
<p>注意:摘要中不要写没有做过的东西,比如“部署”“深度学习”“自动化特征工程”。</p>
<h2>20. 本周练习</h2>
<ol>
<li>从零执行 README 的 How to Run,确认命令完整。</li>
<li>让同学或未来的自己只看 README,判断能否理解项目。</li>
<li>给 final_report 增加一个“Metric Choice”小节。</li>
<li>给 README 增加项目结构树,并解释每个目录。</li>
<li>检查 Git 状态,确保 <code>.venv/</code> 没被提交。</li>
<li>写 5 条 next steps,每条都必须可以在未来一周内验证。</li>
</ol>
<h2>21. 下一步</h2>
<p>回到主线:<a href="/post/ustc-stat-ai-quant-plan/">USTC 统计学:AI / 量化金融 20 周终端式成长计划</a>。Phase 2 到这里结束。接下来 Week 09-10 会进入 PyTorch:你将从 sklearn 的表格建模,转向张量、Dataset / DataLoader、神经网络训练循环与深度学习 baseline。</p>


    </article>
  </div>
</section>

喜欢的话,留下你的评论吧~