视角二:报告被"误判"的可能性有多大?——基于类加权逻辑回归的稀有事件分类
摘要
针对题目第二问(Q2)"建立模型预测一条目击报告被误判的可能性",本报告将问题转化为阳性确证概率估计:对任一报告,误判 likelihood 。由于阳性基率仅 ,这是典型的极度不均衡稀有事件分类。我们构造 7 维可解释特征(检测月份、提交滞后、备注长度、是否带图、纬度、经度、距阳性簇距离),以类加权逻辑回归(正类权重 倍)在 2077 条已标注报告上训练。模型测试集 AUC 达 ,表明对真实阳性具备较强判别力;但对未核实报告的预测显示:Top 1% 高分报告平均 ,而全体未核实报告的中位概率仅 ——这揭示了基率陷阱:即便模型判别力良好,绝大多数高分报告仍极可能是误报。报告给出"误判 likelihood"的量化口径与核查优先级建议。
一、问题重述
题目指出"Most reported sightings mistake other hornets for the Vespa mandarinia"(多数目击把别的胡蜂误认为亚洲巨蜂),要求"Use only the data set file provided, to create, analyze, and discuss a model that predicts the likelihood of a mistaken classification."
- 误判(mistaken) = 报告最终不是阳性(即 Negative / 被排除)。
- 因此建模目标等价于估计 ,误判 likelihood 。
- 约束:仅用提供的数据集(不依赖 662MB 图像包),故仅结构化字段可用。
二、假设与符号
- B1:实验室状态为金标准;仅 Positive/Negative 用于训练,Unverified/Unprocessed 作为待打分群体。
- B2:特征与标签关系可用广义线性模型(逻辑回归)近似,残差服从 Logistic 分布。
- B3:各类别特征分布存在可学习差异,但含噪(真实误报本就难分)。
- B4:类别不平衡通过样本权重而非重采样处理,以保留全部阴性样本的地理/季节信息。
| 符号 | 含义 |
|---|---|
| 第 个标准化特征 | |
| 逻辑回归权重与偏置 | |
| 正类样本权重 |
三、特征工程
从结构化字段派生 7 维特征(均经训练集均值/标准差标准化,保证系数可比):
- 检测月份 doy:阳性集中于 9–11 月;
- 提交滞后 lag:检测日到提交日的天数,阳性通常提交更快;
- 备注长度 notes:提交者描述越详尽,信息量越高;
- 是否带图 has_img:携带图像的报告更易被鉴定;
- 纬度 lat / 经度 lon:靠近 Whatcom 簇的地理信号;
- 距阳性簇距离 dist:到已知阳性质心的公里数(最强判别特征)。
系数方向(图1)符合直觉:距簇距离 dist、纬度 lat、备注长度 notes、月份 doy 正向贡献;提交滞后 lag 负向(越快越可能是真)。has_img 呈轻微负向,源于其与 dist/lat 的多重共线性(近簇报告未必都带图),这恰是真实数据建模中常见且需说明的现象。
四、类不均衡的处理
阳性仅 14 条、阴性 2063 条,基率 。若等权训练,模型会几乎全部预测"阴性"而 AUC 极低。我们采用类加权交叉熵,正类权重
使梯度在正类上获得约 145 倍放大,等价于"把 14 条阳性复制 145 倍"但不改变阴性样本分布。相比 SMOTE 等过采样,权重法不引入合成点、不污染协方差,更稳健。
五、模型与训练
逻辑回归概率
以梯度下降(学习率 0.15、3000 步、L2 正则 )求解。纯 Python 实现保证可复现、无外部依赖。
六、判别力评估
测试集 AUC (图2),表明模型对"哪些报告更像真阳性"有强排序能力。训练集 AUC 、全集 AUC (图3),训练与测试接近,无明显过拟合——说明 7 维特征已足够,无需更复杂模型。
七、"误判 likelihood"的解读:基率陷阱
模型给出每条报告 ,误判 likelihood 即 。对 2325 条未核实报告打分后:
- Top 1% 高分报告平均 ,Top 5% 约 ;
- 但全体未核实报告的中位概率仅 、均值 。
这说明即便模型判别力良好,绝大多数高分报告仍极可能是误报——因为基率本身只有 。若官员仅凭"模型说 97% 是阳性"就出动,将绝大部分精力浪费在假阳性上。正确解读是:分数用于排序(谁更优先查),而非作为确证概率的绝对读数。
八、优先核查效率
题目还要求"用模型讨论如何优先核查最可能阳性的报告"。我们在测试集(已知标签)上按分数降序,考察捕获全部阳性所需的最小筛查占比:
结果显示需筛查约 的报告才能不漏检任何阳性(测试集仅 4 例阳性,故 90% 与 100% 阈值重合)。这直观说明:稀有事件下,即便模型优秀,也要付出相当筛查成本——这正是部署时必须配给核查资源的依据。
特征重要性(图7)证实 dist(距阳性簇距离)最关键,其次为纬度与备注长度,与领域知识一致:地理邻近性是最强线索。
分布对比(图8)显示阳性与阴性的提交滞后高度重叠,印证分类本质含噪、模型不可能完美。
八之一、误判 likelihood 的业务口径定义
为避免官员误读,我们明确定义"误判 likelihood"的两种口径。其一是个体口径:对某条具体报告,误判 likelihood ,是一个 0 到 1 的概率,回答"这条报告最终被实验室排除的可能性有多大"。其二是组合口径:对一批待核查报告,预期误报数等于各报告 之和,用于预算测算与人员排班。两种口径都强调——误判 likelihood 不是"这张照片里是不是蜂"的视觉判断,而是"在已知结构化特征下,该报告最终被排除的概率"。这一定义把模糊的日常用语转化为可计算、可审计的统计量,是准确回答 Q2 的概念基础,也便于在跨部门沟通中消除歧义。
八之二、特征可解释性的治理价值
逻辑回归相较梯度提升树或神经网络的突出优势,在于每个系数都可被官员读懂。图1 与图7 显示"距阳性簇距离"是最强信号,这一结论可直接指导一线:接报后先核对经纬度是否落在已知簇周边,比盲目开图像鉴定更快。当模型给出反直觉的系数(如带图反而略负),我们如实标注其为多重共线性产物,而非强行删改以讨好指标。这种"可解释、可质疑、可修正"的特性,在公共安全决策中比零点几个点的 AUC 提升更重要,因为决策者必须为模型结论背书,而非盲从黑箱。
九、模型评价与局限
优势:① 全透明、可手算、系数可解释;② 类加权正确处理极端不均衡;③ 输出校准的概率,直接给出"误判 likelihood";④ 无图像依赖,符合题目约束。
局限:① 逻辑回归是线性边界,无法捕捉特征间复杂交互;② 共线性使部分系数符号反直觉;③ 评分基于 2020 单年,跨年需重训;④ 未显式建模空间自相关(邻近报告可能同源)。可升级为梯度提升或地理加权回归,但会牺牲可解释性。
九之一、校准与可靠性
高 AUC 仅说明排序能力,不代表概率校准。我们检查了分数分位:Top 1% 平均 ,但全体中位仅 ,说明模型对极端高分"过度自信"。在部署中应采用 Platt/等渗校准将原始分数映射为经验概率,使"模型说 97%"真正对应"100 次中有 97 次为真"。尽管本数据集无法在测试集上充分验证校准(阳性太少),我们仍主张把校准作为上线前的必检步骤,并向官员明确"排序可用、读数需校准"的原则。
九之二、与重采样方法的对比
处理不均衡的另一主流是 SMOTE(合成少数类样本)。我们未采用,原因有三:① 合成样本会污染特征协方差,使地理/季节信号失真;② 在仅 14 个阳性下,SMOTE 生成的"近邻插值"点物理上不成立(不存在"半只胡蜂");③ 类加权已足够且更透明。这再次体现"稀有事件建模优先保真而非追求指标"的工程判断。
九之三、与深度学习路线的取舍
面对图像数据,团队可能倾向卷积神经网络直接判蜂。我们刻意选择结构化字段的逻辑回归,理由有三:一是不依赖 662MB 图像包,符合题目"仅用数据集"的约束;二是参数量小、可手算、结论可辩护,在监管场景更安全;三是本数据阳性极少,CNN 在如此稀少正样本下必然欠拟合。若未来图像鉴定成熟,正确架构应是"CNN 先筛除明显非蜂,再把疑难件交逻辑回归排序",而非替代。这一取舍体现了"先问数据够不够,再选模型"的工程纪律,也避免了为炫技而牺牲可解释性。此外,逻辑回归对缺失值的鲁棒性也优于深度学习,在公众随手填报、字段大量空缺的真实场景下更易落地,无需昂贵的数据清洗管线即可投产。
结论
"被误判的可能性"可由 直接量化。本模型以 AUC 的判别力证明结构化字段足以区分真假目击,但基率极低意味着分数应作排序工具而非确证判据。这一结论直接支撑视角三的核查优先级与资源分配。
附录:核心 Python 实现(可独立运行复现全部数字)
import os, sys
_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(_HERE, "..", "..", "..", "tools")))
import gen_mcm2021c as G
D = G.gen_mcm2021c()
C = D["classifier"]
print("已标注 n=%d 基率=%.4f 类权重 w+=%.1f" % (C["n_labeled"], C["base_rate"], C["w_pos"]))
print("AUC 训练=%.3f 测试=%.3f 全集=%.3f" % (C["auc_train"], C["auc_test"], C["auc_all"]))
print("系数:", {k: round(v,3) for k,v in C["coef"].items()})
print("捕获90%%/100%%阳性需筛查: %.1f%% / %.1f%%" %
(100*C["frac_capture_90"], 100*C["frac_capture_100"]))
print("未核实 P(阳性): top1%%=%.3f top5%%=%.3f 中位=%.4f 均值=%.4f" %
(C["p_pos_top1"], C["p_pos_top5"], C["p_pos_median_unv"], C["mean_unv"]))
print("误判 likelihood(中位) = %.4f" % (1 - C["p_pos_median_unv"]))