☰
医学影像大模型评测:Recall@K 为什么不能横向排名
2026/10/27 23:32:21 网站建设 项目流程

医学影像大模型评测:Recall@K 为什么不能横向排名

一句话结论:把两个模型的 Recall@10 并排放在一起比大小,比的往往不是模型,而是候选池、数据集划分和样本量。

项

内容

摘要

10 月 26 日 Frontiers in Medicine 上线一篇覆盖 50 余项研究的综述,明确拒绝给医学视觉—语言模型排名。本文拆清它给的四条理由、13 篇研究的指标报告率、四类规范的职责边界,并用一个零依赖脚本量化候选池与样本量如何扭曲 Recall@K,最后给出六条可直接写进评测方案的校准线。

前置知识

检索指标 Recall@K 的含义;知道「验证集划分」与「置信区间」两个词

阅读时间

约 15 分钟

代码环境

Python 3.9+,零第三方依赖,不联网,输出确定(无随机源)

读完你能做什么

能在评审会上指出一份医学影像模型对比表里哪几列不可比;能给自己团队的评测方案补上候选池、划分、样本量三项声明;能说清 CLAIM 与 TRIPOD+AI 各自管什么

一手来源是 2026 年 10 月 26 日上线的综述《Vision–language foundation models for multimodal medical image understanding and report generation: a narrative review with quantitative synthesis》,载于Frontiers in Medicine(Volume 13 - 2026,Section Pathology),DOI10.3389/fmed.2026.1958283,作者 Shahid Mehmood 等 7 人,来自巴基斯坦 Bahria University、阿联酋 University of Sharjah、沙特 IMSIU、韩国 Gachon University 与马来西亚 UiTM。本文引用的数字与原文表述均出自该综述页面,涉及第三方转述处已单独标明。


一、这份综述到底说了什么

它做的不是荟萃分析,而是「带定量综合的叙述性综述」。原文在摘要里把立场写得很直接:

Drawing on more than 50 original studies published between 2020 and 2025, we provide a structured descriptive comparison rather than a statistical meta-analysis.

Because datasets, splits, candidate pools, and metrics differ, cross-task results are presented as exploratory benchmark indicators and not as a clinical-readiness scale.

两句话把边界划死了:这是结构化描述,不是合并统计;跨任务结果只是探索性基准指示,不是临床就绪量表。

它给出的模型数字,本文原样摘录(表中 NR = 原综述标注 not reported,破折号 = 原表未报告,均不等于零分):

模型

任务

指标

数值

数据集/规模

BiomedCLIP (2023)

图文检索

Recall@1

0.58

PMC-15M,1500 万图文对

BiomedCLIP (2023)

图文检索

Recall@5 / Recall@10

0.82 / 0.89

同上

GLoRIA (2021)

图文检索

Recall@1 / Recall@5 / Recall@10

0.51 / 0.78 / 0.87

MIMIC-CXR,37.7 万影像

ConVIRT (2022)

图文检索

Recall@10

0.81(Recall@1 未报告)

MIMIC-CXR

MMBERT (2021)

医学 VQA

VQA-RAD 准确率

62.5%

VQA-RAD

MedViLL (2022)

医学 VQA

VQA-RAD 准确率

67.8%

MIMIC-CXR、VQA-RAD

看这张表最容易犯的错,就是把 0.89、0.87、0.81 三个数排个序,然后说 BiomedCLIP 比 GLoRIA 好。综述在 Table 7 的说明里专门堵了这个口子:

Recall@K is protocol dependent. Dataset, split, retrieval direction, candidate-pool size, and preprocessing must match before systems are compared.

Retrieval values are not directly rankable across different datasets, candidate-pool sizes, directions, splits, and preprocessing pipelines.

二、为什么 Recall@K 会随候选池漂移

候选池就是检索时的候选集合大小。同一个模型,从 200 条里找和从 5000 条里找,Recall@10 的绝对值完全不是一回事——因为随机基线就是K / N。

这事的机制不复杂,但后果被严重低估:候选池扩大 N 倍,随机的命中概率就缩小 N 倍,所以同样的模型能力,在大池子里看起来「变差」,其实是任务变难。要跨池比较,得看相对随机基线的提升倍数,而不是绝对值。

三、动手验证:把候选池与样本量的影响算出来

