新冠下的多发性硬化 — 一千一百余例患者自报

1,141 例 PwMS / 47 变量 / CC BY 4.0

来源 https://physionet.org/content/patient-level-data-covid-ms/发布时间: 2026-10-28最后更新: 2026-10-28 阅读 14
新冠下的多发性硬化 — 一千一百余例患者自报

信息速览

数据集名称新冠下的多发性硬化 — 一千一百余例患者自报
数据类型元数据,文本语料,补充材料
规模1,141 名多发性硬化患者(PwMS)
接入方式https://physionet.org/content/patient-level-data-covid-ms/
AI 就绪度

2020 年春天,多发性硬化患者面对的是一道没有答案的选择题:继续用免疫抑制类的疾病修正治疗,还是为了躲避一种新发呼吸道病毒而停药。药停不得,病毒又躲不开,而当时全世界没有一个数据库能回答「用了这类药的人感染之后会不会更重」。COVID-19 与多发性硬化全球数据共享计划(Global Data Sharing Initiative,GDSI)就是为这道题临时搭起来的:一套统一的快速录入问卷,医生和患者都能填,几周内上线,两年后下线,最后留下这份可以整包下载的 CSV。

PhysioNet 上的这份数据不是某项疫苗试验的副产物,也不是某家医院的病历导出,而是「新冠与多发性硬化共病」这一交叉人群里,目前少有的、患者本人可以直接贡献记录并公开复用的患者级数据。它只有一千一百余行、四十七列、单表两百多 KB,第一眼容易被低估;但它的价值不在体量,而在于它记录的是「患者自己说发生了什么」,这在以病历为中心的临床数据生态里是稀缺视角。

本篇按「这是什么—能不能接—该不该选」三层展开:先拆掉三条常见误读,再逐列点名字段、还原一条记录的结构,然后交代 GDSI 的来路与去标识化的具体做法,最后给出可直接运行的取数与建模骨架,并在 §6 逐一交代它与库内既有新冠词条的边界。一屏速览见下表。

维度 内容
官方全名 Patient-level dataset to study the effect of COVID-19 in people with Multiple Sclerosis
PhysioNet slug patient-level-data-covid-ms
版本与日期 v1.0.0 于 2023-05-30;v1.0.1 于 2024-01-02(当前版)
DOI 10.13026/77ta-1866(v1.0.1);最新版 10.13026/3cmh-xa68
论文 Scientific Data(2024),DOI 10.1038/s41597-024-02978-x
作者 Hamza Khan、Lotte Geys、peer baneke、Giancarlo Comi、Liesbet Peeters
规模 1,141 名多发性硬化患者,47 个预定变量
结构 单张 CSV(GDSI_OpenDataset_Final.csv,221.2 KB)+ 许可 + 说明 + 校验和,合计 237.4 KB
记录粒度 一人一行,一次填报一个快照,无随访、无时间戳
采集方式 患者、患者代表或临床医生在 GDSI 中央平台(QMENTA 提供)直接填报
采集窗口 2020 年启动,录入工具于 2022-02-03 下线
去标识化 小单元格风险评估 + 日期 ±15 天平移 + 年龄四档 + k-匿名 + l-多样性,按 HIPAA 口径
伦理 哈瑟尔特大学伦理委员会(CME2020/025 AMD3)
许可 CC BY 4.0,署名即可,可商用
一句话边界 自报横断面、无对照、无国别、无疫苗字段

§1 它要解决的具体麻烦

1.1 一道必须在几个月内作答、却没人有数据的临床选择题

2020 年之前,多发性硬化的治疗决策有一条相对稳定的经验曲线:复发缓解型用高效药压制炎症,进展型谨慎加码,感染风险作为长期代价被纳入权衡。新冠把这个节奏打乱了。患者群体里流传的担心非常具体——奥瑞珠单抗、利妥昔单抗这类抗 CD20 药物消耗 B 细胞,芬戈莫德会降低淋巴细胞计数,如果感染新冠,会不会更容易重症?而另一边的担心同样具体——贸然停药,复发风险立刻回来。

回答这个问题需要的是「用药状态 × 感染结局」的交叉表,而且必须是大样本、跨中心、能快速累积的。但 2020 年 3 月没有任何一个 MS 登记库能提供这种表:传统登记库按年随访、字段固定、伦理与数据出境流程以月计。GDSI 的做法是把门槛降到最低——不做病历抽取,不做影像上传,只做一份结构化问卷,患者本人可以填,医生也可以填,填完即入中央平台。这份 PhysioNet 数据就是那条流水线跑完之后,被判定为可以公开的那一部分。

理解这一点很关键:它不是「研究做完之后公开的数据」,而是「为了快速作答而设计的数据采集工具,其产出被直接开放」。前者通常已经清洗成分析表,后者保留着采集时的粗糙度——缺失、自报、粒度粗、无随访,这些都是设计代价,不是发布事故。

1.2 三条常见的错误期待

第一条:把它当成 MS 人群的新冠自然史队列。 队列的前提是明确的分母与统一的入组标准。这里既没有分母(不知道全人群有多少 MS 患者、也不知道有多少人填了但没填完),也没有入组标准(任何愿意填的人都能进来)。它更接近一次覆盖面很广的便利抽样调查,只是抽样框极难刻画。

第二条:把它当成可以训练影像或文本模型的「多模态」资源。 四十七列里没有一列是影像路径,没有一列是自由文本病历,唯一的开放式字串是「其他合并症」的补充填写,且经过脱敏。它的形态是一张典型的长宽比失衡的分析表,行数少、列数中等、全部是短码。任何以「数据集」直觉期待的大量非结构化内容,在这里都会落空。

第三条:把它当成疫苗安全性数据。 变量表里没有疫苗字段,没有接种时间、剂次、品牌、接种后不良事件。录入工具在 2022 年 2 月下线,正好卡在大规模接种铺开之前。想研究 MS 患者接种后的问题,应该去看药物警戒系统(如 VAERS 一类的被动上报库)或专门的疫苗队列,而不是这里。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
描述 MS 患者感染后的症状谱 十个症状二值字段 + 是否有症状的总标记 够做描述,不够做严重度分级
看不同 DMT 与住院的关联 当前用药状态、具体药物类别、激素使用 够做探索性关联,样本量限制功效
校正年龄与性别 四档年龄 + 性别 够,但年龄被分箱,无法做连续建模
校正残疾程度 EDSS 二分类(≤6 与 >6) 勉强,覆盖度低且二分类丢失信息
计算感染率、住院率、病死率 分子有,分母没有 不够,任何率都不可算
做时间序列或波次分析 无日期列(仅停用 DMT 日期) 不够
做国家或中心间比较 无国别、无中心标识 不够
研究疫苗与 MS 无疫苗字段 不够,方向不符
教学:完整走一遍数据清洗与建模 小体积、真缺失、真偏倚、许可无摩擦 够,而且是它最稳的用途

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
手上没有 MS 数据,想先验证一个分析思路是否成立 提供真实字段名与真实缺失结构,几分钟内可跑通全流程 把思路写成脚本,在它上面跑通,再迁到有分母的登记库
正在写 MS 与感染的综述,需要一份可引用的开放数据描述 提供一手的方法学与去标识化细节,可直接引用 同时引用 Scientific Data 论文与 PhysioNet DOI
是患者组织的志愿者,想做一份面向病友的科普统计 提供患者视角的症状与住院分布素材 明确标注「自愿填报、不代表全体病友」,避免误导
在做课程设计,需要一份「小但脏」的教学数据 体积小、许可宽松、缺失真实、偏倚可讲 把缺失机制与选择偏倚设计成课堂讨论题
想训练临床预测模型并发表 样本量与标签粒度都不足以支撑独立验证 改用 N3C、ISARIC-CCP 一类有分母的队列,或把它当外部小样本校验
想研究 DMT 与新冠重症的因果关系 只有关联,且混杂严重、无时序 需要带时间戳与用药起止的登记库,配合倾向评分或目标试验模拟

1.5 一句话判断

它是一份体量很小、偏倚很重、但结构极干净且许可极宽松的患者自报横断面数据:不要指望它回答流行病学问题,它最擅长的是把「MS 患者感染新冠后会怎样」这件事,用一份能在十分钟内读完的表讲清楚。

1.6 不适合谁:四条边界

不适合想算率的人。 任何以「人数 ÷ 分母」形式出现的指标在这里都失效。分子是自愿填报者中的事件数,分母不可定义。这不是数据质量缺陷,而是采集方式的直接结果,无法通过后期加权补救——因为连加权所需的目标分布都不存在。

不适合需要时序的人。 表里唯一的日期列是停用 DMT 的日期,且已被随机平移。感染发生在用药之前还是之后,无法从数据中判定。任何「先用药、后感染」的因果叙述都必须靠外部假设补上,而那个假设恰恰是争论的焦点。

不适合要求标签权威性的人。 九成以上记录由患者自报,「确诊」这一项依赖患者对自己检测结果的记忆与理解。确诊、疑似、未怀疑三档的定义在问卷层面是自洽的,但落到个体记录上,其可靠性远低于实验室确认的队列。

