$npx -y skills add QFIN-tech/model-evo --skill classification-model-training端到端训练 xgboost/dnn/lr 二分类模型——读上游 feature-analysis 产出的 splits/{train,test,oot}.parquet,产八阶段产物(features/model/evaluation/predictions/explainability/comparison/logs/config),并与历史 baseline 做 AUC/KS/分档多维对比。本 skill 不取数也不切分。当用户说"建模""训练新模型""跑模型""对比base""迭代模型"时使用。
| 1 | # classification-model-training |
| 2 | |
| 3 | 训练为进程内实现(xgboost / dnn / lr),按 `model.algo` 切换;由 `scripts/run_build.py` 编排。 |
| 4 | 共享配置读写代码位于 `model-skills/_modelevo-shared/scripts/`(config_io),通过 `scripts/_bootstrap.py` 注入;源在仓库根 `_modelevo-shared/scripts/`,由 `install.sh` 复制。 |
| 5 | |
| 6 | ## 1. 输入依赖 |
| 7 | |
| 8 | | 输入 | 必选 | 来源 | 说明 | |
| 9 | |---|:---:|---|---| |
| 10 | | `splits/{train,test,oot}.parquet` | ✅ | 上游 `feature-analysis` 按 `model.split` 切分产出 | 本 skill 直接消费,不取数、不切分;缺失时回到 `classification-model-development` Stage 0 跑 `feature-analysis` 补齐,本 skill 不做切分兜底 | |
| 11 | | 特征清单(`features` / `feature_list_source`) | ✅ | 用户配置 或 上游 `feature-matching` 派生的 `feature-list.csv` | 候选特征清单强制过**边界安全过滤**(可配 `model.boundary_filter.enable_*=false` 关闭),剔除 4 类会让训练失败或泄漏的特征(常量/泄漏/ID 类/全缺失,规则表见第 3 节);过滤后剩余特征即入模特征集;剔除弱特征(低 IV/高 PSI)的优化筛选不在本 skill,走 `classification-model-tuning` 产 `-feat` 新 run;`features` 留空则走 `feature_list_source`(各业务域清单见 `model-knowledge/assets/feature-knowledge/feature-knowledge.md` 索引,如 `feature-list/feature-list-user-operation-v1.csv`) | |
| 12 | | `train_config.yaml` | ✅ | 复制 `config/train_config.example.yaml` 后填写 | 填模型名/标签列/特征清单;可选 `model.baseline_eval_dir` 配基线评估目录以走 N-way 对比;可选 `model.run_label` 当作本次 run 的版本号(如 v1/v2)。**输入 yaml 必须放 `<session_dir>/new-models/{algo}-v{N}/config/` 下**(即 model 内部 config 目录),**严禁落到 session 根目录或 `<skill_dir>/config/` 下**;`run_build.py` 会把 `--config` 指向的 yaml 视为输入源,`write_train_config_yaml` 在同目录原地写 `_manifest.json`(含 `source_yaml` 指向自身),不做副本拷贝 | |
| 13 | | `session_dir` | ✅ | 上游 `classification-model-development` / `classification-model-orchestration` 传入 | 本 skill 不负责 session 决议;无 session 上下文时请先调 `classification-model-development/scripts/list_sessions.py` 列历史 sessions | |
| 14 | |
| 15 | ## 2. 执行命令 |
| 16 | |
| 17 | `<skill_dir>` 指本 skill 所在目录(即本文件所在目录),执行时替换为实际绝对路径,不要依赖当前工作目录。 |
| 18 | |
| 19 | **Session 决议**(由上游负责):本 skill 假定 `session_dir` 已由上游 `classification-model-development` / `classification-model-orchestration` 确定。若用户直接调本 skill 且无 session 上下文,请先跑: |
| 20 | |
| 21 | ```bash |
| 22 | python <model-skills>/classification-model-development/scripts/list_sessions.py |
| 23 | ``` |
| 24 | |
| 25 | 用 `AskUserQuestion` 询问选历史 session 还是新建,确认 `session_dir` 后再执行训练。 |
| 26 | |
| 27 | **输入 yaml 落盘(强制)**:输入 yaml 必须落 `<session_dir>/new-models/{algo}-v{N}/config/train_config.yaml`(model 内部 config 目录),不要放 `<skill_dir>/config/` 或 session 根目录。流程: |
| 28 | |
| 29 | 1. 复制 `<skill_dir>/config/train_config.example.yaml` 到 `<session_dir>/new-models/{algo}-v{N}/config/train_config.yaml`(`{algo}` 取 `xgb|dnn|lr`,`{N}` 由 `next_version` 自增;目录不存在则 `mkdir -p` 创建) |
| 30 | 2. 编辑该 yaml 填真实值 |
| 31 | 3. 调 `run_build.py` 指向该 yaml: |
| 32 | |
| 33 | ```bash |
| 34 | python <skill_dir>/scripts/run_build.py \ |
| 35 | --config <session_dir>/new-models/{algo}-v{N}/config/train_config.yaml \ |
| 36 | --output_dir <session_dir> \ |
| 37 | --version v1 # 可选; 否则按 yaml.run_label → 自动自增 |
| 38 | ``` |
| 39 | |
| 40 | `--data_dir` 可选,默认从同 session 下 `<session_dir>/sample-features/` 读 `splits/{train,test,oot}.parquet`(由 `feature-analysis` 切分产出);若需用其他数据,显式传 `--data_dir` override(指向含 `splits/` 子目录的目录)。`--output_dir` 直接传 `<session_dir>`,`run_build` 会在其下落 `new-models/{algo}-v{N}/`(无 `classification-model-training/` 中间层)。test.parquet 当 val 段(early stopping);进程内用调优超参训练(`tune_train.TUNED_PARAMS`: depth 6 / lr 0.03 / n 800 + early-stop;比 `engines/_xgb/entry.py` 的强正则默认更高容量,避免欠拟合)。 |
| 41 | |
| 42 | 训练完成后,模型报告路径需人工登记到 `classification-model-recommend` 台账(本 skill 不自动改 csv)。 |
| 43 | |
| 44 | ## 3. 参数说明 |
| 45 | |
| 46 | ### run_build.py |
| 47 | |
| 48 | | 参数 | 必选 | 默认值 | 说明 | |
| 49 | |---|:---:|---|---| |
| 50 | | `--config` | ✅ | - | 训练配置 yaml 路径(load_config + validate 后使用,并复制到 run_dir/config/) | |
| 51 | | `--output_dir` | ✅ | - | session_dir 本身(编排器在其下落 `new-models/`) | |
| 52 | | `--data_dir` | 否 | 自动推断 | 含 `splits/{train,test,oot}.parquet` 的目录(通常 `<session_dir>/sample-features/`);留空从 `<output_dir>/sample-features/` 推断,推断失败则报错退出 | |
| 53 | | `--version` | 否 | `None` | 显式版本号(仅纯版本号: `v1` / `v2` / `custom-tag` / `20260710`;**不要带 algo/suffix 前缀**如 `xgb-v1`/`tuned-v1`/`feat`,会被拦截报错);与 `--label` 都传时 `--version` 优先 | |
| 54 | | `--label` | 否 | `None` | `--version` 的别名;留空则按优先级回退 yaml `model.run_label`,再空则自动自增 | |
| 55 | |
| 56 | **version 决议优先级**(本次 run 的 version 用作目录后缀,形如 `v1` / `v2` / `custom-tag`): |
| 57 | |
| 58 | | 优先级 | 来源 | 备注 | |
| 59 | |:---:|---|---| |
| 60 | | 1 | CLI `--version`(别名 `--label`) | 显式指定,跳过自增 | |
| 61 | | 2 | yaml `model.run_label` | 语义化短名(如 v1 / v2) | |
| 62 | | 3 | 自动自增 | 扫 `new-models/` 下同 algo 已有目录取 max+1,首次为 `v1` | |
| 63 | |
| 64 | 字符集限制 `[a-zA-Z0-9_.-]`,非白名单字符归一为 `_`;空值走自动自增。 |
| 65 | |
| 66 | **⚠️ version 保留字拦截**:目录命名规则为 `{algo}{suffix}-{version}`,若 version 含 algo(`xgb`/`dnn`/`lr`/`lgb`)或 suffix(`tuned`/`feat`)保留字 token,会叠加产生重复前缀目录(如 `xgb-xgb-v1` / `xgb-tuned-tuned-v1` / `xgb-feat`)。`validate_config` 与 CLI 入口(`run_build.py` / `run_tuning.py` / `select_features.py`)在 run_dir 创建前统一拦截,报错示例: |
| 67 | |
| 68 | ``` |
| 69 | ValueError: model.run_label 非法: version 标识 'lgb-v1' 含算法/后缀保留字 ['lgb'], ... |
| 70 | ``` |
| 71 | |
| 72 | 写 yaml 或跑 CLI 时,`run_label` / `--version` / `--label` 只填纯版本号(如 `v1` / `v2` / `20260710` / `exp01`),不要重复 algo 或 suffix。 |
| 73 | |
| 74 | ### model.boundary_filter |