4. 测试数据集构建工程

在医学影像模型鲁棒性测试中,模型本身往往不是最脆弱的环节,数据集才是。一个在公开数据集上Dice达到0.92的肝脏分割模型,换到另一家医院、另一台CT、另一套扫描协议的数据上,性能可能骤降到0.71。这种落差通常不来自算法,而来自数据集的构建方式。本章围绕数据采集、标注、清洗、划分、伦理合规与开源数据集六个环节,说明如何把"一堆DICOM文件"工程化为可用于鲁棒性评测的测试数据集。

一、数据采集:先定义分布,再决定来源

采集的第一步不是找数据,而是明确测试目标所对应的数据分布。鲁棒性测试关心的是"模型在什么条件下会失效",因此采集方案应围绕扰动维度设计,而不是单纯追求样本数量。常见的扰动维度包括:设备厂商(GE、Siemens、Philips、Canon)、层厚(0.625mm~5mm)、重建核(软组织核/骨核/肺核)、造影期相(平扫、动脉期、门脉期、延迟期)、患者群体(年龄、BMI、是否含金属植入物)以及扫描体位与呼吸状态。

工程上建议采用"分层配额采集":先确定每个扰动维度需要覆盖的层数,再按配额从各来源补齐。例如一个腹部CT鲁棒性测试集,可设定厂商4类、层厚3档、期相3档,理论组合36格,每格至少5例,则最低规模约180例。这样得到的测试集在统计上能支撑"按子集分组评估"的分析方式,而不是只给出一个总体指标。

采集时需同步记录元数据:设备型号、扫描参数(kVp、mAs、螺距、重建核)、层厚、像素间距、造影剂用量与注射速率、患者基本信息(脱敏后)。这些字段是后续分组分析和失效归因的依据,缺失元数据的数据在鲁棒性测试中价值会大幅降低。

二、标注:从"画得准"到"标得一致"

标注质量的核心指标不是单次准确率,而是标注者之间的一致性。对于分割任务,常用Dice系数衡量两名标注者的重合度:同一批20例数据由两位放射科医师独立勾画,若平均Dice低于0.85,说明标注规范存在歧义,需要先修订规范再扩大标注规模。

标注规范应明确边界定义。以肝脏分割为例,需要规定:是否包含胆囊窝、是否包含肝内血管、下腔静脉旁组织如何处理、肿瘤区域是否计入肝脏轮廓。这些细节若不在规范中写清,不同标注者会给出系统性差异,而这种差异会被误判为模型的不鲁棒。

对于分类或检测任务,建议采用"双人独立标注+第三人仲裁"流程。分歧样本单独归档,作为难例集保留,它们往往正是模型鲁棒性的关键测试点。标注工具方面,3D Slicer、ITK-SNAP、MONAI Label均可支持DICOM序列的逐层勾画与导出,导出格式建议统一为NIfTI或NRRD,并保留原始DICOM的SeriesInstanceUID以便溯源。

三、清洗:把"脏数据"变成可控变量

清洗不是简单删除异常,而是识别并分类处理。常见问题包括:重复病例(同一患者多次检查)、层间缺失或错序、金属伪影严重、标注与图像不对齐、像素值溢出、方向矩阵异常。处理策略应记录在案,因为"删掉了什么"本身会影响测试集的分布代表性。

一个可操作的清洗流程如下:先用pydicom批量读取元数据,检查SliceThickness、PixelSpacing、ImageOrientationPatient的一致性;再用SimpleITK检查图像与标注的几何对齐;对金属伪影可计算高密度像素占比,超过阈值(如5%)的层面标记为"伪影层"而非直接删除,在测试时作为独立子集评估。清洗后应输出一份数据质量报告,包含原始例数、剔除例数、剔除原因分布、剩余子集分布。