不适合需要地理或机构维度的公共卫生分析。 数据里没有国别、没有中心、没有语言,也看不出填报集中在哪些国家。想比较不同医疗体系下的住院阈值差异,这份数据提供了零信息。

§2 数据构成与规格

2.1 一张表、四十七列、四种信息层

整包解压后只有四个文件:主数据 CSV、许可文本、一页说明、一份校验和。真正有内容的只有那张 CSV,221.2 KB,无压缩时全部文件合计 237.4 KB。这个体量意味着它可以被塞进任何一次邮件附件、任何一台笔记本的内存、任何一次课堂练习的十分钟窗口。

四十七列按语义可以分成四层。第一层是身份与通道:谁填的、编号是什么。第二层是患者背景:年龄档、性别、体质指数档、妊娠、吸烟。第三层是 MS 疾病背景:表型、残疾评分档、当前是否用药、用什么药、用药多久、何时停药、是否用激素。第四层是这次 COVID-19 事件本身:诊断判定、是否有症状、十个具体症状、是否住院、是否进 ICU、是否上呼吸机、是否自我隔离、结局分级,以及合并症的一个总标记加十个具体系统加一个开放补充。

四层的边界很清楚:前三层是「这个人本来是什么样」,第四层是「这次发生了什么」。做关联分析时的自变量几乎全部来自前三层,因变量几乎全部来自第四层。这个划分也解释了为什么它无法回答「感染后长期结局」——第四层只有一个时点。

2.2 字段完整字典

官方对变量数的表述是 n=47。按其数据说明页逐个点名,可以明确对上四十六个字段名,剩余一个未单独展开说明;下表按官方给出的字段名与取值域整理,对不上号的那一格留白,不做推测。

组 字段名 含义 取值域
身份 secret_name 记录唯一标识 随机串,P_ 前缀为患者填报,C_ 前缀为医生填报
身份 report_source 填报通道 Patient / Clinician
人口学 age_in_cat 年龄档 0 为 0 至 18 岁以下,1 为 18 至 50 岁,2 为 51 至 70 岁,3 为 71 岁及以上
人口学 sex 性别 Male / Female
人口学 bmi_in_cat2 体质指数档 not_overweight(不超过 30)/ overweight(超过 30)
人口学 pregnancy 妊娠状态 Yes / No
生活方式 current_or_former_smoker 现在或曾经吸烟 Yes / No
MS 背景 ms_type2 表型 relapsing_remitting / progressive_MS / other
MS 背景 edss_in_cat2 残疾评分档 0 为 EDSS 0 至 6,1 为 EDSS 大于 6
MS 背景 current_dmt 当前治疗状态 yes / no / never_treated
MS 背景 dmt_type_overall 具体药物类别 干扰素、醋酸格拉替雷、那他珠单抗、芬戈莫德、富马酸二甲酯、特立氟胺、阿仑单抗、克拉屈滨、利妥昔单抗、奥瑞珠单抗、当前未用、其他未列出
MS 背景 dmt_glucocorticoid 是否用糖皮质激素 Yes / No
MS 背景 duration_treatment_cat 治疗时长档 0 为不足 11 年,1 为 11 年及以上
MS 背景 stop_or_end_date_combined 停用 DMT 日期 dd/mm/yyyy,逐行随机平移
事件 covid19_confirmed_case 是否确诊 Yes / No
事件 covid19_diagnosis 诊断判定 not_suspected / suspected / confirmed
事件 covid19_has_symptoms 是否有症状 Yes / No
事件 covid19_self_isolation 是否自我隔离 Yes / No
事件 covid19_admission_hospital 是否住院 Yes / No
事件 covid19_icu_stay 是否进 ICU Yes / No
事件 covid19_ventilation 是否使用呼吸机 Yes / No
事件 covid19_outcome_levels_2 结局分级 0 未住院,1 住院,2 住院且进 ICU 或通气,3 死亡(集内为空)
症状 covid19_sympt_fever 发热 Yes / No
症状 covid19_sympt_dry_cough 干咳 Yes / No
症状 covid19_sympt_fatigue 乏力 Yes / No
症状 covid19_sympt_shortness_breath 气短 Yes / No
症状 covid19_sympt_sore_throat 咽痛 Yes / No
症状 covid19_sympt_nasal_congestion 鼻塞 Yes / No
症状 covid19_sympt_chills 寒战 Yes / No
症状 covid19_sympt_pain 疼痛 Yes / No
症状 covid19_sympt_loss_smell_taste 嗅觉或味觉丧失 Yes / No
症状 covid19_sympt_pneumonia 肺炎 Yes / No
合并症 has_comorbidities 是否有任何合并症 Yes / No
合并症 com_cardiovascular_disease 心血管疾病 Yes / No
合并症 com_hypertension 高血压 Yes / No
合并症 com_diabetes 糖尿病 Yes / No
合并症 com_lung_disease 肺部疾病 Yes / No
合并症 com_chronic_kidney_disease 慢性肾病 Yes / No
合并症 com_chronic_liver_disease 慢性肝病 Yes / No
合并症 com_immunodeficiency 免疫缺陷 Yes / No
合并症 com_malignancy 恶性肿瘤 Yes / No
合并症 com_neurological_neuromuscular 神经或神经肌肉合并症 Yes / No
合并症 comorbidities_other 其他合并症(文本) 自由填写,已脱敏
未说明 — 官方所称第 47 个变量 数据说明页未单独展开

字段命名本身透露了整理历史。sympt_ 前缀统一加在症状前,代表症状是一批追加的列;has_comorbidities 与 com_ 系列并存,说明「有没有」与「是哪一类」是两次问的;outcome_levels_2 里的数字 2 表示这是结局分级的第二个版本,早期版本没有随数据一起发布。这些痕迹解释了为什么部分变量并不正交:结局分级可由住院、ICU、通气三列推导,四者共线。

2.3 一条记录的完整解剖

位置 字段 这一格在说什么
第 1 列 secret_name 这条记录的身份,前缀已经告诉你填表的是患者还是医生
第 2 列 report_source 与上一列冗余,但显式声明通道,便于直接分组
第 3 至 7 列 age_in_cat 到 current_or_former_smoker 患者的基本盘,全部是分档后的离散值
第 8 至 14 列 ms_type2 到 stop_or_end_date_combined 疾病与治疗背景,是这份数据最独特的七列
第 15 至 22 列 covid19_confirmed_case 到 covid19_outcome_levels_2 这次事件的主干,从判定到结局八步
第 23 至 32 列 十个 sympt_ 字段 症状清单,成组出现,成组缺失
第 33 至 43 列 has_comorbidities 与十个 com_ 字段 合并症清单,同样成组缺失

上面这张表是列序骨架,按官方变量表的语义关系排列,不是原始文件的物理列序。真正读入时不要依赖列的位置,一律按列名取。下面这段代码把「一行」完整打出来,并顺手标出哪些格子在语义上可以互相推导。

#-- 读入并把一条记录还原成可读的键值对
import pandas as pd

df = pd.read_csv("GDSI_OpenDataset_Final.csv", keep_default_na=True, na_values=[""])
row = df.iloc[0]

#-- 按前缀分组打印,避免一次性刷屏
groups = {
    "身份": ["secret_name", "report_source"],
    "背景": ["age_in_cat", "sex", "bmi_in_cat2", "pregnancy", "current_or_former_smoker"],
    "疾病": ["ms_type2", "edss_in_cat2", "current_dmt", "dmt_type_overall",
             "dmt_glucocorticoid", "duration_treatment_cat", "stop_or_end_date_combined"],
    "事件": ["covid19_diagnosis", "covid19_has_symptoms", "covid19_self_isolation",
             "covid19_admission_hospital", "covid19_icu_stay", "covid19_ventilation",
             "covid19_outcome_levels_2"],
}
for name, cols in groups.items():
    print(f"[{name}]")
    for c in cols:
        print(f"  {c:34s} = {row.get(c)}")

#-- 语义冗余核对:结局分级应能由三列住院相关字段推出
derived = 0 if row["covid19_admission_hospital"] != "Yes" else (
    2 if (row["covid19_icu_stay"] == "Yes" or row["covid19_ventilation"] == "Yes") else 1)
print("结局分级自洽:", derived == int(row["covid19_outcome_levels_2"]))

值得留意的是最后那行自洽核对。它几乎总会返回真,因为结局分级本来就是从住院与重症两列合成的。这意味着建模时不能把四列一起放进同一个模型当作独立预测因子——那是把一个变量拆成四份喂进去,系数会互相稀释。正确做法是选一个作为因变量,其余作为理解其定义的注脚。

2.4 变量家族与覆盖度结构

不使用逐字段的空值率,只描述覆盖度的形状,因为这个形状决定了你该怎么建模。

