笔者近期针对门诊患者的心理量化特征(焦虑/抑郁指数)展开了一系列研究,并推进了基于 AI 驱动的门诊病患焦虑抑郁识别工作。本文是该系列研究的基座篇——数据构建与预处理管线(Data Pipeline)设计。 笔者首先与医学同学们完成了原始的医疗场景语音数据采集与 TTS(语音转文字)工作。数据池包含了 133 份门诊场景下患者与医生的对话转录文本(涵盖初诊与复诊),以及每位患者在门诊后填写的 PHQ-9(抑郁)和 GAD-7(焦虑)心理量表。至此,我们获得了医患对话的原始文本与对应的心理指标对照组。
在深度学习(尤其是大模型)普及之前,特征工程是 NLP 任务的核心。即使在今天,在处理特定垂直领域数据或使用轻量化机器学习模型(如 SVM、XGBoost)时,特征工程依然至关重要,更何况在我们的研究场景下特征工程其实。我们的愿景是构建一套高精度、多维度的自然语言数据集。这套数据集不仅是对门诊对话的简单记录,更是要通过特征工程,将非结构化的医患互动转化为可计算、可感知的“数字心理表型“。
然而在 NLP 与医疗大模型的交叉领域,真实的门诊对话数据是极具价值的“富矿”。然而,现实中的门诊录音转写文本往往是极其非结构化、充满噪音且缺乏语境的。
在进入深度的特征挖掘(Feature Mining)之前,特征工程的第一步,也是最重要的一步,是数据清洗、多源对齐与结构化重塑。本文将详细记录我是如何将零散的“门诊对话文本”与“心理量表表格”,加工成符合大模型训练与纵向特征追踪的高质量结构化数据集的。
1. 有参考性的开源数据集与工业标准
门诊对话数据集和心理数据集早有相应的成熟范例,然而医疗门诊对话数据集却没有相关资料,这暗示我参考现有的开源数据集和工业标准制订相关的。在设计自己的数据集架构前,我参考业内权威的数据集标准,以保证未来管线的可扩展性与兼容性。
1.1 全球心理健康计算权威:DAIC-WOZ (The Distress Analysis Interview Corpus)
DAIC-WOZ 是用于抑郁症检测的标杆数据集,它具有分离式存储架构:采用了“元数据表 + 原始记录”分离的方式。train_split.csv 仅存储病人 ID 和 PHQ-8 总分(Label);而另一个独立文件夹存放具体的对话转录(Transcript)。这为我们处理 .csv 量表与 .txt 文本的对齐提供了标准范式。值得注意的是其 Transcript 文件严格保留了 start_time 和 end_time 字段,这种时间戳的标注为未来的多模态(音频特征)分析留下了切入口。
- 格式:“元数据表 + 原始记录”分离**的存储方式。
- 样例:
- CSV 表 (train_split.csv):只存 ID 和 标签(PHQ-8分数)。
Participant_ID, PHQ8_Binary, PHQ8_Score, Gender 303, 0, 0, 0 304, 0, 6, 0- Transcript 文件 (303_TRANSCRIPT.csv):存具体对话,带有详细的时间戳。
start_time, stop_time, speaker, value 10.5, 12.1, Ellie, How are you doing today? 12.5, 14.2, Participant, I am doing good. - 借鉴意义: .xlsx 和 .txt 分离存储完全符合这一标准。在论文中可以写:“Followed the data organization structure of the DAIC-WOZ corpus.”
1.2 中文医疗标准:IMCS-21 (Intelligent Medical Consultation System)
IMCS-21 是目前国内医疗对话理解领域的基准数据集(Benchmark),被广泛应用于国内顶尖科研机构及大模型医疗微调的评测中。该数据集已在 GitHub 完全开源,具有行业参考价值。
- 特点:高度结构化的实体标注(NER)。它不仅有对话,还标注了这句话是在谈论“症状”、“药物”还是“检查”。
IMCS-21 带来的最大启发在于其高度结构化的字段定义。在我们的数据管线构建初期,即使当前阶段尚未引入自动化的实体提取工具,也应当参考其规范,在 JSON 架构中预留出
diagnosis(诊断结果)、symptoms(症状列表)、medication(用药建议)等关键字段,即使现在是空的,也有可能等未来管线自动化提取时填入,确保数据集的向前兼容性。
1.3 大模型微调标准:OpenAI Chat Format / ShareGPT格式
这是目前训练 Llama 3, Qwen, ChatGLM 等大模型最通用的格式。将所有对话转化为 messages 列表,包含 role 和 content,如果把数据整理成这个格式,未来不需要任何转换就能直接拿来微调大模型。
{ "conversations": [ {"from": "human", "value": "医生,我最近总是失眠。"}, {"from": "gpt", "value": "这种情况持续多久了?"}, {"from": "human", "value": "大概两周了。"} ], "system": "你是一个专业的心理医生。" }
这是目前工业界微调模型最通用的接口。把数据做成这样,兼容性最强。然而这可能与保留我们的保留原有的医患对话数据集的初衷背离。
2. 数据清洗
数据脱敏
在医疗数据处理中,隐私保护是不可逾越的底线,我引入了基于深度学习的命名实体识别(NER)方案:roberta-base-finetuned-cluener2020-chinese是HuggingFace上的较为出名的简体中文命名体识别模型,模型基于 RoBERTa 中文预训练模型,并在 CLUENER2020 数据集上进行微调。CLUENER2020 是一个细粒度的中文命名实体识别数据集。
接着我使用roberta-base-finetuned-cluener2020-chinese模型进行脱敏,通过 transformers 库加载模型,我们在数据脱敏阶段,精准提取并遮蔽了所有真实人名(替换为 [NAME])与医疗机构名(替换为 [ORG]),满足数据最小化与隐私保护的伦理标准。
说话人标注
在早期 TTS 工作中,由于缺乏统一的 SOP,原始数据的角色标注出现了严重的异构问题:有一位同学的文本目前基本是“纯对话句子逐行”,文本没有身份标签;至于另一位同学,虽然进行了身份的标注工作,但是却也有两套标注风格并存,部分使用了中文标记(如 医生/患者/家属);还有部分混用了半角英文标记(如 【D】/【P】)。
我的目标是将所有说话人统一清洗为干净的 [医生]:、[患者]:、[患者家属]: 的非常干净形式,对此我的解决方案是:
- 启发式规则处理:针对已有显式标记的文本(50 份),编写 Python 正则脚本进行规则匹配与强制替换。
- 大模型辅助划分:针对完全没有说话人标签的纯对话句子(34 份),利用大模型的语境理解能力进行自动化 Speaker 推断与回填。
3. 数据分析
3.1 数据面貌
经过几重处理后,我们现有的数据基本符合进行大规模批处理的前提。我们拿到手的数据属于典型的多源异构数据:
-
量表数据 (.csv): 包含每位患者的编号、年龄、性别以及 GAD-7(焦虑)和 PHQ-9(抑郁)的具体量表得分。
-
对话文本 (.txt): 门诊录音转录文本,文件命名极其不规则,且包含了多轮、多次的门诊对话。
3.2 目标结构设计
为了便于后续提取时序特征和角色特征,笔者采用“以患者为中心(Patient-Centered)”的树状 JSON 架构。 这种设计不仅能绑定静态特征(量表评分),还能将动态特征(多次就诊的对话)按时间线串联:
-
Patient (根节点) -> 包含基础画像(年龄、性别)与心理量表评分。
-
Visits (子节点) -> 记录纵向的多次就诊记录。
- Dialogue (叶节点) -> 包含清洗后的逐句(Turn-level)对话,并打上规范化的角色标签。
-
4. 核心处理管线
基于上述目标设计了批量转换管线:
Step 1: 多源数据对齐与元数据提取
原始文本文件名极度随意(如 101[NAME] 男 58岁.txt 或 102,103[NAME] 女 4岁.txt)。
-
匹配逻辑:通过正则表达式提取文件名前缀数字作为
Patient_ID,将其与量表 CSV 文件中的序号进行关联匹配,生成GAD-7.total和PHQ-9.total节点。 -
属性提取:通过后缀规则优先提取性别、年龄等元数据(Metadata)写入 JSON 根节点。此外,扫描文本首部,若存在“关键词”段落,则提取为症状标签特征。
Step 2: 纵向会话切片
原始文本将患者当天的初诊、复诊混杂在同一个 TXT 中。为了保留时间层次感,系统会识别单行孤立的 [(...)]、OUT、出去 等环境音/动作标记符,将其作为特殊分隔符(Delimiter),自动将长文本切分为独立的 Visit 单元。
Step 3: 角色推断与话轮提取
将单次 Visit 下的文本按行解析为 Turns 列表。在这里加入了一个关键的医疗业务逻辑:儿童与成人患者的角色推断差异。
Python
# 角色映射的核心业务逻辑伪代码
if is_pediatric(age):
# 若为儿童,对话中的“患者”通常指代代为诉说的家属
if raw_role in ["患者", "患者家属", "P"]:
return "caregiver"
else:
# 若为成人,区分患者本人与陪同家属
if raw_role in ["患者", "P"]:
return "patient"
elif raw_role == "患者家属":
return "caregiver"
5. 最终的结构化输出成果
经过以上 ETL(Extract, Transform, Load)流程,原本混乱不堪的文件目录,最终被炼化为了如下高信息密度的 JSON 结构:
{
"patients": [
{
"patient_id": "P-000102",
"name": "[NAME]",
"gender": "女",
"age": 4,
"scales": [
{
"GAD-7": {"total": 14},
"PHQ-9": {"total": 17}
}
],
"visits": [
{
"visit_id": "V-000102-1",
"dialogue": {
"source_file": "102,103[NAME] 女 4岁.txt",
"turns": [
{"role": "doctor", "text": "你好久等[NAME]。"},
{"role": "caregiver", "text": "你好,他看那个腺样体"}
]
}
},
{
"visit_id": "V-000102-2",
"dialogue": { ... }
}
]
}
]
}
伦理声明: 本数据集使用roberta-base-finetuned-cluener2020-chinese模型对于人名和组织进行脱敏,完成身份脱敏,删除所有可直接识别个人的信息(PII),姓名、身份证号、精确联系方式等,处理可能推断出身份的独特病史或社会关系;满足最小化原则, 仅收集研究所必需的数据。满足知情同意,数据采集获得了患者或其监护人的明确同意,并告知数据用途。符合国际和国内(如《个人信息保护法》、HIPAA 或 GDPR)的医疗数据研究伦理标准。
4. 总结
在复杂对话场景的 AI 研究中,“数据结构即特征”。 我们成功解决了异构数据对齐、多轮复诊切分、角色身份规范化以及隐私脱敏四大问题。这一干净、结构化的基座,为下一步开展基于深度学习的情感计算(VADER)、人格特征提取(Personality)、语言探究与词数统计(LIWC-CH)以及最终的焦虑抑郁风险预测模型,铺平了坚实的道路。