从大厂转行医疗AI,我在eICU数据集上踩的5个坑

发布时间:2026/7/29 2:19:21

从大厂转行医疗AI,我在eICU数据集上踩的5个坑 作为一个在互联网大厂做了五年推荐系统的算法工程师今年初我转到了医疗AI方向。本以为数据处理这块自己轻车熟路结果第一个项目用eICU数据集就连续踩坑。这篇文章记录我踩过的5个坑希望能帮同样跨界的朋友少走弯路。先说背景我所在的新团队在做ICU死亡预测模型数据集选的是eICU-CRDeICU Collaborative Research Database。这个数据集是MIT和Philips Healthcare在2018年联合发布的覆盖美国208家医院的335个ICU单元总共20万次住院记录。选它的原因很简单多中心数据可以按医院划分训练集和测试集评估模型的跨机构泛化能力。这在医疗AI里是刚需——你不可能只在一个医院的数据上验证了就敢说模型”通用”。在大厂做推荐的时候数据管道、特征工程、模型训练这套流程我闭着眼睛都能跑。但医疗数据和用户行为日志完全是两个世界。以下是我踩的5个坑按”踩坑时间”排序。坑1vitalPeriodic表里的-1不是零不是正常值是”没采到”这个坑我第一天就踩了。eICU里最核心的表是vitalPeriodic存的是每5分钟一次的生命体征——心率、呼吸频率、血氧、血压、体温。我在做特征聚合的时候直接对每个住院时段取了均值、标准差。# 我的第一版代码有问题 vitals vitalPeriodic.groupby(patientUnitStayID).agg({ heartrate: [mean, std, min, max], systemicsystolic: [mean, std, min, max], temperature: [mean, std, min, max] })跑出来发现一部分患者的心率均值是负数。第一反应是数据有脏数据直接filter掉了。直到review的时候被组里的临床医学背景同事指出-1在eICU里表示”信号中断/设备未连接”不是零不是异常值就是”这个时间点没有采集到数据”。正确的处理方式# 把-1替换为NaN再做聚合 vital_cols [heartrate, systemicsystolic, systemicdiastolic, sao2, respRate, temperature] for col in vital_cols: vitalPeriodic[col] vitalPeriodic[col].replace(-1, np.nan) vitals vitalPeriodic.groupby(patientUnitStayID).agg({ heartrate: [mean, std, min, max], systemicsystolic: [mean, std, min, max], temperature: [mean, std, min, max] })改完之后模型的AUROC从0.72直接跳到了0.79。就这一个改动。教训医疗数据里的特殊编码是”语义信息”不是”脏数据”。在互联网公司处理日志缺失值往往是NULL或者空字符串在医疗数据里-1、-99、空字符串、”89”都可能各有含义。处理之前必须先搞清楚编码规则。坑2nurseCharting和vitalPeriodic不是一回事第二个坑更隐蔽。我在做特征的时候发现生命体征数据有两个来源vitalPeriodic监护仪自动采集5分钟一次和nurseCharting护士手动录入。一开始我以为是冗余数据就只用了vitalPeriodic。后来做误差分析的时候发现有一批患者的生命体征数据严重缺失——覆盖率只有30%左右。排查了半天才发现这些患者所在的ICU没有接入Philips的监护仪系统所以vitalPeriodic里根本没有他们的数据但护士手写的nurseCharting里有。两个表的区别维度vitalPeriodicnurseCharting采集方式监护仪自动护士手动录入时间粒度5分钟不固定数据来源床旁设备护理记录系统可信度设备级未临床验证护士验证级覆盖率约99%医院约99.5%医院问题在于这两个表的数据不能直接互换使用。vitalPeriodic的值是设备原始读数nurseCharting的值经过了护士的临床判断筛选。比如血压异常高的时候护士可能会复测一次再记录而监护仪会忠实地记录每一次读数。最终的解决方案是对vitalPeriodic缺失的患者用nurseCharting做补充但聚合策略不同——自动采集的用时间窗口聚合护士记录的取最近一次有效值。教训医疗数据里同一个概念可能有多个数据来源它们的语义和可信度不同。在互联网公司同一个指标比如”点击”一般只有一种定义在医疗数据里”心率”可以是设备读数、护士记录、或者APACHE评分里的值含义各不相同。坑3labname字段没有标准化同一检验有十几个名字这个坑在特征工程阶段才暴露出来。eICU的lab表存的是实验室检验结果字段labname是检验项目名称。我想提取几个核心检验指标血钾、血钠、肌酐、白细胞计数天真地以为直接匹配就行# 天真的做法漏掉大量数据 potassium lab[lab[labname] potassium]结果发现血钾的记录数远少于预期。打印出所有包含”potass”的labnamepotassium potassium, whole blood potassium..serum potassium (serum) potassium (whole blood) potassium, serum K # 有的甚至缩写了同一个检验在labname里有6种以上的写法。这是因为eICU的数据来自208家医院每家医院的LIS实验室信息系统命名规则不同数据入库时没有做标准化映射。最终我不得不手动维护一个映射表lab_name_mapping { # 血钾 potassium: potassium, potassium, whole blood: potassium, potassium..serum: potassium, potassium (serum): potassium, potassium (whole blood): potassium, potassium, serum: potassium, # 血钠 sodium: sodium, sodium, whole blood: sodium, sodium..serum: sodium, sodium (serum): sodium, # ... 以此类推 } lab[labname_normalized] lab[labname].map(lab_name_mapping)教训多中心数据集的字段值不保证标准化。在大厂的数据仓库里维度表和事实表有严格的schema约束同一个指标的名字是唯一的。但在医疗多中心数据集里”同一个概念多种写法”是常态不是异常。中间插一句后来我找到了一个系统整理踩到坑3的时候我开始意识到一个问题我之前的做法是拿到数据直接上手写代码出了问题再回头查文档。但医疗数据集的字段含义、编码规则、缺失模式最好在动手之前就系统了解。那几天我在找资料翻到千方病案的AI Ready数据集百科里面有个eICU的页面。当时截了张图是页面顶部的INFOBOX基本信息一目了然数据来自 https://qianfanghub.com/ai-ready-dataset/eicu-collaborative/9更关键的是页面把31个表的结构、缺失值编码规则、甚至8个常见坑点都整理得很清楚。我踩的这几个坑有一半在页面上已经写得明明白白。如果项目开始前先过一遍能省不少返工时间。坑4按医院划分训练/测试集时忽略了数据覆盖率差异这个坑在模型评估阶段才被发现也是最隐蔽的一个。前面说过eICU最大的价值是支持按医院划分——把208家医院分成训练集150家、验证集28家、测试集30家确保模型在”从未见过的医院”上评估。我按这个策略划分后模型在测试集上的AUROC是0.85看起来不错。但拆开看每家医院的性能发现有些医院的AUROC低到0.62。排查后发现不是所有表在所有医院都可用。比如microLab微生物培养表只有10.58%的医院有数据customLab非标准检验只有7.21%的医院有数据。而我的特征工程里用到了微生物培养结果——在训练集的医院里这个特征很有效但在测试集的医院里这个特征全空模型自然表现差。各表跨医院覆盖率差异表名跨医院覆盖率说明patient100%全覆盖vitalPeriodic99.04%基本全覆盖lab99.52%基本全覆盖medication83.65%部分医院缺失microLab10.58%大部分医院没有customLab7.21%极少数医院有教训多中心数据集的”多中心”不只是样本量增加还意味着数据异质性。按医院划分时必须检查每个特征在测试集医院中的可用性否则模型在训练集上学到的特征模式在测试集上根本不存在。坑5以为eICU就是标准ICU数据最后一个坑是认知层面的。项目中期我们拿模型结果去和临床团队讨论一位ICU主任问了一个问题”你们的模型在真实ICU场景下能用吗”我当时不太理解这个问题——eICU不就是ICU数据吗后来才搞明白eICU是TeleICU远程重症监护数据不等于标准ICU数据。eICU的数据来源于Philips的eCareManager系统——远程临床团队通过这个系统集中监控多个医院的ICU患者。数据虽然来自真实的ICU患者但采集和记录流程与医院本地的ICU信息系统不完全一致。具体来说远程监护团队和本地护理团队的记录可能存在重复或差异部分数据如护理记录的完整度取决于医院是否要求远程团队录入远程监护的介入本身可能影响治疗决策产生”观察者效应”这意味着直接把在eICU上训练的模型部署到医院本地ICU系统可能会遇到数据分布偏移的问题。教训使用数据集之前先搞清楚数据的”采集场景”。数据集名字里的”ICU”和你理解的”ICU”可能是两回事。写在最后从大厂转行医疗AI这半年最大的感受是医疗数据的复杂度远超互联网数据。不是数据量大就复杂而是数据背后的临床语义、采集流程、机构差异每一层都可能影响模型的实际效果。上面提到的千方病案eICU百科页面https://www.qianfanghub.com/ai-ready-dataset/eicu-collaborative/9 我后来时不时地还会回去翻尤其是准备新实验或者换患者队列的时候。页面上对31个表结构、缺失值编码、以及常见坑点的整理确实比我自己零散查资料要系统很多。医疗AI这条路不好走但数据是地基。地基打好了模型才有意义。

相关新闻