家族 覆盖度形状 对建模的含义
身份与通道 完整 可直接作为分组变量,但 P_ 与 C_ 的比例极不均衡
人口学(年龄、性别) 基本完整 可作为核心协变量,但年龄只有四档
体质指数、妊娠 有可见缺口 孕期分析基本不可行,体质指数只能当粗分类
MS 表型 完整 可作分层变量,三类中「其他」占比不低
EDSS 缺口很大 只能做完整案例分析,且失去连续信息
当前用药状态 完整 最有价值的自变量之一
具体药物类别 小缺口 类别多、单类别样本少,需合并
治疗时长 缺口极大 基本不可用,不建议进模型
COVID 判定与是否住院 完整 因变量与主结局的骨架
十个症状 成组大缺口 只在「有症状」子集上有意义,不能当全样本变量
合并症 总标记完整,细项成组缺口 用总标记做粗校正,细项只做描述

这张表最重要的信息是「成组缺失」。症状与合并症的细项不是随机漏填,而是问卷的分支逻辑:没有症状的人不会被追问哪几种症状,没有合并症的人不会被追问哪一种。于是缺失本身携带信息,属于结构性缺失而非随机缺失。把缺失当默认阴性处理,等于把「没问」当成「没有」,会系统性低估症状与合并症的负担;把缺失当缺失直接删除,又会把分析样本压缩到「有症状且填了细项」的那一小群人身上,结论只对这群人成立。

2.5 与同类资源的字段差异

资源 字段重心 与本集的互补关系
本集 MS 背景 + 自报新冠事件 唯一同时含 MS 治疗细节与患者自报感染结局的开放表
ISARIC-CCP 住院期生命体征、检验、治疗、结局 本集缺的严重度分层与实验室指标,那里有;本集有的 MS 用药细节,那里没有
N3C 全美 EHR 结构化诊断、用药、就诊 可用作有分母的对照,但 MS 亚组需自行识别,且无患者自报视角
VIRUS 注册 ICU 级器官支持与预后 覆盖重症端,本集几乎不覆盖重症端
CDSL 单中心多模态(EHR 六表 + 影像) 提供影像与检验,但无 MS 人群
通用新冠影像库 胸片与 CT 及病灶标注 与本集完全正交,无重叠字段

一句话概括这张表:本集的字段重心不在「病得多重」,而在「这个人本来在用什么药、他自己觉得发生了什么」。需要严重度客观指标的问题不该由它回答。

§3 核心层 A:身份与谱系

3.1 GDSI 不是一家医院的登记库

把这份数据当成「某中心的 MS 队列」是最常见的身份误判。它的组织形态更接近一次由专业社群发起、由技术公司托底、由学术机构出伦理背书的全球征集。三方的分工很清晰:多发性硬化领域的临床与患者组织网络负责动员与问卷设计,QMENTA 提供中央数据平台并承接录入,哈瑟尔特大学承担伦理审批与后续的数据整理发布。数据说明页的致谢里专门感谢了平台方,这类致谢在单中心数据集里很少见,恰好说明了它的多来源属性。

多来源带来一个直接后果:数据里没有「中心」这个维度。既没有站点编号,也没有国别,更没有语言。这不是脱敏时被删掉的,而是采集时就没有设计——问卷面向的是「任何一位愿意填的 MS 患者」,而不是「某几家医院的患者」。所以它无法做中心效应校正,也无法比较不同医疗体系下住院门槛的差异。想做这类分析,必须换数据源。

另一个后果是填报通道的极端不均衡。官方给出的通道构成里,患者自报占绝对多数,医生填报只占很小一部分。这个比例本身就是一条重要的边界信息:它意味着整份数据在气质上是「患者视角的记录」,症状描述用的是患者能感知的语言,住院信息依据的是患者的转述,而医生填报的那一小部分虽然更接近病历,却因为量太少而无法单独支撑分析。任何试图把两者放在一起比较「自报准不准」的想法,都会撞上样本量这堵墙。

3.2 从问卷到 CSV:五步流水线

步骤 做的事 留下的痕迹
问卷设计 把临床问题压成能在几分钟内答完的题 年龄四档、体质指数二分类、EDSS 二分类
入口开放 患者、代表、医生三路直填,不上传病历 report_source 只有两种取值
汇集清洗 统一导出、字段名规范化、取值域锁成短码 全部字段为英文短码,无自由数值
去标识化 分类、平移、分箱、匿名约束 唯一日期被扰动,年龄被合并
伦理与发布 批号、许可、版本、校验和 版本号与 SHA256 清单

第一步是问卷设计。题目被刻意压到最少,只保留能在几分钟内答完的项:年龄档、性别、身高体重、是否怀孕、是否吸烟、MS 类型、残疾评分、当前用药、具体药物、用药时长、是否停药、新冠判定、症状清单、住院与否、ICU 与否、通气与否、合并症。设计取向是「宁可粗,也要填得完」,这解释了为什么年龄是四档、体质指数是二分类、EDSS 是二分类。

第二步是入口开放。患者本人、患者代表、临床医生都可以直接进入中央平台填报,不需要上传病历,不需要机构账号背书。这一步把参与门槛降到接近零,同时把数据核验的可能性也降到了接近零。

第三步是数据汇集与清洗。录入的数据进入中央平台后统一导出,字段名规范化,取值域统一为英文短码。这一步的产物就是我们看到的 CSV 的雏形。

第四步是去标识化。这是整条流水线里技术含量最高、也最值得单独讲的一环,下一节展开。

第五步是伦理与发布。伦理批号、许可选择、版本管理、校验和,一起构成发布包。v1.0.0 与 v1.0.1 之间的差异属于发布层面的修订,主数据文件的时间戳停在 2023 年 5 月,说明数据内容在首版之后基本冻结。

3.3 三个名字,三种指称范围

名字 指什么 什么时候该用
GDSI COVID-19 and MS Global Data Sharing Initiative,整个计划,含问卷、平台、全量数据与多篇产出 讲背景、讲组织、讲方法学时
本集(PhysioNet 版) GDSI 的一个公开子集,千余行、47 列、CC BY 4.0 引用数据、写方法节、写可复现材料时
Scientific Data 论文版 同一份数据的论文描述,附匿名化方法学的完整论证 引用方法学、引用去标识化细节时

三者不是三个数据集,而是同一件事的三个切面。容易混淆的地方在于「全量」与「公开子集」的关系:GDSI 在运行期间汇集的数据规模大于这份公开文件,公开的是经过筛选与脱敏、被判定可以无条件开放的那一部分。因此任何以「GDSI 有多少例」开头的句子,都必须紧跟一句说明指的是计划全量还是这份公开文件,否则数字会打架。

3.4 与 MS 领域其他数据资源的身份区别

MS 领域的数据资源大致分三类。第一类是大型前瞻登记库,按固定周期随访,字段标准化,覆盖全病程,访问通常需要申请与付费,代表是各国的国家级 MS 登记网络。第二类是单中心或单企业的 EHR 导出,颗粒度细、时间戳完整,但人群代表性受限。第三类就是本集这样的自报快照,优势是快、开放、含患者视角,劣势是无随访、无核验、无分母。

三类的用途几乎不重叠。要估计患病率、要算治疗持久性、要做长期残疾进展建模,必须用第一类。要做影像组学或需要检验值,必须用第二类。要在几天内拿到一份能合法分发的、含真实缺失与真实偏倚的小数据用于方法验证或教学,第三类才是合理选择——而这正是本集在生态里的位置。

§4 核心层 B:质量与特色

4.1 去标识化的五件套

小样本登记库要开放,难点从来不是「删掉姓名」,而是「删掉姓名之后仍然能通过组合反推到人」。本集的处理方式在论文里有完整交代,可以拆成五件互相配合的事。

第一件是小单元格风险评估。把所有变量先分成三类:直接标识符(姓名、联系方式一类,直接移除)、敏感变量(感染状态、用药一类,保留但需保护)、间接标识符(年龄、性别、地区、罕见病型一类,组合起来可能指向个体)。这个分类的作用是给后续每一步提供依据——哪些必须删,哪些可以留但要做处理,哪些组合需要额外约束。

第二件是日期平移。唯一保留的日期列是停用 DMT 的日期,处理方式是每一行独立随机偏移负十五到正十五天。这个幅度足以打乱「某天某地某医院有一批患者停药」这类外部信息与数据行的对应关系,又不至于把季节信息破坏掉。对分析的影响是:日期可以用于粗略的时间定位,但不能用于与外部事件逐日对齐。

第三件是年龄分箱。连续年龄被压成四档,最高档从 71 岁起合并。这既是隐私保护,也是为了避免高龄单例被反推——在 MS 人群里,七十岁以上的患者相对少见,一个精确到岁的记录加上性别与表型,很可能在全网范围内唯一。

第四件与第五件是 k-匿名与 l-多样性,两者配合使用:前者要求任何一组准标识符组合至少对应 k 条记录,后者要求在同一组合内敏感属性的取值足够分散,避免「知道你在这一组,就知道你用了什么药」。这两步是国际通行的登记库开放前置条件,也是这份数据敢用 CC BY 4.0 而不是受限许可的技术底气。

值得强调的是:CC BY 4.0 在这个领域是极少见的宽松。多数患者级临床数据即便脱敏,也会选择限制再分发或要求签署使用协议。这里选择无条件开放,意味着发布方对去标识化的强度有相当信心,也意味着使用者要自己承担「重新识别尝试」的伦理责任——技术上能做,不等于合规上可做。

