$npx -y skills add QFIN-tech/model-evo --skill classification-model-tuning对 classification-model-training 的 baseline run 做超参调优(run_tuning.py:规则诊断 / 可选 Optuna 搜索)或特征筛选(select_features.py:按 PSI/IV/缺失率剔除特征),产 -tuned / -feat 新 run,按 baseline.algo 直通 xgb/dnn/lr。当用户说"调优""调参""优化模型""超参搜索""欠拟合""过拟合""不收敛""特征筛选""剔除高 PSI 特征""剔除低 IV 特征""剔除高缺失特征""缩小特征集"时使用。
| 1 | # classification-model-tuning |
| 2 | |
| 3 | ## 1. 输入依赖 |
| 4 | |
| 5 | | 输入 | 必选 | 来源 | 说明 | |
| 6 | |---|:---:|---|---| |
| 7 | | `baseline_run` | ✅ | 上游 `classification-model-training` 产物 | baseline run 目录(如 `<session_dir>/new-models/xgb-v1`);从其 `config.json` 恢复 cfg / data_path / algo / used_params / metrics / best_iteration | |
| 8 | | `analysis_dir` | 流程 B 必选 | 上游 `feature-analysis` 产物 | 含 `stats.csv` / `iv_table.csv` / `psi_table.csv` 的目录,仅 `select_features.py` 用 | |
| 9 | | baseline 的 data_path | ✅ | baseline `config.json` 记录 | train/test/oot 三档 parquet 必须可访问 | |
| 10 | | `session_dir` | 否 | 从 `baseline_run` 推断(parent.parent) | 输出根目录;可用 `--output_dir` 显式覆盖 | |
| 11 | | Optuna 包 | 否 | `pip install --user "optuna<4"` | 仅 `--method optuna` 需要 | |
| 12 | |
| 13 | ## 2. 执行命令 |
| 14 | |
| 15 | `<skill_dir>` 指本 skill 所在目录(即本文件所在目录),执行时替换为实际绝对路径,不要依赖当前工作目录。 |
| 16 | |
| 17 | ### 2.1 流程 A:超参调优(run_tuning.py) |
| 18 | |
| 19 | ```bash |
| 20 | # 假设上游 classification-model-training 已产出 baseline: |
| 21 | # <session_dir>/new-models/xgb-v1/ |
| 22 | |
| 23 | python <skill_dir>/scripts/run_tuning.py \ |
| 24 | --baseline_run <session_dir>/new-models/xgb-v1 \ |
| 25 | [--method rule|optuna] \ |
| 26 | [--n_trials 30] \ |
| 27 | [--version v1] \ |
| 28 | [--output_dir <session_dir>] \ |
| 29 | [--auto-apply] |
| 30 | ``` |
| 31 | |
| 32 | 执行步骤: |
| 33 | 1. **读 baseline**:从 `config.json` 恢复 cfg / data_path / algo / used_params / metrics / best_iteration |
| 34 | 2. **算法直通**:按 `baseline.algo` 走 xgb / dnn / lr 路径 |
| 35 | 3. **规则诊断**(algo-aware):根据 train/val/oot AUC gap、PSI、训练动力学信号推断状态 |
| 36 | - `overfit` / `underfit` / `unstable_psi` 三条规则 algo-agnostic,只看 AUC gap 与 PSI |
| 37 | - `underconverged` 按 algo 分流:xgb 看 `best_iteration / n_estimators >= 0.95`;dnn 看 `early_stopped=False` 或 `best_epoch / epochs >= 0.95`;lr 看 `converged=False`(凸优化罕见,兜底) |
| 38 | |
| 39 | | 状态 | 触发条件(algo-agnostic 部分) | |
| 40 | |---|---| |
| 41 | | `underfit` | `train_auc < 0.70` 或 `train-oot gap < 0.005` | |
| 42 | | `overfit` | `train-oot gap > 0.05` | |
| 43 | | `unstable_psi` | `train→oot psi > 0.10` | |
| 44 | |
| 45 | 4. **推荐超参**(algo-aware): |
| 46 | |
| 47 | xgb 策略表: |
| 48 | |
| 49 | | 状态 | 动作 | |
| 50 | |---|---| |
| 51 | | underfit | depth+1, mcw/2, lr/2, n_est×1.5(各受 bounds 约束) | |
| 52 | | overfit | depth-1, reg_lambda×2, mcw×2 | |
| 53 | | underconverged | n_estimators ×2(受上限 2000 约束) | |
| 54 | | unstable_psi | subsample -0.1, colsample_bytree -0.1(受下限 0.5 约束) | |
| 55 | | well_fit | 不动 | |
| 56 | |
| 57 | dnn 策略表: |
| 58 | |
| 59 | | 状态 | 动作 | |
| 60 | |---|---| |
| 61 | | underfit | lr×2, dropout×0.7, epochs×1.5 | |
| 62 | | overfit | dropout+0.1, weight_decay×2 | |
| 63 | | underconverged | epochs×2, patience+5 | |
| 64 | | unstable_psi | dropout+0.1, batch_size×2(减梯度噪声) | |
| 65 | | well_fit | 不动 | |
| 66 | |
| 67 | lr 策略表: |
| 68 | |
| 69 | | 状态 | 动作 | |
| 70 | |---|---| |
| 71 | | underfit | C×2(减弱正则), max_n_bins+2(更细 WoE 分箱) | |
| 72 | | overfit | C/2(加强正则), max_n_bins-2 | |
| 73 | | underconverged | max_iter×2 | |
| 74 | | unstable_psi | max_n_bins-2, min_bin_size×2(粗分箱更稳) | |
| 75 | | well_fit | 不动 | |
| 76 | |
| 77 | 5. **问用户**:打印诊断 + 推荐参数,要 `[Y/n]` 确认(`--auto-apply` 跳过) |
| 78 | 6. **训练**:`--method rule` 直接用推荐参数训练;`--method optuna` 在 baseline 周围 ±30% 搜索 `n_trials` 次,取 val_auc 最优 params 重训 |
| 79 | 7. **复用 classification-model-training 产物管线**:落八阶段产物到新 run_dir,`config.json.runtime` 含 `baseline_run / diagnosis / method / recommended_params / final_params / trials_log / baseline_metrics` |
| 80 | |
| 81 | ### 2.2 流程 B:特征筛选(select_features.py) |
| 82 | |
| 83 | ```bash |
| 84 | # 上游需要先跑 feature-analysis,产出含 stats/iv_table/psi_table.csv 的目录 |
| 85 | |
| 86 | python <skill_dir>/scripts/select_features.py \ |
| 87 | --baseline_run <session_dir>/new-models/xgb-v1 \ |
| 88 | --analysis_dir <session_dir>/sample-features/feature-analysis/analysis \ |
| 89 | [--version v1] \ |
| 90 | [--output_dir <session_dir>] \ |
| 91 | [--no-psi] [--no-iv] [--no-missing] \ |
| 92 | [--psi_threshold 0.10] \ |
| 93 | [--iv_threshold 0.02] \ |
| 94 | [--missing_threshold 0.95] \ |
| 95 | [--auto-apply] |
| 96 | ``` |
| 97 | |
| 98 | 执行步骤: |
| 99 | 1. **读 baseline**:同流程 A |
| 100 | 2. **算法直通**:同流程 A(按 baseline.algo 走 xgb / dnn / lr) |
| 101 | 3. **应用规则**(三条独立,可分别启停): |
| 102 | |
| 103 | | 规则 | 数据源 | 阈值 | 默认 | |
| 104 | |---|---|---|---| |
| 105 | | `high_psi` | `psi_table.csv.psi` | `> psi_threshold` | 0.10 | |
| 106 | | `low_iv` | `iv_table.csv.iv` | `< iv_threshold` 或 IV=NaN | 0.02 | |
| 107 | | `high_missing` | `stats.csv.missing_rate` | `> missing_threshold` | 0.95 | |
| 108 | |
| 109 | csv 不存在时对应规则**静默跳过**(不抛错,见 `selection_rules._read_csv`) |
| 110 | 4. **打印剔除明细**(分规则列出 + 总数),要 `[Y/n]` 确认(`--auto-apply` 跳过) |
| 111 | 5. **重训**:用 baseline 的 `used_params`(不调参) + 筛选后的特征集训练,落八阶段产物 |
| 112 | 6. `config.json.runtime` 含 `baseline_run / selection {kept/dropped/dropped_by_rule/thresholds/rules_enabled} / analysis_dir / final_params / baseline_metrics` |
| 113 | |
| 114 | ## 3. 参数说明 |
| 115 | |
| 116 | ### 3.1 run_tuning.py |
| 117 | |
| 118 | | 参数 | 必选 | 默认值 | 说明 | |
| 119 | |---|:---:|---|---| |
| 120 | | `--baseline_run` | ✅ | - | `classification-model-training` 产出的 baseline run 目录 | |
| 121 | | `--method` | 否 | `rule` | 调优方法:`rule`(规则推荐)\| `optuna`(贝叶斯搜索) | |
| 122 | | `--n_trials` | 否 | `30` | Optuna 搜索次数(仅 `--method optuna`) | |
| 123 | | `--version` | 否 | `None` | 新 run 显式版本号(仅纯版本号:`v1` / `v2` / `custom-tag`;**不要带 algo/suffix 前缀**如 `xgb-v1` / `tuned-v1` / `feat`,会被拦截报错,避免产出 `xgb-tuned-tuned-v1` 重复前缀目录);留空自动自增(xgb-tune |