案例研究:将医生转录本转化为时间性医疗记录知识图谱

2024/11/15 21:03:04

本文主要是介绍案例研究:将医生转录本转化为时间性医疗记录知识图谱,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

是否对将医生和患者的医疗记录转换为时间线知识图谱感兴趣,以便你可以在多个医疗历史、时间阶段和患者之间提出复杂问题?

在这份案例研究中,我们展示了如何将医疗转录转换为可靠的时间知识图谱,用于信息检索与生成及分析。我们展示了在此系统中的实际问答示例,以及使用该系统可以实现什么样的业务成果。据我们所知,我们认为,这种组合步骤的知识图实现方式相对新颖。

用到的数据

出于数据隐私的原因,我们使用了一个由这里的Synthea数据生成的合成医疗转录数据集:https://synthea.mitre.org/downloads。以下是一个用于构建知识图谱的医疗转录示例。我们将这些转录数据与Synthea数据中的结构化医疗记录结合起来。我们大约有75份转录文件,涉及10位患者(每位患者大约有5到10份转录文件)。下面是一个实际使用的转录示例:

新型知识图架构概览
节点(Nodes):

我们有五种类型的节点:患者、观察、疫苗接种、状况和就诊。

三元组:一些示例:

病人 -> 来看病 -> 看病

病人 -> 患有病症 -> 病

病人已接种疫苗

病人 -> 有测量值 -> 观测结果

块:

块是独立的文本片段。每个块都与一个三元组相关联,一个三元组也可以关联多个块。与作为三元组原始未结构化的文本不同,这里的块是每个三元组类型的摘要和要点。因此,我们有六种类型的块,如下:患者基本信息块(简称患者信息块)、病情摘要块(简称病情摘要)、就诊记录块(简称就诊记录)、观察记录块(简称观察记录)、免疫记录块(简称免疫记录)和病情详情块(简称详情记录)。

以下是一个示例,展示了哪些不同类型片段与三元组关联。

1. 患者 -> 就诊类型代码  
    三元组:(患者) - [had_encounter] -> (就诊类型代码)  
     - Chunk_ids 链接到特定就诊实例  
     - 示例: "2024年1月15日的年度体检。血压120/80,常规筛查结果更新。"  

2. 患者 -> 病症  
    三元组:(患者) - [has_condition] -> (病症)  
     - Chunk_ids 链接到病症发作  
     - 示例: "2020年3月10日确诊高血压。状态:活跃。通过药物治疗。"  

3. 患者 -> 接种疫苗  
    三元组:(患者) - [received] -> (接种疫苗)  
     - Chunk_ids 链接到接种记录  
     - 示例: "2024年1月15日接种流感疫苗。"  

4. 患者 -> 观察数据  
    三元组:(患者) - [has_measurement] -> (观察数据)  
     - Chunk_ids 链接到测量实例  
     - 示例: "2024年1月15日:血压120/80毫米汞柱,体重70kg。"

图表链接如下: https://main--whyhowai.netlify.app/public/graph/673032011997e08c8849316c.

在这样的图架构中,你可以将关键点和摘要与这些三元组(triples)关联起来,然后通过非结构化的搜索,聚焦于找到正确的三元组集,然后通过链接的片段结构化地引入所有相关的关键信息,这样一来,所有相关的关键信息就会结构化地呈现出来。

为何建筑的独特性

有几个WhyHow图基础设施的独特特性,使我们能够以简单的方式构建这一架构。

首先,三元组通过向量搜索进行嵌入和检索,避免了常见的检索问题,即必须通过Text2Cypher识别节点和关系,再构建Cypher查询以找到正确的三元组。这已经证明可以将检索准确性提高多达3倍。详情请见:https://medium.com/enterprise-rag/knowledge-table-multi-document-rag-extraction-memory-ec08450e858f。