4.2 自报与医生填报的双通道

双通道设计原本是为了扩大覆盖面:患者能找到自己的用药信息就自己填,找不到就请医生填。落到数据上,它变成了一条隐含的质量分层——医生填报的记录在用药名称、残疾评分这些需要专业判断的字段上更可靠,患者自报的记录在症状体验、隔离行为这些只有本人知道的字段上更真实。

麻烦在于两层样本不可比。医生填报的那部分很可能系统性地偏向「病情更重、就医更频繁、与专科联系更紧密」的人,而患者自报的那部分偏向「更主动、更懂自己的病、更愿意参与研究」的人。把两层混在一起做描述统计,得到的分布既不是人群分布,也不是任一子群的分布,而是两种选择机制的混合。

实用建议是把 report_source 当作分层变量而不是协变量:先分别看两层的描述,再决定是合并还是只用一个层。如果某层的样本量小到无法支撑分层,那就必须在局限性里明确写出「结果主要由自报层驱动」,而不是含糊地说「数据来自患者与医生」。

4.3 案例:一条 42 岁复发缓解型记录的三次出场

下面这条记录是为讲解字段联动而构造的示例,字段名与取值域完全来自官方变量表,取值组合不代表任何真实个体。

设定是这样:一位 42 岁的女性,复发缓解型多发性硬化,正在使用奥瑞珠单抗,没有停药,体质指数不超过 30,不吸烟,未怀孕,EDSS 在 6 分及以下,有高血压这一个合并症。她填表时自报「疑似」感染,有症状,症状包括乏力与嗅觉味觉丧失,没有住院,居家隔离。对应的字段组合是:age_in_cat 为 1,sex 为 Female,ms_type2 为 relapsing_remitting,current_dmt 为 yes,dmt_type_overall 为奥瑞珠单抗,covid19_diagnosis 为 suspected,covid19_has_symptoms 为 Yes,covid19_sympt_fatigue 与 covid19_sympt_loss_smell_taste 为 Yes,covid19_admission_hospital 为 No,covid19_self_isolation 为 Yes,has_comorbidities 为 Yes,com_hypertension 为 Yes,outcome_levels_2 为 0。

这条记录第一次出场在建模层面。它说明了一个容易被忽略的问题:outcome_levels_2 为 0 的人里,既有「确诊且未住院」的,也有「未怀疑感染」的——后者根本没病,只是来填了一份背景问卷。如果把所有人放进同一个逻辑回归去预测住院,绝大多数样本的因变量恒为 0,模型学到的是「谁会来填表」而不是「谁会住院」。正确做法是先按 covid19_diagnosis 切出确诊与疑似的子集,再在这个子集里做结局分析。

第二次出场在缺失机制层面。这位患者填了乏力与嗅觉味觉丧失两项为阳性,其余八项症状留空。若把留空当阴性,她的症状计数是二;若把留空当缺失,她的症状计数不可算。两种处理会得出完全不同的症状负担描述。官方没有提供「逐项勾选」与「未勾选即阴性」的区分标记,所以这个歧义无法在数据内部解决,只能靠分析时的一致性声明来控制。

第三次出场在隐私层面。四十二岁、女性、复发缓解型、用奥瑞珠单抗、有高血压——这五个条件的交集在一个人群里已经相当窄。这正是年龄必须分箱、日期必须平移的原因,也是为什么任何试图把这份数据与外部登记库做个体级链接的尝试,在伦理上都站不住。这条记录在 §5 与 §7 还会各出现一次。

4.4 质量的三条实证线索

不看分布,也能从三个地方判断这份数据的成色。

第一条线索是版本管理。v1.0.0 到 v1.0.1 的更新集中在发布包层面(许可文本与校验和的时间戳晚于主数据),说明数据内容稳定、修订克制。有校验和文件意味着可以验证下载完整性,这是开放数据的基本礼貌,很多同类资源做不到。

第二条线索是文档与代码的配套。数据说明页给出了完整的匿名化流程、伦理批号、变量清单、以及一个公开的代码仓库地址。代码仓库里放的是 GDSI 在运行期使用的分析与可视化脚本,用 Python 生态(pandas、NumPy、SciPy、matplotlib)写成,跑在 Jupyter 环境里。这意味着复现路径是通的,而不是只有一份 PDF 描述。

第三条线索是二次使用。已有独立研究直接以这份公开文件为数据源做过分析,说明字段定义足够清楚、许可足够宽松、数据足够可用,以至于第三方愿意在它上面做正式研究。对一份只有一千余行的数据集来说,「被别人用过并且被期刊接受」是比任何自评都硬的证据。

4.5 为什么它被当成教学数据

官方在论文摘要里直接写明,这份数据可以用于教育活动,帮助不同背景的学习者理解 GDSI 用到的复杂数据科学概念。这个定位不是客套,它精确对应了这份数据的几个特征:体量小到可以在一节课内跑完,缺失真实到必须处理而不能绕过,偏倚明显到可以当作案例讨论,许可宽松到不需要任何审批就能分发给学生。

教学场景里最常被拿来演示的三件事,都能在它上面成立。第一件是缺失机制:症状字段的成组缺失是天然的例子,讲清楚「分支问卷导致的缺失不是随机缺失」比任何模拟数据都直观。第二件是选择偏倚:让学生自己算一次「住院率」,再让他们解释为什么这个数没有意义,比讲十遍定义有效。第三件是结局变量构造:结局分级与住院、ICU、通气三列的冗余关系,是讲共线与变量派生的小型标本。

§5 核心层 C:取数

5.1 三条下载路径

PhysioNet 对这份数据不设访问门槛,三种方式都能拿到完整包。

方式 命令形态 适用场景
网页 ZIP 在版本页点击压缩包下载 一次性取用,手工检查文件
wget 递归 对版本目录做递归镜像 需要保留目录结构、写进脚本
S3 同步 对公开桶做无凭证同步 集群上批量拉取、做校验
#-- 方式一:直接镜像整个版本目录
mkdir -p data/gdsi && cd data/gdsi
wget -r -N -c -np https://physionet.org/files/patient-level-data-covid-ms/1.0.1/

#-- 方式二:从公开桶同步(无需 AWS 凭证)
aws s3 sync --no-request-payer --no-sign-request \
    s3://physionet-open/patient-level-data-covid-ms/1.0.1/ ./gdsi-1.0.1/

#-- 下载后先验校验和,再解压使用
cd gdsi-1.0.1 && sha256sum -c SHA256SUMS.txt

三条路径拿到的内容完全一致。真正的差别在于可重复性:如果分析要进版本控制,用 wget 或 S3 把获取步骤写进脚本,比手工点下载更可靠。校验和文件不是装饰,它是判断「文件在传输中是否损坏」的唯一低成本手段,养成先验后用的习惯。

5.2 读入与基本核对

读入这张表有两个坑:一是空字符串与缺失值的区分,二是分类字段的取值既有英文短码又有自由文本。下面的骨架把这两件事一次处理掉。

#-- 读入并做三项基本核对:行列数、主键唯一性、结局自洽
import pandas as pd

PATH = "data/gdsi-1.0.1/GDSI_OpenDataset_Final.csv"
df = pd.read_csv(PATH, na_values=[""], keep_default_na=True)

print("形状:", df.shape)
print("主键唯一:", df["secret_name"].is_unique)

#-- 通道字段只应有两种取值
print("通道取值:", sorted(df["report_source"].dropna().unique().tolist()))

#-- 结局分级与住院三列的自洽率
hosp = df["covid19_admission_hospital"].eq("Yes")
icu = df["covid19_icu_stay"].eq("Yes")
vent = df["covid19_ventilation"].eq("Yes")
derived = pd.Series(0, index=df.index)
derived = derived.mask(hosp, 1).mask(hosp & (icu | vent), 2)
print("结局自洽率:", (derived == df["covid19_outcome_levels_2"]).mean())

#-- 症状列成组缺失:统计有多少行是全缺
sympt = [c for c in df.columns if c.startswith("covid19_sympt_")]
print("症状列数:", len(sympt))
print("症状全缺行数:", df[sympt].isna().all(axis=1).sum())

最后一行输出通常不是一个小数。它告诉你:有相当一部分记录根本没有进入症状分支,因为他们在「是否有症状」这一问上答了否,或者压根没被追问。这个数字是后续所有症状分析的起点——分子分母都必须限定在「进入分支」的那部分行上。§4.3 的案例里那八项留空的症状,正是这一步的输出。

5.3 从原始表到分析表

§4.3 的案例已经演示了为什么必须切人群:不切,因变量会被大量「未感染」记录稀释。从这张表出发做分析,第一步几乎总是构造一个分析子集:确定研究问题、切出目标人群、定义结局、选定协变量。下面这段代码给出一个可复用的骨架,用于研究「当前用药状态与住院结局的关联」这一经典问题。

#-- 构造分析表:确诊或疑似子集 + 二值结局 + 最小协变量集
import pandas as pd
import numpy as np

df = pd.read_csv("data/gdsi-1.0.1/GDSI_OpenDataset_Final.csv", na_values=[""])