import pydicom, SimpleITK as sitk
ds = pydicom.dcmread(path)
assert abs(ds.SliceThickness - 1.0) < 1e-3
img = sitk.ReadImage(nii_path)
lab = sitk.ReadImage(label_path)
assert img.GetSize() == lab.GetSize()
assert img.GetSpacing() == lab.GetSpacing()

四、划分策略:测试集必须"独立"

随机按切片划分是医学影像中最常见的错误。同一患者的相邻切片高度相似,随机划分会导致训练集和测试集共享患者信息,指标虚高。正确做法是按患者划分(patient-level split),确保同一患者的全部序列只出现在一个子集中。

对于鲁棒性测试,还需要考虑"外部测试集":来自不同医院、不同设备的数据不参与训练和调参,仅用于最终评测。建议的划分比例为训练:验证:内部测试:外部测试 = 6:1.5:1.5:1,外部测试集应覆盖采集阶段设定的主要扰动维度。若样本量有限,可采用分层划分,保证各子集在厂商、层厚、期相上的分布尽量一致。

五、伦理与隐私合规

医学影像数据涉及患者隐私,合规是底线。DICOM文件中的PatientName、PatientID、BirthDate、StudyDate等字段必须脱敏,且脱敏后需检查私有标签(Private Tags)中是否残留身份信息。日期可采用"偏移法"处理:保留相对时间间隔,但整体平移一个随机天数,以保留随访时间关系而不暴露真实日期。

此外,数据使用需获得伦理审查批准(IRB)或等效授权,明确使用范围、存储期限和共享方式。若数据来自公开数据集,需核对其许可协议(如CC BY-NC-SA、CC0)是否允许用于模型测试与结果发表。跨境数据流动还需符合当地法规要求。

六、开源数据集介绍与选用

常用开源医学影像数据集包括:LiTS(肝脏肿瘤分割,131例训练/70例测试,CT)、BTCV(腹部多器官分割,30例,CT)、MSD(Medical Segmentation Decathlon,10个任务,涵盖脑、肝、肺、胰腺等)、BraTS(脑肿瘤分割,MRI多模态)、CheXpert(胸部X线,14类观察)、NIH ChestX-ray14(胸部X线,14类)。这些数据集适合作为基线测试,但需注意其采集条件相对单一,直接用于鲁棒性评测时可能低估真实场景下的性能下降。

选用开源数据集时,应检查:标注质量与一致性、是否提供患者级划分、元数据是否完整、许可是否允许测试用途。若用于鲁棒性测试,建议将其作为"内部测试集",再补充自采的外部测试集,形成"公开基线+本地扰动"的双层评测结构。

医学影像测试数据集构建工程链路 数据采集 厂商/层厚/期相 分层配额采集 标注 双人独立+仲裁 Dice一致性≥0.85 清洗 几何对齐检查 伪影层标记 划分 患者级划分 6:1.5:1.5:1 伦理合规 DICOM脱敏 IRB授权 输出:内部测试集 + 外部测试集 + 难例集 + 数据质量报告 按厂商/层厚/期相分组,支持子集鲁棒性评估 常用开源数据集与适用场景 LiTS 肝脏肿瘤CT分割 BTCV 腹部多器官CT MSD 10任务多模态 BraTS 脑肿瘤MRI多模态 CheXpert 胸部X线14类 选用要点:标注一致性 · 患者级划分 · 元数据完整性 · 许可协议允许测试用途 建议结构:公开数据集作内部基线 + 自采外部测试集覆盖本地扰动维度

把上述六个环节串起来,测试数据集构建的产出不应只是一批文件,而应是一份可追溯、可分组、可复现的评测资产:每例数据有来源与元数据,每个子集有明确的扰动标签,每次清洗有记录,每次划分有患者级隔离,每份数据有合规依据。只有这样的数据集,才能让鲁棒性测试的结果具备解释力——当模型在某个子集上掉点时,我们能说清是设备、层厚还是期相导致的,而不是笼统地归因于"数据不够好"。