其次,Triples 是 WhyHow 中的独立对象,你可以将片段链接到各个 Triple。这让你能够提炼出每个 Triple 中的关键信息,并将其直接带入上下文中。这避免了将关键信息和上下文以图形方式表示,从而使模式构建过程复杂化,并在非结构化向量搜索后以结构化的方式引入信息。这和 LinkedIn 在其系统中应用知识图谱的过程类似,在 LinkedIn 系统中,关键信息,如“重现步骤”,会以类似方式表示和检索,而步骤本身则表示为单独的“片段”/“节点”。

第三,WhyHow接受JSON格式的数据,这使得从任何提取框架无缝对接到图创建变得可能。在这种情况下,我们用Claude将转录数据转换成必要的JSON格式,以便可以加载到WhyHow中。如果你已有JSON格式的数据,这样的话,将数据加载到WhyHow中就会容易得多。

第四,由于WhyHow系统中块(块组)和检索过程的设计方式,你可以轻松地加入时间数据,这些数据可以用来控制答案构建的方式。时间数据在知识图谱中一直难以建模,以至于业内专家通常建议尽量避免使用,但它显然是工作流程中不可或缺的一部分。即使现有的试图建模时间数据的方法也会尝试将这些数据直接纳入知识图谱,通过结构化的Cypher查询进行检索。而我们的架构则利用大语言模型(LLM)的独特功能来帮助筛选相关的时间数据。

我们将大型语言模型与知识图谱结合是实现业务目标的重要方法,我们认为这种结合时序数据的知识图谱架构能够帮助企业取得成果并释放大量业务价值。

我们使用的数据转换过程

首先,我们用Claude将转录信息转化为与模式相匹配的信息集。结合结构化医疗记录中的信息,转录信息被转换成如下格式的JSON摘要:

{
  "transcript": "...",
  "structured_information": {
    "key": "value", // 示例键值对
    "key": "value"  // 示例键值对
  }
}

针对每一份转录文件,都执行上述转换。

    患者总结  
    姓名:约瑟夫·克罗纳  
    出生日期:2022年08月29日  
    年龄:2岁  
    性别:男  
    病历号:#dbfbaa  

    当前测量值(截至2024年08月05日)  
    身高:84.1厘米(第50百分位点)  
    体重:14.5千克(第52百分位点)  
    过敏史  
    无已知过敏  

    疫苗接种情况  
    - 百白破(DTaP):2022年12月05日,2023年02月06日,2023年03月06日,2024年02月05日  
    - 甲型肝炎:2023年11月06日  
    - 乙型肝炎:2022年08月29日,2022年10月03日,2023年03月06日  
    - b型流感嗜血杆菌(Hib):2022年12月05日,2023年02月06日,2023年11月06日  
    - 流感:2023年03月06日,2024年08月05日  
    - 麻疹、腮腺炎、风疹(MMR):2023年11月06日  
    - 13价肺炎球菌疫苗(PCV13):2022年12月05日,2023年02月06日,2023年03月06日,2023年11月06日  
    - 脊髓灰质炎:2022年12月05日,2023年02月06日,2023年03月06日  
    - 轮状病毒:2022年12月05日,2023年02月06日  
    - 水痘:2023年11月06日  

    病史  
    - 病毒性鼻窦炎(疾病)  
    发病日期:2023年03月13日  
    状态:已解决  
    结局:已解决  

    生长发育  
    - 2023年11月06日:体重:12.7千克  
    - 2024年02月05日:身高:79厘米  
    - 2024年02月05日:体重:13.4千克  
    - 2024年08月05日:身高:84.1厘米  
    - 2024年08月05日:体重:14.5千克  
    发展:达到了相应的发育里程碑  
    - 大运动:符合年龄  
    - 精细运动:符合年龄  
    - 语言:符合年龄  
    - 社交:符合年龄  

    预防保健  
    定期随访:  
    - 2024年08月05日:2岁定期随访-发育正常  
    - 2024年02月05日:1岁定期随访-发育正常  
    - 2023年11月06日:1岁定期随访-发育正常  
    - 2023年08月07日:1岁定期随访-发育正常  
    - 2023年05月08日:9个月定期随访-完成符合年龄的检查  
    - 2023年02月06日:6个月定期随访-完成符合年龄的检查  
    - 2022年12月05日:4个月定期随访-完成符合年龄的检查  
    - 2022年10月03日:2个月定期随访-完成符合年龄的检查  
    - 2022年08月29日:新生儿初访-检查结果正常  

    家族史  
    母亲:健康  
    父亲:健康  
    兄弟姐妹:无记录  

    社会史  
    生活情况:与父母同住  
    发展:达到相应的年龄里程碑  
    睡眠:符合年龄的作息  
    营养:符合年龄的饮食习惯