#-- 第一步:切人群。未怀疑感染的记录没有事件可研究
mask_event = df["covid19_diagnosis"].isin(["confirmed", "suspected"])
d = df.loc[mask_event].copy()

#-- 第二步:定义结局。住院及以上记为 1
d["severe"] = d["covid19_outcome_levels_2"].isin([1, 2]).astype(int)

#-- 第三步:协变量整理。药物类别合并为三组,避免稀疏
d["dmt_group"] = np.select(
    [d["dmt_type_overall"].str.contains("ocrelizumab|rituximab|alemtuzumab|cladribine", na=False),
     d["current_dmt"].eq("never_treated")],
    ["anti_cd20_or_immune_reconstitution", "never_treated"],
    default="other_dmt",
)

#-- 第四步:只保留建模需要的列并报告完整案例规模
keep = ["secret_name", "report_source", "age_in_cat", "sex", "ms_type2",
        "edss_in_cat2", "dmt_group", "has_comorbidities", "severe"]
ana = d[keep].copy()
print("分析子集:", ana.shape, "完整案例:", ana.dropna().shape)
print(ana["severe"].value_counts().to_dict())

这段代码里最值得学的是第三步的合并逻辑。原始的药物类别有十几种,直接进模型会产生大量只有个位数样本的哑变量,系数估计极不稳定。按作用机制合并成三组(抗 CD20 与免疫重建、从未治疗、其他)既保留了临床含义,又把维度压到可控。合并规则要在方法节写明,且应做敏感性分析——换一种合并方式,结论会不会翻,是这类小样本分析的必答题。

5.4 缺失与敏感性

对这份数据,缺失不能只做一次处理就交差。至少要做两个方向的检验。

第一个方向是完整案例与全体样本的比较。按 edss_in_cat2 是否缺失分组,比较两组的年龄档分布、表型构成、住院比例。如果缺失组的住院比例明显更高,说明「有残疾评分的人」本身就是被更密切随访的那群人,完整案例分析会引入选择偏倚。

第二个方向是缺失处理方式的敏感性。对症状类字段,把缺失当阴性、当缺失删除、当多重插补,三种处理得到的症状负担描述会有实质差异。把三种结果并列报告,比只报一种更能说服审稿人——尤其当结论在这三种处理下方向一致时,可信度会明显上升。

#-- 两个方向的缺失敏感性检验
import pandas as pd

df = pd.read_csv("data/gdsi-1.0.1/GDSI_OpenDataset_Final.csv", na_values=[""])
df["severe"] = df["covid19_outcome_levels_2"].isin([1, 2]).astype(int)

#-- 方向一:按 EDSS 是否缺失分组比较
df["edss_missing"] = df["edss_in_cat2"].isna()
print(df.groupby("edss_missing")["severe"].agg(["mean", "size"]).round(4))

#-- 方向二:症状缺失的三种处理
sympt = [c for c in df.columns if c.startswith("covid19_sympt_")]
as_zero = df[sympt].eq("Yes").sum(axis=1)
as_drop = df[sympt].eq("Yes").sum(axis=1, skipna=False)
as_any = df[sympt].eq("Yes").any(axis=1)
print("按阴性计 均值:", round(as_zero.mean(), 3))
print("按缺失删 可用行:", int(as_drop.notna().sum()))
print("按任一症状 比例:", round(as_any.mean(), 3))

5.5 与外部数据的链接方式

把这份数据与外部资源连起来有两种做法,一种合规,一种不合规。

合规的做法是分布层面的对照。把本集的年龄结构、性别比例、表型构成与某国 MS 登记库的公开汇总做比较,判断这份自愿样本在人口学上偏了多少。这种对照用的是汇总数,不涉及个体匹配,既不侵犯隐私,也不需要额外审批。它是评估外部效度最经济的手段。

不合规的做法是个体层面的链接。用年龄档、性别、表型、用药、合并症的组合去外部库里找人,试图把自报记录与病历对上。技术上可行,伦理上不可行:这份数据之所以能用 CC BY 4.0 开放,前提就是不可重新识别。一旦有人证明可以反推,发布方要么收紧许可,要么下架数据,受损的是整个社群。

5.6 复现官方分析

官方代码仓库给出的是一条完整的分析管线:读入、清洗、描述、建模、出图。复现它有一个现实好处——你能确认自己的读入方式与官方一致,尤其是缺失值的判定。如果官方把空字符串当缺失而你当成了类别,后面所有数字都会对不上。建议的复现顺序是:先跑通读入与形状核对,再跑描述,最后跑模型。任何一步对不上,都先怀疑读入参数,而不是怀疑数据。

#-- 复现顺序:三步逐级核对,任一步不一致就回退检查读入参数
python3 - <<'PY'
import pandas as pd
df = pd.read_csv("data/gdsi-1.0.1/GDSI_OpenDataset_Final.csv", na_values=[""])
#-- 一级核对:形状
print("rows", len(df), "cols", df.shape[1])
#-- 二级核对:通道与判定两个关键分类字段的取值集合
print(sorted(df["report_source"].dropna().unique()))
print(sorted(df["covid19_diagnosis"].dropna().unique()))
#-- 三级核对:结局分级的取值集合,确认第 3 档是否为空
print(sorted(df["covid19_outcome_levels_2"].dropna().unique()))
PY

§6 与库内词条的关系

6.1 区隔表

库内涉及新冠的词条已过百,逐个比对不现实,但按「人群 × 数据来源 × 粒度」三个轴可以切成几族。下表只列与本集最容易混淆的十一个,逐一说明切分点。

词条 它的重心 与本集的切分点
ISARIC-CCP 全球新冠住院前瞻队列,标准化病例报告表 它只收住院者、字段是临床级;本集收门诊与未就诊者,字段是自报级
N3C 美国全国 EHR 协作网络,有明确人群分母 它来自病历、可算率;本集来自问卷、不可算率
VIRUS 注册 全球 ICU 前瞻注册,聚焦器官支持 它覆盖重症端;本集几乎不覆盖重症端
NWICU 芝加哥多院区 ICU 电子病历 单一都市圈、ICU 专属;本集全球自愿、非 ICU
CDSL 西班牙单中心多模态(EHR 六表 + 百万级影像) 它有多模态与检验值;本集只有结构化问答
新冠胸片与 CT 影像库(多篇) 影像与病灶标注 完全正交:本集无任何影像字段
COVIDx 一类胸片基准 影像分类评测 同上,任务与数据形态都不同
VAERS 疫苗不良事件被动上报 它是接种后安全信号;本集问的是感染后经过,且无疫苗字段
Synthea 新冠专供 合成数据 它是生成的人造记录;本集是真实自报,但同样不可算率
UK Biobank 一类人群队列 有分母、有基因与影像、有链接病历 它能算率、能做纵向;本集不能
各国 MS 登记库类词条 全病程随访、字段标准化 它们有随访与分母;本集只有一次快照

这张表的核心结论是:本集与库内所有新冠词条都不构成实质重合。它不是更小的 ISARIC,也不是更粗的 N3C,而是一个在「人群」轴上独一无二的存在——唯一一份以多发性硬化患者为主体、以患者自报为底色、以无条件开放为许可的交叉人群数据。库内没有任何一篇以 MS 为主体展开,也没有任何一篇以患者自报为主要通道。

6.2 关系图谱

关系类型 对象 说明
同人群不同数据源 各国 MS 登记库类资源 同一个患者群体,一个走病历、一个走问卷
同疾病不同人群 ISARIC-CCP、N3C、VIRUS 同是新冠,人群是全人群而非 MS 专属
同平台同许可 PhysioNet 上的其他开放临床表 同一套版本管理与 DOI 体系,引用格式可复用
同方法学谱系 其他做过小单元格风险评估的开放登记库 共享「先分类再处理」的去标识化思路
可互补 影像类新冠数据 若将来出现带 MS 标签的影像集,可与本集按人群描述互补
不可互补 疫苗安全类数据 变量域不重叠,无法拼接

6.3 检索路径

你想找什么 该去哪个词条 为什么不去本集
新冠住院患者的临床过程 ISARIC-CCP 本集无住院期指标
有分母的感染率与病死率 N3C 或人群队列类 本集分母不可定义
新冠重症的器官支持 VIRUS 注册 本集重症样本极少
新冠影像与病灶标注 影像类词条 本集无影像
疫苗与不良事件 VAERS 一类 本集无疫苗字段
MS 的长期残疾进展 MS 登记库类资源 本集无随访
MS 患者感染后的自报症状谱 本篇 这正是它唯一的强项
小样本临床数据的教学素材 本篇 体积、缺失、偏倚、许可四项都合适

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

评估这份数据时,最容易发生的误判是把「小」直接读成「差」。一千余行的体量在临床数据里确实偏小,但体量小是设计选择的结果,而不是采集失败的残骸:为了让全球患者能在几分钟内填完,问卷必须短;为了让数据能在疫情期间快速开放,流程必须轻;为了通过伦理与隐私审查,粒度必须粗。这三条约束共同决定了最终形态。