下面这段脚本不装任何依赖,直接python recall_pool_drift.py就能跑。它把模型能力固定成一个参数(正例与负例得分分布的距离 d'),只让候选池变化,看 Recall@10 怎么动;再算同一个观测值在不同测试集规模下的 Wilson 置信区间。

import math K = 10 # 取前 10 个结果 DPRIME = 2.5 # 模型能力(正例与负例得分分布的距离),固定不动 def log_binom_pmf(n: int, i: int, p: float) -> float: """二项分布 pmf 的对数,用 lgamma 避免大组合数溢出。""" if p <= 0.0: return 0.0 if i == 0 else -math.inf if p >= 1.0: return 0.0 if i == n else -math.inf return (math.lgamma(n + 1) - math.lgamma(i + 1) - math.lgamma(n - i + 1) + i * math.log(p) + (n - i) * math.log1p(-p)) def binom_cdf(n: int, k: int, p: float) -> float: """P(X <= k),X ~ Binom(n, p)。这里 k 很小,直接累加前 k+1 项。""" return math.fsum(math.exp(log_binom_pmf(n, i, p)) for i in range(k + 1)) def recall_at_k(pool: int, k: int = K, dprime: float = DPRIME) -> float: """ 正例落在前 k 名的概率。 对正例得分做数值积分:给定得分 x,负例超过 x 的个数 ~ Binom(pool-1, Φ(-x)), 要求其 <= k-1。 """ total, wsum = 0.0, 0.0 x = dprime - 6.0 while x <= dprime + 6.0: w = math.exp(-0.5 * (x - dprime) ** 2) # 未归一化的正态密度 q = 0.5 * math.erfc(x / math.sqrt(2.0)) # 单个负例超过 x 的概率 total += w * binom_cdf(pool - 1, k - 1, q) wsum += w x += 0.01 return total / wsum def random_baseline(pool: int, k: int = K) -> float: """随机排序下正例进入前 k 的概率,就是 k / N。""" return min(1.0, k / pool) def wilson_interval(hits: int, total: int, z: float = 1.96): """Wilson 分数区间:样本量小的时候比正态近似稳得多。""" if total == 0: return (0.0, 0.0) p = hits / total denom = 1 + z * z / total center = (p + z * z / (2 * total)) / denom margin = z * math.sqrt(p * (1 - p) / total + z * z / (4 * total * total)) / denom return (max(0.0, center - margin), min(1.0, center + margin)) def main(): print(f"模型能力固定 d' = {DPRIME},只改候选池大小,k = {K}") print() print(f"{'候选池 N':>8} | {'Recall@10':>9} | {'随机基线':>9} | {'提升倍数':>9}") print("-" * 44) for n in (200, 500, 1000, 2000, 5000): r = recall_at_k(n) base = random_baseline(n) print(f"{n:>8} | {r:>9.3f} | {base:>9.4f} | {r / base:>8.0f}x") print() print("=== 测试集样本量对 95% 置信区间宽度的影响(观测 Recall@10 = 0.58)===") print(f"{'样本量 n':>9} | {'命中数':>6} | {'95% Wilson 区间':>22} | {'半宽':>7}") print("-" * 56) for n in (30, 100, 300, 1000): hits = round(0.58 * n) lo, hi = wilson_interval(hits, n) print(f"{n:>9} | {hits:>6} | [{lo:.3f}, {hi:.3f}]{'':>5} | {(hi - lo) / 2:>7.3f}") if __name__ == "__main__": main()

本机实跑(Windows,Python 3.13.12)输出:

模型能力固定 d' = 2.5,只改候选池大小,k = 10 候选池 N | Recall@10 | 随机基线 | 提升倍数 -------------------------------------------- 200 | 0.796 | 0.0500 | 16x 500 | 0.665 | 0.0200 | 33x 1000 | 0.562 | 0.0100 | 56x 2000 | 0.464 | 0.0050 | 93x 5000 | 0.348 | 0.0020 | 174x === 测试集样本量对 95% 置信区间宽度的影响(观测 Recall@10 = 0.58)=== 样本量 n | 命中数 | 95% Wilson 区间 | 半宽 -------------------------------------------------------- 30 | 17 | [0.392, 0.726] | 0.167 100 | 58 | [0.482, 0.672] | 0.095 300 | 174 | [0.523, 0.634] | 0.056 1000 | 580 | [0.549, 0.610] | 0.031

两个结论可以直接拿去用:

  • 候选池从 200 扩到 5000,同一个模型的 Recall@10 从 0.796 掉到 0.348,而相对随机基线的提升从 16 倍涨到 174 倍。掉下去的那部分不是能力损失,是任务难度。看到跨论文的 Recall@K 对比表,先问一句候选池多大。
  • 测试集 30 例时,95% 区间的半宽是 0.167。两个模型点估计差 0.05,在这个样本量下和没差别是一回事。综述里那些两三个点的差距,多数属于这一类。

四、13 篇研究的指标报告率:缺的不是指标,是配套信息

综述对 13 篇研究做了一次来源审计,分母统一为 13:

报告项

篇数

占比

BLEU/ROUGE

4

31%

RadGraph F1

0

0%

CheXpert/CheXbert 标签评估

6

46%

BERTScore

1

8%

人类专家评估

4

31%

推理延迟或吞吐

0

0%

综述自己加了一句限定:这些比例只描述被展示的审计样本,不构成领域总体估计。但两项 0% 很有信息量——没有一篇报告推理延迟或吞吐。对要落在读片流程里的系统,延迟和能不能横向扩展,是和准确率同量级的约束条件,却在公开证据里整体缺席。

关于「不排名」,综述在 5.5.1 节给了操作口径:

The source audit in Table 4 shows that direct longitudinal ranking is not defensible when models address different tasks or use different evaluation protocols.

Comparisons should therefore be restricted to studies using the same dataset, patient-level split, preprocessing, and evaluation implementation.

VQA 那边同理。Table 6 的注脚写明:VQA-RAD、SLAKE、PathVQA、ImageCLEF VQA-Med 在答案格式、划分构造、归一化与临床语境上各不相同,模型或数据集之间的表面差异应被理解为基准特异的,而不是共同的成熟度标尺。

五、常见误区

误区一:把破折号当 0 分。综述在 Table 4 注脚专门写了A dash or 'not reported' should not be interpreted as zero performance。ConVIRT 的 Recall@1 是未报告,不是测出来为零。

误区二:把「遵循报告规范」当成「拿到监管许可」。原文措辞是:遵循报告指南本身不构成监管授权(adhering to reporting guidelines does not itself constitute regulatory authorization)。CLAIM 是报告清单,不是通行证。

误区三:跨任务合成一个总分。Table 8 的标题就写着Exploratory cross-task evidence summary (not a clinical-readiness scale),并注明各行指标测的是不同构念。

误区四:把单中心回顾性结果当普遍结论。综述在 roadmap 里把外部验证与亚组验证写进最低标准,正是针对这一点。

误区五:只看准确率不看延迟。13 篇里 0 篇报告延迟或吞吐,这不代表延迟不重要,只代表公开证据存在缺口。自己评测时不要继承这个缺口。

六、工程落地:六条可以写进评测方案的校准线

综述第 9 节提出了「最低临床验证与报告标准」,对齐 FDA/Health Canada/MHRA 与 IMDRF 的良好机器学习实践、EU AI Act、TRIPOD+AI 与 CLAIM。落到一份能执行的内部评测方案,可以拆成六条:

校准线

要声明/要做的事

对应规范职责

数据溯源

数据来源、许可、脱敏方式、入排标准

报告类

患者级划分

按患者而非按影像切分,写明划分比例与随机种子

报告类(TRIPOD+AI)

指标与区间

主指标 + 95% 置信区间,样本量写进表里

报告类

候选池与协议

检索任务的候选池大小、检索方向、预处理

报告类(CLAIM)

外部与亚组验证

至少一处外部数据 + 按人群/设备亚组拆分

生命周期实践(GMLP)

部署后监控

上线后的性能监测与回退路径

生命周期实践(GMLP)

四类规范不是一回事,混用会出事:TRIPOD+AI 与 CLAIM 属报告指南,GMLP 属生命周期实践,EU AI Act 属法律义务,适用与否取决于司法辖区与预期用途。综述明确提出这份清单要区分 reporting guidance、lifecycle practice 与 legal obligations 三类。

七、适用边界与产业坐标

这份综述的适用范围是医学影像的视觉—语言基础模型,不包括纯文本临床大模型,也不覆盖手术机器人一类的控制类系统。它的结论强度也有限定:作者给出的十一项优先方向里,RAG grounding、知识图谱推理、时序建模、联邦学习都还停在「待研究」,不是已验证结论。

把视角从论文拉回工程:医学影像类模型真正进到医院里,卡点往往不在模型本身,而在它前面那圈东西——影像与报告的调阅链路、与既有系统的接口、数据不出域的部署形态。综述在数据侧提到的隐私顾虑(去标识不能完全排除模型记忆到具体患者影像或文本)在工程上会转化成一条硬约束:推理与数据都得放在院内,出域通路要能被审计。

这类形态在信创环境里通常由两层承接:平台层负责部署编排与资源隔离,集成层负责把模型能力包成业务系统可调用的接口,并把调用留痕。金蝶天燕 Apusic 这条线上,AAS 应用服务器承担院内应用的承载,ADMQ 分布式消息队列承担影像调阅与报告回传这类异步链路,两者要满足的不是峰值数字,而是数据不出域的前提下接口仍然可管、可审计。至于模型与产品之间的适配口径,以各自的官方文档为准。

八、结论

  • 综述覆盖 50 余项 2020–2025 年的研究,给出的定位是结构化描述性比较,不是荟萃分析,也不是临床就绪量表。
  • Recall@K 是协议依赖的指标:数据集、划分、检索方向、候选池大小、预处理必须对齐才可比较。固定能力下,候选池从 200 到 5000 会让 Recall@10 从 0.796 变到 0.348,而提升倍数从 16 倍涨到 174 倍。
  • 13 篇研究中推理延迟与吞吐的报告率为 0%,这是公开证据的缺口,不是可以忽略的理由。
  • CLAIM、TRIPOD+AI、GMLP、EU AI Act 分属报告指南、生命周期实践与法律义务三类,混用会把报告合规误当成准入。

问一句:你们团队的模型对比表里,有没有写明候选池大小和测试集样本量?如果这两列是空的,表里的排名大概率是噪声。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询