其次,我们将这个 JSON 模式映射转换到 WhyHow 模式,接着将所有的信息导入 WhyHow.AI KG Studio,完成这个过程。

下面是一个加载到WhyHow的知识图结构。

知识图谱结构(永恒):

节点:
1. 患者节点
    结构:{
        name: str,  # "John Smith"
        label: "Patient",
        properties: {
            gender: str,  # FHIR性别
            patient_type: str  # "成人" | "儿童"
        },
        chunk_ids: List[str]  # 链接到具体的记录
    }

2. 就诊类型节点
    结构:{
        name: str,  # "儿童保健" | "年度体检"
        label: "EncounterType",
        properties: {
            category: str,  # "预防" | "急性" | "慢性"
            specialty: str  # "全科" | "儿科" | "急诊"
        },
        chunk_ids: List[str]  # 链接到具体的记录
    }

3. 病症节点
    结构:{
        name: str,  # "原发性高血压"
        label: "Condition",
        properties: {
            category: str,  # "慢性" | "急性" | "已解决"
            system: str,  # "呼吸系统" | "心血管系统" | 等
            is_primary: bool  # 如果是主要诊断
        },
        chunk_ids: List[str]  # 链接到具体的记录
    }

4. 疫苗接种节点
    结构:{
        name: str,  # "百白破" | "麻疹腮腺炎风疹"
        label: "Immunization",
        properties: {
            series: str,  # "初次" | "加强"
            target: str  # "破伤风" | "麻疹" | 等
        },
        chunk_ids: List[str]  # 链接到具体的记录
    }

5. 观察节点
    结构:{
        name: str,  # "血压" | "身高"
        label: "Observation",
        properties: {
            category: str,  # "生命体征" | "实验室检查" | "生长"
            unit: str  # "毫米汞柱" | "厘米" | 等
        },
        chunk_ids: List[str]  # 链接到具体的记录
    }

关系:
1. 患者 -> 就诊类型
    三元组:(患者) -[就诊]-> (就诊类型)
    - chunk_ids 链接到具体的记录

2. 患者 -> 病症
    三元组:(患者) -[有病症]-> (病症)
    - chunk_ids 链接到具体的记录

3. 患者 -> 疫苗接种
    三元组:(患者) -[接种]-> (疫苗接种)
    - chunk_ids 链接到具体的记录

4. 患者 -> 观察
    三元组:(患者) -[有测量值]-> (观察)
    - chunk_ids 链接到具体的记录

5. 病症 -> 就诊类型
    三元组:(病症) -[管理于]-> (就诊类型)
    - 链接到具体的记录

6. 疫苗接种 -> 就诊类型
    三元组:(疫苗接种) -[接种于]-> (就诊类型)
    - 链接到具体的记录

第三,每次自然语言查询之后,我们都会运行一个自定义提示语,为知识图谱中检索到的三元组提供上下文。

有了这样的架构,一个有趣的地方在于,我们现在可以继续轻松地向知识图谱添加关于患者的就诊记录、患者的治疗信息和病情的信息,只需要在现有的三元组基础上添加更多信息。如果患者出现新的疾病,会在患者的节点上添加新的病情节点。

这个过程耗时25个开发人员小时,具体如下:

  • 2小时(8%)用于数据探索(Exploratory Data Analysis)
  • 18小时(72%)用于迭代调整架构,确定哪些点应该连接,哪些块应该存在,如何连接到各种三元组,测试并根据问题迭代结果
  • 2小时(8%)用于编写生成三元组的代码
  • 3小时(12%)用于编写验证和输出检查以捕捉任何错误