第二个容易发生的误判是把「自报」直接读成「不可信」。自报在症状体验与行为(隔离、就医决策)上有独特优势,在用药名称与残疾评分上有明显劣势。正确的评估方式不是给整份数据打一个笼统的可信度分数,而是按字段分层判断:哪一层可以放心用,哪一层只能当粗变量,哪一层基本不能用。

§4.3 的案例之所以连「这个人有几项症状」都算不清,正是粒度损失与结构性缺失叠加的结果,而不是记录写错了。做完这两个校正之后,剩下的评估才有意义:下面五维评分与 DAIMS 二十四项,都是在「它本来想做成什么」这个前提下打的分。

7.1 五维评分

维度 得分 依据
文档完备度 4.5 / 5 变量清单、匿名化流程、伦理批号、代码仓库齐备
结构规整度 4.5 / 5 单表、命名统一、取值域封闭、主键唯一
标签可信度 2.5 / 5 九成自报,关键临床字段无外部核验
分析就绪度 3.0 / 5 可直接读入,但必须自行切人群、构造结局、处理结构性缺失
许可与可及性 5.0 / 5 CC BY 4.0,无门槛下载,可商用
综合 3.9 / 5 工程与合规接近满分,统计可用性受采集方式硬约束

7.2 DAIMS 二十四项评估

DAIMS 是千方医数集用于评估数据 AI 就绪度的框架,八个维度各三项,每项按 0、0.5、1 三档打分,满分 24。

维度 检查项 得分
文档 变量字典完整且可对上字段 1
文档 采集流程与伦理交代清楚 1
文档 版本与变更记录可追溯 1
机读 单一表格、无需解析嵌套结构 1
机读 字段类型一致、取值域封闭 1
机读 主键唯一、无重复行 1
标签 结局变量定义明确 1
标签 关键标签有外部核验 0
标签 症状级标签可直接用于监督学习 0.5
可访问 无需申请即可下载 1
可访问 提供校验和 1
可访问 提供多种获取方式 1
许可 许可明确且机器可读 1
许可 允许商用 1
许可 允许再分发 1
格式 通用格式、无私有编码 1
格式 日期与分类编码自解释 0.5
格式 字符编码与分隔符规范 1
评测 有官方基线或参考分析 0.5
评测 有划分建议 0
评测 有公开排行榜或基准 0
生态 有配套代码 1
生态 有第三方二次使用 1
生态 有活跃维护 0.5
合计 — 19 / 24

十九分里,扣分集中在三处:标签核验(自报无外部对照)、评测基线(无官方划分与排行榜)、维护活跃度(数据冻结、工具已下线)。这三处扣分恰好对应它的三个真实短板,而不是文档或格式上的疏忽。

7.3 已知的、可枚举的偏差

偏差在这里不是抽象的免责声明,每一条都能落到具体字段上,也都能预判它把结论往哪个方向推。

偏差 机制 把结论推向哪边
自愿填报 更关注疾病、信息更充分、与社群联系更紧的人更可能填 高估用药知晓率与症状报告意愿
幸存者效应 重症与死亡者无法自报,医生代填量又小 低估重症比例,死亡档直接缺失
时代偏倚 窗口覆盖原始株到德尔塔,止于接种普及前 结论不能平移到奥密克戎时代
地理与体系 无国别字段,住院阈值随医疗体系剧烈变化 住院结局的跨国可比性被削弱
通道混合 自报与医生填报的纳入机制不同 混合分布不对应任何真实人群
粒度损失 年龄、体质指数、EDSS、治疗时长全部二分或四档 非线性关系无法刻画,J 形曲线被抹平
无对照 既无未感染的 MS 患者,也无非 MS 感染者 「MS 是否更易重症」在集内无解

七条里有三条是结构性的,无法通过统计手段补救:没有分母、没有对照、没有时间戳。另外四条可以通过分析设计部分缓解——分层报告能拆开通道混合,敏感性分析能界定粒度损失的影响范围,而在结论里明确写出时代窗口,则是对外推最便宜的防护。

7.4 外部验证矩阵

验证方向 可用参照 能验证什么 不能验证什么
人群构成 各国 MS 登记库的公开汇总 年龄与性别结构是否偏离 用药分布是否偏离(登记库口径不同)
结局量级 住院队列的重症比例 数量级是否离谱 精确率值(分母不同)
字段定义 同领域的问卷类研究 变量语义是否一致 填报质量
分析可复现 官方代码仓库 读入与清洗是否一致 结论是否成立
二次使用 已发表的独立分析 数据是否真的可用 结论的外部效度

这张矩阵的读法是:能被验证的部分几乎都在「结构对不对」,不在「结论准不准」。这是自报数据的固有属性。

7.5 它为何能持续:一次性的采集,长期的教学位

疫情结束后,GDSI 的录入工具在 2022 年 2 月下线,数据内容随之冻结,这份文件不会再增长。按常理,一个冻结的、一千余行的、偏倚明显的自报数据集应该迅速沉底。它没有,原因是它占据了三个不会消失的位置。

第一个位置是教学。方法学课程永远需要一份「小、真、脏、可自由分发」的数据,这个组合极难凑齐:真实数据通常受许可限制,可自由分发的通常是合成数据,而合成数据讲不了真实的选择偏倚。它同时满足四个条件,于是被反复取用。

第二个位置是方法学示范。它的匿名化流程是小样本登记库开放的教科书式案例:先分类、再逐项处置、最后用 k-匿名与 l-多样性兜底。任何准备开放自己登记库的团队,都可以把这份论文当作操作手册。

第三个位置是历史档案。它记录了疫情初期 MS 社群最想知道的那个问题的原始提问方式——不是「感染率多少」,而是「我在用这个药,我该怎么办」。这种问题意识在后来的大型队列里被标准化掉了,只剩这份问卷还留着它。

§8 生态位与历史

8.1 一条从应急到归档的时间线

时间 事件 意义
2020 年初 计划启动 疫情初期,MS 社群自发组织,目标是在数周内开始收数
2020 年 中央平台上线,问卷开放 QMENTA 提供平台,患者与医生双通道填报
2020 至 2021 年 数据持续累积,产出多篇分析 为用药与感染的讨论提供最早的一批实证
2022-02-03 录入工具下线 采集窗口关闭,数据定格
2023-05-30 PhysioNet v1.0.0 发布 公开子集首次可下载,DOI 分配
2023-05 主数据文件时间戳 说明数据内容在首版后基本冻结
2024-01-02 v1.0.1 发布 发布包层面修订,许可与校验和更新
2024 年 Scientific Data 论文发表 匿名化方法学获得同行评议背书

这条时间线里最值得注意的是采集与发布的时差:工具在 2022 年初就下线了,公开版本到 2023 年中才出现。这一年半的间隔主要花在匿名化方案的设计与审查上——小样本数据的去标识化比大样本更难,因为每一条记录都更接近唯一。

8.2 与大型 MS 登记库的分工

大型登记库与这份数据的关系不是替代,而是分层。登记库回答「这个人群长期怎么走」,本集回答「这一批人在那个特殊时点经历了什么」。前者需要持续投入、需要机构背书、需要多年积累;后者只需要一次问卷、一个平台、一次伦理审批。两者在时间尺度上相差两个数量级,在结论的稳健性上也相差两个数量级。

合理的用法是把本集当作探索性证据的来源:先用它提出假设(比如某类药物的住院比例是否偏高),再在有分母、有随访的登记库里验证。反过来用——用登记库的结论去否定本集的描述——意义不大,因为两者的目标人群本就不同。

8.3 与新冠队列的分工

轴 住院队列(ISARIC、VIRUS 一类) 本集
入组 住院或 ICU 治疗者 任何愿意填报的 MS 患者
数据来源 病历与临床表单 问卷自报
严重度覆盖 中重症为主 轻症与未就诊为主
分母 有(住院人群) 无
随访 院内至出院 单时点
独特价值 器官支持与死亡的精细刻画 用药背景与患者体验

两个谱系合起来才构成完整图景:住院队列告诉你「重的那一端长什么样」,本集告诉你「轻的那一端和没就诊的那一端长什么样」。任何只用一个谱系去推断全貌的分析,都会在另一端失真。

8.4 开放共享的方法学遗产

这份数据留下的最实用遗产,不是那一千余行记录,而是它证明了一件事:小样本、敏感人群、多来源的登记数据,可以在不做访问限制的前提下合法开放。路径是清楚的——先做变量分类,再对直接标识符做移除、对间接标识符做约束,用日期扰动与分箱切断外部对齐的可能,最后用 k-匿名与 l-多样性给出可验证的下限。

这条路径对国内的患者登记项目有直接参考价值。很多团队卡在「数据太敏感不敢开放」与「开放了怕被反推」之间,实际上缺的不是技术,而是一套能写进伦理申请、能被审查者接受的处置流程。这份论文的匿名化章节可以直接当模板用,它的每一步都有明确的输入、输出与判定标准。

§9 使用指引

9.1 三种角色的路径

