# Final Ensemble ## 正式最终系统 本仓库的正式最终系统是一个 **7-voter Logistic Regression Stacking** 方案。它不是规则硬投票,也不是探索阶段的静态加权投票,而是基于连续分数学习出来的 stacking 模型。 正式结果入口: - `results/final-system/ds13/ensemble_meta.json` - `configs/ensemble_config.json` - `results/final-system/upstream-voters/ds13/` ## 7 个 voter 包含什么 | Voter | 类型 | 仓库里保留的资产 | 在最终系统中的角色 | |---|---|---|---| | `qwen7b_general` | LoRA adapter | `models/qwen-adapters/general/` | 通用主力分支 | | `qwen7b_short` | LoRA adapter | `models/qwen-adapters/short/` | 补强 76-180 字短文本 | | `qwen7b_extreme_short` | LoRA adapter | `models/qwen-adapters/ultra-short/` | 补强 0-75 字极短文本 | | `bert` | 微调分类模型 | `models/bert-final/` | 最终 LR 权重最高 | | `roberta` | 微调分类模型 | `models/roberta-final/` | 与 BERT 和 Qwen 分支形成互补 | | `FastDetectGPT` | 零样本 detector | 算法脚本 + 结果文件 | 提供生成痕迹分数 | | `Binoculars` | 零样本 detector | 算法脚本 + 结果文件 | 提供另一类生成痕迹分数 | 这里最容易被误解的是最后两个 detector。`FastDetectGPT` 和 `Binoculars` 不是单独训练出来的新分类模型,它们是零样本检测算法分支: - `FastDetectGPT` 使用 `Qwen2.5-3B-Instruct` 与 `Qwen2.5-3B` 的对比分数。 - `Binoculars` 也基于同一对 3B 模型,只是打分公式不同。 - 对应实现位于 `scripts/inference/run_zero_shot_detectors.py`。 因此仓库不会给这两个 detector 单独保存“分类器权重目录”。它们的可交付形式是:算法说明、推理脚本、实验留档和最终分数文件。 ## 最终权重如何确定 正式 DS13 系统的权重学习流程如下: 1. 收集 7 个 voter 在 dev 上的连续输出分数。 2. 构造特征矩阵,并额外加入长度特征 `len_norm = length / 1000.0`。 3. 通过 `StandardScaler` 标准化特征。 4. 用 `sklearn.linear_model.LogisticRegression(solver="lbfgs", C=1.0)` 拟合二分类 stacking 模型。 5. 在 dev 上按 F1 搜索最优阈值,得到最终推理阈值。 对应实现可从 `scripts/inference/run_logistic_regression_ensemble.py` 看出,正式参数以结果文件为准,而不是以脚本默认参数猜测。 ## DS13 正式 LR 系数与阈值 以下数字直接来自 `results/final-system/ds13/ensemble_meta.json` 与 `configs/ensemble_config.json`: | Feature | Coefficient | |---|---:| | `bert` | 2.0188854029 | | `qwen7b_general` | 1.8788706258 | | `roberta` | 1.8788624937 | | `qwen7b_short` | 1.2970493780 | | `qwen7b_extreme_short` | 0.8596312618 | | `FastDetectGPT` | 0.2563906985 | | `Binoculars` | 0.2295749248 | | `len_norm` | 0.0062348417 | 补充参数: - `intercept = 1.6861943699` - `threshold = 0.1307` 可以直接把这些系数理解成“正式最终系统的权重”。如果有人去看 `src/enhanced_replica/voter_registry.py`,会看到 `default_weight_champion` 和 `bucket_weights`。这些值属于 E04 / E06 探索阶段的硬投票默认值,只服务于探索期脚本,不代表正式最终 DS13 ensemble 权重。 ## 分桶方式与 DS13 的 fallback 本仓库保留的 bucket 定义为: - `extreme_short = 0-75` - `short = 76-180` - `general = 181+` DS13 正式 bundle 虽然同时保存了 `lr_global` 和 `lr_bucket` 两套结果,但 `lr_bucket` 在 DS13 上没有学出单独桶模型,而是全部回退到 global: | Bucket | `n_dev` | 是否回退到 global | |---|---:|---| | `extreme_short` | 1 | 是 | | `short` | 0 | 是 | | `general` | 9 | 是 | 这意味着: - DS13 的 bucket 流程被保留了。 - 但因为 dev 样本极少,正式结果实际上等价于 global LR。 - 所以 DS13 上讨论“bucket 权重”没有意义,真正需要看的就是全局 LR 系数。 ## 为什么会回退到 DS01 dev DS13 dev 过小,不足以稳定拟合 7-voter LR stacking。因此最终配置明确采用了 fallback 思路:用更稳定的 dev 参考来拟合 LR,再迁移到 DS13 test 评估。仓库里保留 `results/final-system/ds01-reference/`,是为了让这条 fallback 逻辑有一个可追溯的参考 bundle。 需要注意的是,`ds01-reference` 是参考证据区,不是第二个正式最终系统入口。对于 DS13 的正式最终权重,始终以: - `results/final-system/ds13/ensemble_meta.json` - `configs/ensemble_config.json` 为准。 ## DS13 正式最终结果 ### 总体结果 - `F1 = 0.986091` - `Accuracy = 0.986182` - `Precision = 0.992448` - `Recall = 0.979815` ### 子集结果 | Subset | N | F1 | Precision | Recall | Accuracy | |---|---:|---:|---:|---:|---:| | `normal` | 4000 | 0.997505 | 0.995518 | 0.999500 | 0.997500 | | `mixed_attack` | 1000 | 0.962810 | 0.993603 | 0.933868 | 0.964000 | | `paraphrase_attack` | 1000 | 0.979675 | 0.995868 | 0.964000 | 0.980000 | | `perturbation_attack` | 1000 | 0.996000 | 0.996000 | 0.996000 | 0.996000 | | `len_64` | 1000 | 0.940452 | 0.966245 | 0.916000 | 0.942000 | | `len_128` | 1000 | 0.982880 | 0.989858 | 0.976000 | 0.983000 | | `len_256` | 1000 | 0.994995 | 0.995992 | 0.994000 | 0.995000 | | `len_512` | 1000 | 0.998004 | 0.996016 | 1.000000 | 0.998000 | 这里最值得保留的结论是:短文本仍然最难,`len_64` 明显低于长文本段。这也解释了为什么最终系统没有只保留一个通用 Qwen 分支,而是把 `short` 和 `extreme_short` 两个长度专门化 adapter 一起保留下来。 ## 上游 voter 结果为什么也要保留 `results/final-system/upstream-voters/ds13/` 保存了 7 个 voter 的 dev / test 输出。保留它们不是为了让人手动拼装提交,而是为了做到两件事: 1. 让最终 DS13 ensemble 可追溯。 2. 让后续研究者能直接看到每个 voter 的分数文件,从而复算 stacking、阈值与误差来源。 ## 一句话区分两类“权重” - 正式最终系统权重:看 `results/final-system/ds13/ensemble_meta.json` 和 `configs/ensemble_config.json`。 - 探索期硬投票默认值:看 `src/enhanced_replica/voter_registry.py`,只属于 E04 / E06 研究路线。