医学记录知识图谱问答

请注意,原文使用了Markdown标题格式,因此这里也保留了相应的格式。

用于在从知识图谱检索到相关上下文后构建答案的提示词,利用WhyHow自然语言查询引擎。

你是一位专注于医疗记录分析的人工智能助手。  
使用以下信息回答用户的问题。  
这些信息是从患者医疗记录生成的知识图谱中获取的。  

以下是相关节点(包括患者、就诊和疾病):  
{node_context}  

以下是相关关系(展示患者、就诊和疾病之间的关联):  
{triple_context}  

相关医疗记录:  
{chunk_context}  

请按以下步骤回答问题:  
1. 分析医疗信息,重点关注问题的具体主题  
2. 确定关键的医疗事件、疾病和时间关系  
3. 形成一个清晰简洁的答案,直接回答问题  
4. 如果医疗信息中有任何不确定性,明确指出  
5. 如果没有足够的信息来回答问题,说明这一点  
6. 考虑医疗事件之间的时间关系  
7. 当前日期为{datetime.now().strftime("%Y-%m-%d")},请在解释日期时考虑这一点。  
8. 为保护患者隐私,请在必要时仅使用患者的名字或首字母  

问题:{question}
价值分析:患者治疗分析
历史患者分析报告

问题:约瑟夫·克罗纳 (Joseph Crona) 在他第一年里接受了哪些类型的常规检查和接种疫苗?

答:

为了确定约瑟夫·克罗纳在出生第一年内接受的儿童保健随访和免疫接种的类型,我们需要考虑相关的医疗事件及其时间。约瑟夫出生于2022年,截至目前是2024年11月9日。因此,他的第一年是从2022年到2023年。

**儿童保健随访:**
- 约瑟夫有一次被分类为“儿童保健随访”的就诊,这属于预防性医疗。这种类型的随访通常是儿童常规检查的一部分,尤其是在婴儿期。

**免疫接种:**
在第一年内,约瑟夫接受了以下免疫接种,这些都是儿科患者常见的:
1. **乙肝疫苗,青少年或儿童用** - 已完成
2. **Hib(PRP-OMP)疫苗** - 已完成
3. **轮状病毒单株疫苗** - 已完成
4. **脊髓灰质炎灭活疫苗(IPV)** - 已完成
5. **白喉、破伤风和百日咳疫苗(DTaP)** - 已完成
6. **肺炎球菌结合疫苗(PCV 13)** - 已完成

这些免疫接种通常会在婴儿的第一年内按照标准免疫接种计划进行。

总结来说,约瑟夫·克罗纳在出生第一年不仅接受了儿童保健随访,还完成了标准的儿科免疫接种。

问题:患有中耳炎的患者,他们经历了哪些就诊步骤和观察顺序?

答:

为回答关于患有中耳炎患者的遭遇和观察顺序的问题,我们将重点关注迈尔斯·迪金森的医疗记录,因为他就是被诊断出患有这种病症的患者。

1. **病情发作:**
- 迈尔斯·迪金森于2024年6月10日被诊断出患有中耳炎,目前该病症已经痊愈。

2. **遭遇:**
- 迈尔斯记录了两种类型的遭遇:
- **儿童常规检查:** 这种类型属于儿科预防性检查。
- **症状遭遇:** 这种类型是初级保健的随访检查。

3. **观察结果:**
- 为迈尔斯记录了各种观察结果,包括:
- **疼痛严重程度:** 多次记录,评分范围从0到4。
- **体重:** 记录的数值范围从3.2公斤到8.2公斤。
- **头部前后围和百分位数:** 记录了具体的厘米数值和百分位数范围。
- **心率:** 记录的数值范围从每分钟61次至100次。
- **呼吸频率:** 记录的数值范围从每分钟12次至16次。

4. **时间顺序:**
- 中耳炎诊断发生在2024年6月10日。在此之前记录的观察和遭遇可能与其他疾病或常规检查有关。此日期之后的观察和遭遇可能与中耳炎的随访护理或其他健康评估有关。