角色 最短路径 需要注意
临床研究者 下载 → 切确诊疑似子集 → 定义住院结局 → 按用药分组做描述与粗略关联 → 明确声明不可算率 不要报率;不要在无时序的情况下谈因果
数据科学教学者 下载 → 演示结构性缺失 → 让学生自己算一次住院率并解释为何无效 → 讲结局变量构造 提前准备「为什么这个数没意义」的标准答案
患者组织分析志愿者 下载 → 只做症状与隔离行为的描述 → 与病友社群经验对照 → 标注自愿填报 绝不把描述统计包装成「病友群体的真实比例」
方法学研究者 精读匿名化章节 → 对照自己的登记库逐项评估 → 借鉴处置流程 注意 k 与 l 的取值需按自己的数据重算

9.2 一条最短的可用流程

从零到跑出一个可解释的关联,最短的路径是六步:取数、读入、切人群、定结局、控混杂、报边界。

#-- 六步走完的最小脚本,输出三张表:人群、结局、粗关联
mkdir -p work && cd work
wget -q -r -N -c -np https://physionet.org/files/patient-level-data-covid-ms/1.0.1/
python3 - <<'PY'
import pandas as pd, numpy as np
p = "physionet.org/files/patient-level-data-covid-ms/1.0.1/GDSI_OpenDataset_Final.csv"
df = pd.read_csv(p, na_values=[""])

#-- 第一步 取数与读入已完成,先报规模
print("总行数", len(df), "总列数", df.shape[1])

#-- 第二步 切人群
d = df[df["covid19_diagnosis"].isin(["confirmed", "suspected"])].copy()

#-- 第三步 定结局
d["severe"] = d["covid19_outcome_levels_2"].isin([1, 2]).astype(int)

#-- 第四步 控混杂:年龄、性别、表型、合并症四个粗变量
tab = pd.crosstab(d["current_dmt"], d["severe"], normalize="index").round(3)
print(tab)

#-- 第五步 分层复核,避免辛普森反转
for k, g in d.groupby("ms_type2"):
    print(k, len(g), round(g["severe"].mean(), 3) if len(g) else "NA")

#-- 第六步 报边界:明确写出分母不可定义
print("本次分析的分母为自愿填报者,不代表任何人群")
PY

这段脚本故意写得很朴素,因为它示范的是流程而不是模型。真实分析还需要加置信区间、做敏感性分析、检查共线。但它已经把最重要的三件事做完了:切对了人群、定对了结局、说清了边界。

9.3 引用方式

引用这份数据要分两层:数据本身与论文。数据引用使用 PhysioNet 的版本化格式,必须带版本号与 DOI,因为不同版本的文件可能有细微差异。

Khan H, Geys L, baneke p, Comi G, Peeters L. Patient-level dataset to study the effect of COVID-19 in people with Multiple Sclerosis (version 1.0.1). PhysioNet. 2024. DOI: 10.13026/77ta-1866. RRID: SCR_007345.

论文引用使用期刊格式:

Khan H, Geys L, Baneke P, Comi G, Peeters L. Patient level dataset to study the effect of COVID-19 in people with Multiple Sclerosis. Scientific Data. 2024. DOI: 10.1038/s41597-024-02978-x.

若使用 PhysioNet 平台本身的分析工具或镜像服务,按平台要求还需同时引用平台标准文献。BibTeX 的文献类型用 article,字段保留版本号与 DOI。

§10 AI 使用声明

项目 声明
可用于训练 结构化表格的缺失处理、类别编码、结局构造、小样本关联分析
不建议用于训练 影像、文本生成、长序列建模(本集无相应数据)
标签来源 患者自报为主,少数为医生填报,无外部核验
人群代表性 自愿填报的多发性硬化患者,不代表全体患者
伦理约束 原数据已按 HIPAA 口径去标识化,禁止任何重新识别尝试
许可义务 CC BY 4.0,署名并标明改动
失效场景 任何需要分母、时序、地理维度或疫苗信息的任务
责任边界 基于本集训练的模型不得直接用于临床决策

常见误读(避坑清单)

说法 实际 证据
这是新冠疫苗在 MS 患者中的研究 研究的是感染后的经过,采集期早于大规模接种 变量表无疫苗字段;工具 2022-02-03 下线
这是某家医院的 MS 队列 全球自愿填报,无中心与国别 数据说明页无站点字段,致谢平台方而非医院
一千多例就是一千多个住院病人 绝大多数未住院,住院是少数事件 结局分级四档中 0 档为主体
可以算出 MS 患者的感染率 分母不可定义,填报自愿 无人群基数字段,无抽样框说明
症状十列可以直接做多标签分类 成组结构性缺失,留空不等于阴性 分支问卷逻辑;症状列全缺行占比高
死亡档为空说明没人死亡 是没人被记录为死亡,重症者难以自报 结局分级第 3 档在集内无记录
这是多模态数据 单表、纯结构化短码 文件清单仅一个 CSV,无影像无自由文本
有日期列可以做波次分析 唯一日期是停用 DMT 日期且已扰动 变量表无感染日期;日期逐行平移
许可严格,需要申请 无需申请,CC BY 4.0,可商用 许可文件与页面标注一致
数据量小所以是残缺版 小是设计结果,全量公开子集 论文说明公开的是经脱敏的子集,非截断

FAQ

Q1:这份数据到底属于「新冠队列」还是「MS 队列」?
两个标签都只对一半。它的入组条件是「多发性硬化患者」加「愿意填报新冠相关状态」,所以人群是 MS 专属,事件是新冠专属。把它归入任何一边的队列清单都会误导检索,最准确的描述是「MS 人群的 COVID-19 横断面自报快照」。

Q2:一千一百余例在国际合作研究里算大还是小?
在 MS 这种相对低患病率、且需要跨国动员的疾病里,短时间内凑到这个量级并不容易;但放到新冠研究里,它与住院队列的规模差两到三个数量级。判断大小要看参照系,不能脱离语境。

Q3:为什么没有任何地理信息?
因为采集时就没有设计这一维度。问卷面向全球患者,未要求填写国家,脱敏阶段也没有可恢复的地理线索。想做地区分析必须换数据源。

Q4:能不能把它和 N3C 或 ISARIC 拼起来用?
只能做分布层面的对照,不能做个体层面的拼接。两者没有共享主键,也没有可用于匹配的准标识符组合,任何匹配尝试都会同时违反隐私原则与统计有效性。

Q5:症状字段那么多空值,是不是数据质量差?
不是。那是分支问卷的正常产物:没有症状的人不会被追问具体症状。问题不在数据,而在分析者是否意识到「留空」与「否」不是一回事。

Q6:为什么 EDSS 只有两档?
为了在几分钟的问卷里让患者能答。完整 EDSS 需要医生评估,自报不现实。两档(6 分及以下、6 分以上)是折中,代价是丢失了中间段的信息。

Q7:结局分级里的第 3 档为什么是空的?
因为死亡病例几乎不可能由本人填报,而医生填报的样本量又很小。这一档保留在编码体系里,是为了与其他 GDSI 数据保持口径一致,不代表数据里应该有。

Q8:可以用于商业产品吗?
可以。CC BY 4.0 允许商业使用,义务只有署名与标明改动。但商业使用不等于可以宣称代表性,产品文案里任何「MS 患者群体比例」的表述都缺乏数据支持。

Q9:v1.0.0 和 v1.0.1 该引哪个?
引当前版 v1.0.1,DOI 为 10.13026/77ta-1866。两版的数据内容差异很小,但版本号是引用的一部分,写错会导致复现困难。

Q10:如果我要做一个 MS 与新冠的预测模型,这份数据够吗?
不够独立支撑。它可以作为外部小样本校验集,或者作为特征工程的探索集,但训练与验证都需要有分母、有随访的数据。用它单独训练出的模型,学到的更多是填报行为而非临床风险。

Q11:为什么它被归类为电子健康记录而不是调查数据?
两个标签都成立。它的内容是健康状态记录,形态是结构化表格,所以归入电子病历大类;它的采集方式是问卷自报,所以同时带调查数据属性。分类体系里两者并不互斥。

Q12:这份数据会更新吗?
数据内容已冻结,工具已下线。未来的变化只可能发生在发布包层面(许可文本、元数据、平台迁移),不会有新记录加入。

术语表

术语 含义
PwMS People with Multiple Sclerosis,多发性硬化患者
MS Multiple Sclerosis,多发性硬化,中枢神经系统炎性脱髓鞘疾病
GDSI COVID-19 and MS Global Data Sharing Initiative,本集的来源计划
DMT Disease-Modifying Therapy,疾病修正治疗,改变病程而非仅缓解症状的药物
EDSS Expanded Disability Status Scale,扩展残疾状态量表,0 至 10 分
复发缓解型 发作后部分或完全恢复的病程类型,MS 中最常见
进展型 功能持续下降、不以发作为主的病程类型
抗 CD20 消耗 B 细胞的单抗类治疗,如奥瑞珠单抗、利妥昔单抗
免疫重建治疗 以阿仑单抗、克拉屈滨为代表的强效诱导方案
糖皮质激素 急性期冲击用激素,与长期 DMT 不同
合并症 除 MS 与新冠之外的其他慢性疾病
小单元格风险 样本中取值极少的单元格可能指向个体的风险
直接标识符 姓名、联系方式一类可单独识别个体的字段
间接标识符 年龄、性别、地区等组合后可识别个体的字段
k-匿名 要求每组准标识符至少对应 k 条记录
l-多样性 要求同组内敏感属性取值足够分散
日期平移 对日期做随机偏移以切断外部对齐
结构性缺失 由问卷分支逻辑导致的缺失,携带信息
选择偏倚 参与者的纳入机制与目标人群不同导致的偏差
幸存者偏倚 重症或死亡者无法进入样本导致的偏差
横断面 单一时间点的观测,无随访
分母不可定义 无法确定目标人群规模,比率无意义
完整案例分析 只保留所有变量均非缺失的记录
敏感性分析 改变处理方式看结论是否稳健
外部效度 结论能否外推到样本之外的人群
DAIMS 千方医数集的数据 AI 就绪度评估框架,八维二十四项

附录 A:核心数字核对表

项 值 来源 来源层级
患者数 1,141 PhysioNet 数据说明页原文 官方页面
变量数 47(可点名对上 46 个) 数据说明页 n=47 官方页面
主数据文件 GDSI_OpenDataset_Final.csv 文件清单 官方页面
主文件大小 221.2 KB 文件清单 官方页面
整包大小 237.4 KB 文件清单 官方页面
记录粒度 一人一行 变量表与论文 官方页面
首版日期 2023-05-30 版本页 官方页面
当前版日期 2024-01-02 版本页 官方页面
DOI 10.13026/77ta-1866 版本页 官方页面
许可 CC BY 4.0 许可文件 官方页面
伦理批号 CME2020/025 AMD3 数据说明页 官方页面
工具下线 2022-02-03 数据说明页 官方页面
论文期刊 Scientific Data Europe PMC 检索 论文摘要
论文年份 2024 Europe PMC 检索 论文摘要
填报通道比例 患者为主、医生为辅 数据说明页 官方页面
死亡档记录数 集内为空 变量表取值说明 官方页面

附录 B:数字的来源分层

第一层:官方页面。 患者数、变量数、文件清单与大小、版本日期、DOI、许可、伦理批号、工具下线日期、字段名与取值域,全部来自 PhysioNet 项目页与版本页的正文。这一层的数字可以直接引用,不需要二次核对。

第二层:论文摘要。 采集背景、计划动因、公开子集与全量的关系、教育用途的定位,来自 Scientific Data 论文摘要与 Europe PMC 的检索记录。摘要能确认方向,但具体数字仍以官方页面为准——两者若冲突,以官方页面为发布口径。

第三层:未核实与不可核实。 国别构成、填报者的招募渠道、各中心参与度、症状的真实临床判定标准,这些在公开材料里没有交代,本集也没有相应字段。凡是正文中出现「未说明」「官方未展开」的表述,都属于这一层。使用时不要用推测填补。

附录 C:完整参考文献

  1. Khan H, Geys L, Baneke P, Comi G, Peeters L. Patient level dataset to study the effect of COVID-19 in people with Multiple Sclerosis. Scientific Data. 2024. DOI: 10.1038/s41597-024-02978-x.
  2. PhysioNet. Patient-level dataset to study the effect of COVID-19 in people with Multiple Sclerosis, version 1.0.1. 2024-01-02. DOI: 10.13026/77ta-1866. RRID: SCR_007345.
  3. PhysioNet. 同一数据集的 v1.0.0 版本页,2023-05-30 发布,用于版本差异比对。
  4. GDSI 开源代码仓库(数据集说明页给出的分析管线地址),用于复现读入与清洗步骤。
  5. PhysioNet 平台标准引用文献,用于平台层面的引用义务。
  6. 本集许可全文(LICENSE.txt),CC BY 4.0 的完整条款。
  7. 数据说明页附列的 GDSI 计划背景文献,用于理解问卷设计的临床动因。

附录 D:任务代码

下面是一段可直接运行的完整脚本,把「取数—清洗—建模—报边界」四步走完,用于在本地做一次端到端的可行性验证。

#-- 端到端最小验证:逻辑回归 + 自助法置信区间 + 边界声明
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

PATH = "data/gdsi-1.0.1/GDSI_OpenDataset_Final.csv"
df = pd.read_csv(PATH, na_values=[""])

#-- 人群:确诊或疑似
d = df[df["covid19_diagnosis"].isin(["confirmed", "suspected"])].copy()
d["severe"] = d["covid19_outcome_levels_2"].isin([1, 2]).astype(int)

#-- 特征:只用覆盖度尚可的粗变量
feat_cat = ["age_in_cat", "sex", "ms_type2", "current_dmt", "has_comorbidities"]
d = d.dropna(subset=feat_cat + ["severe"])
X = d[feat_cat].astype(str)
y = d["severe"].to_numpy()

pre = ColumnTransformer([("oh", OneHotEncoder(handle_unknown="ignore"), feat_cat)])
pipe = Pipeline([("pre", pre), ("lr", LogisticRegression(max_iter=2000, class_weight="balanced"))])

#-- 自助法:小样本下比解析解更稳
rng = np.random.default_rng(20261028)
coefs = []
for _ in range(500):
    idx = rng.integers(0, len(d), len(d))
    pipe.fit(X.iloc[idx], y[idx])
    names = pipe.named_steps["pre"].get_feature_names_out(feat_cat)
    coefs.append(pd.Series(pipe.named_steps["lr"].coef_[0], index=names))
boot = pd.concat(coefs, axis=1)
summary = pd.DataFrame({
    "median_odds_ratio": np.exp(boot.median(axis=1)),
    "lo": np.exp(boot.quantile(0.025, axis=1)),
    "hi": np.exp(boot.quantile(0.975, axis=1)),
}).sort_values("median_odds_ratio", ascending=False)
print(summary.head(12).round(3))

#-- 边界声明:必须随结果一起输出
print("分母为自愿填报者,非人群样本;结果仅供假设生成")

这段代码有三处刻意的设计。第一处是用 class_weight 平衡类别,因为重症在子集里是少数,不平衡会让模型倾向于全部预测为轻症。第二处是用自助法而不是解析标准误,因为小样本下解析解对稀疏类别过于乐观。第三处是把边界声明写进脚本输出,确保任何人跑一遍都会看到那句提醒,而不是只在论文里出现一次。

附录 E:如果只记五件事

  1. 它是一份多发性硬化患者的 COVID-19 横断面自报数据,一千一百余行、四十七列、单表两百多 KB。
  2. 九成以上记录由患者自报,症状与住院信息没有病历核验,这是它最大的软肋,也是它唯一的独特视角。
  3. 分母不可定义,任何感染率、住院率、病死率都算不出来;想做率的问题必须换数据源。
  4. 无日期、无国别、无随访、无疫苗字段,这四项缺失划定了它的能力边界。
  5. 许可为 CC BY 4.0,无门槛可商用;它最稳的用途是教学与方法验证,不是流行病学推断。

编辑说明

核验时间:2026-10-28。核验方式:逐页读取 PhysioNet 项目页与 v1.0.1 版本页的正文、文件清单、变量说明、许可与引用段落;通过 Europe PMC 检索确认论文题录与摘要;未下载主数据文件做逐行统计,正文中不含任何需要下载后才能得到的分布类数字。

数字口径:规模与结构类数字(行数、列数、文件大小、版本日期、DOI)以官方页面为准;边界类判断(分母不可定义、死亡档为空、无国别字段)以变量表取值域与说明页表述为准。官方称变量数为 47、变量表可点名对上 46 个,差额 1 个未做推测,按「官方未展开说明」处理。

未覆盖内容:填报者的国别分布、各招募渠道的贡献比例、问卷的具体题面措辞、症状判定的临床标准、GDSI 全量与公开子集的差额构成。这些均未在公开材料中给出,正文相应位置已标注。

体例说明:全文不含对原始数据的逐行统计表述,因为本篇未下载主表做分布核算;凡涉及同库其他词条,只写其重心与切分点,不引用其内部数字。

医学免责声明:本篇为数据资源说明,不构成医疗建议。任何基于该数据的分析结论,在用于临床决策前必须经过独立验证。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • cdsl-covid-data-shared-learning — 共享标签:电子健康记录 / 公共卫生与流行病学 / COVID-19
  • encode-chile — 共享标签:电子健康记录 / 公共卫生与流行病学 / 调查数据
  • abdm — 共享标签:电子健康记录 / 公共卫生与流行病学 / 调查数据
  • knhanes — 共享标签:电子健康记录 / 公共卫生与流行病学 / 调查数据
  • synthea-covid — 共享标签:电子健康记录 / 公共卫生与流行病学 / COVID-19
  • flatten-covid-survey — 共享标签:公共卫生与流行病学 / COVID-19 / 调查数据
  • charls — 共享标签:电子健康记录 / 公共卫生与流行病学 / 调查数据
  • nwicu — 共享标签:电子健康记录 / 公共卫生与流行病学 / COVID-19
  • meps — 共享标签:电子健康记录 / 公共卫生与流行病学 / 调查数据
  • mimicel — 共享标签:电子健康记录 / 公共卫生与流行病学

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集