5. **结论:**
- 迈尔斯·迪金森的遭遇和观察顺序包括预防性和随访性检查,以及各种健康观察。具体的中耳炎相关序列在确切的观察或遭遇日期上并未详细记录。但诊断日期提供了理解后续医疗活动的时间标记。

如果有关每项观察和遭遇的更详细的时间数据可用,可以建立更精确的时间序列。然而,基于当前的信息,这是迈尔斯·迪金森中耳炎相关情况的概述。
历史多病例研究

问题:有多少人被诊断为急性支气管炎,以及它们通常是如何发作的?

答:

根据提供的医疗记录,有两个被诊断为急性支气管炎的患者:Maximo Swaniawski 和 Bennie Herman。

### 发病状况:
- **Maximo Swaniawski**:
- 急性支气管炎发作的日期:
- 2014年10月24日
- 2015年11月7日
- 2018年11月29日
- **Bennie Herman**:
- 急性支气管炎发作的日期:
- 2014年10月24日
- 2015年11月7日
- 2018年11月29日

### 典型的发病模式:
两人的发病日期相同,表明急性支气管炎的发作通常发生在深秋或十一月。这可能表明存在某种季节性规律,可能与寒冷天气或其它季节性因素有关,这些因素可能会影响呼吸道健康。

两人的病情都已经恢复,这表明他们的急性支气管炎发作都是急性而非慢性病程。

哪些患者同时患有病毒性鼻窦炎和支气管炎,他们的最早发病时间是什么时候?

回答:

为了确定哪些患者同时患有病毒性鼻窦炎和急性支气管炎,我们需要分析每个患者的病症及其发病日期。

1. **Maximo Swaniawski**:
- 病症:急性支气管炎
- 支气管炎最早的发病日期:2014-10-24
2. **Cassandra Monahan**:
- 病症:病毒性鼻窦炎
- 鼻窦炎最早的发病日期:2014-12-12
3. **Bennie Herman**:
- 病症:急性支气管炎
- 支气管炎最早的发病日期:2014-10-24
4. **Deangelo Price**:
- 病症:病毒性鼻窦炎
- 鼻窦炎最早的发病日期:2014-12-12
5. **Joseph Crona**:
- 病症:病毒性鼻窦炎
- 鼻窦炎最早的发病日期:2014-12-12

从提供的信息来看,没有患者同时患有病毒性鼻窦炎和急性支气管炎。每个患者要么只患有一种病症,要么另一种,但没有同时患有两种病症的。因此,没有同时患有这两种疾病的患者,也没有同时记录这两种疾病的发病日期。
相比仅用向量的RAG系统如下

针对多位患者的高级分析:

  • 在关于哪些患者同时患有支气管炎和病毒性鼻窦炎的问题中,我们必须能够知道某个患者是否被记录为患有或未患某种疾病。由于仅通过向量搜索是关于识别相关数据片段的,它无法确定某个患者是否确实没有某种疾病。这意味着需要一个中间的数据聚合,能够明确地说患者X的记录中没有“糖尿病”这个节点。

多文档理解和RAG:

  • 在关于迈尔斯及其在过去一年中的多次访问的问题中,我们可以看到,这些条件跨越了多次访问和多个转录。这意味着需要一个中间的数据聚合过程,以便将患者及其随时间累积的访问和观察结果进行整合。

WhyHow.AI 提供了用于结构化知识、知识图谱以及更可靠的代理增强检索(Agentic RAG)解决方案的工具、服务和流程。如果您对我们的任何工具(如 KG Studio 或开源知识表)或服务感兴趣,欢迎随时与我们聊天。点击这里与我们聊天。KG Studio 的描述可以改为“原生知识图谱的KG Studio平台测试版”。

如果你正在考虑、或已经将知识图谱融入到RAG中以提高准确性、记忆性和确定性,请关注我们的电子邮件通讯WhyHow.AI网站,或加入我们的Discord聊天室讨论,一起讨论规则、确定性和RAG中的知识图。



这篇关于案例研究:将医生转录本转化为时间性医疗记录知识图谱的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程