当前位置:首页 > 科技  > 软件

利用贝叶斯网络预测医院服务患者数量

来源: 责编: 时间:2023-10-18 09:18:43 187观看
导读译者 | 朱先忠审校 | 重楼驾驭复杂性:预测医疗保健中的患者数量在医疗保健领域,准确预测即将到来的患者数量不仅对手术成功至关重要,也是一个非常棘手的问题。原因很简单:需要考虑的依赖性因素太多了——患者的严重程度和

译者 | 朱先忠Li728资讯网——每日最新资讯28at.com

审校 | 重楼Li728资讯网——每日最新资讯28at.com

驾驭复杂性:预测医疗保健中的患者数量

Li728资讯网——每日最新资讯28at.com

在医疗保健领域,准确预测即将到来的患者数量不仅对手术成功至关重要,也是一个非常棘手的问题。原因很简单:需要考虑的依赖性因素太多了——患者的严重程度和特殊要求、管理需求、检查室限制、员工请病假、严重的暴风雪等等。更糟糕的是,意外情况可能会对日程安排和资源分配产生连锁影响,甚至可能与最高质量Excel项目预测结果产生矛盾。Li728资讯网——每日最新资讯28at.com

从数据的角度来看,这些挑战真的很有趣,因为它们极其复杂,足够你考虑一段时间。但是,即使是轻微的改进也可带来重大的胜利(例如,提高患者吞吐量、缩短等待时间、让医疗保健提供者更快乐、降低成本)。Li728资讯网——每日最新资讯28at.com

另一种预测方法:贝叶斯模型

那么,还有什么替代方案呢?Epic为我们提供了大量数据,包括患者何时赴约的实际记录。在已知历史“显示”和“未显示”的情况下,我们可以在监督学习的空间中操作,贝叶斯网络(BN:Bayesian Networks)提供了很好的概率图形模型来预测未来的访问概率。Li728资讯网——每日最新资讯28at.com

虽然生活中的大多数决定都可以通过一个输入来决定(例如,考虑“我应该带雨衣吗?”假设外面下雨,那么这个决定应该是“是”),但贝叶斯网络可以很容易地处理更复杂的决策——涉及多个输入的决策(例如,天气潮湿,步行仅3分钟,你的雨衣在另一层楼,你的朋友可能有伞,等等),具有不同的概率结果和依赖性。在这篇文章中,我将在Python语言环境构造一个超简单的贝叶斯网络,它可以根据症状、癌症分期和治疗目标这三个因素的已知概率,输出患者在2个月内到达的概率得分。Li728资讯网——每日最新资讯28at.com

理解贝叶斯网络

贝叶斯网络的核心是使用有向无环图(DAG)的联合概率分布的图形表示。DAG中的节点表示随机变量,有向边表示这些变量之间的因果关系或条件依赖关系。正如所有数据科学项目一样,在一开始就花大量时间与利益相关者协商,以正确映射决策中涉及的工作流程(例如变量),这对于高质量的预测结果是至关重要Li728资讯网——每日最新资讯28at.com

因此,我将发明一个场景,让我们与乳腺肿瘤合作伙伴会面,他们解释三个变量——患者症状、癌症分期和当前治疗目标对于确定患者是否需要在2个月内预约至关重要。Li728资讯网——每日最新资讯28at.com

(事实上,影响未来患者数量的因素不下几十个,其中一些是单一或多重依赖性的,另一些是完全独立但仍有影响的)。Li728资讯网——每日最新资讯28at.com

Li728资讯网——每日最新资讯28at.com

现在,假设我们同意如下工作流程:阶段取决于他们的症状,但治疗类型与症状无关,也影响2个月内的预约。Li728资讯网——每日最新资讯28at.com

基于此,我们将从我们的数据源(对我们来说Epic)中获取这些变量的数据,该数据源将再次包含我们的分数节点(Appointment_2months)的已知值,标记为“是”或“否”。这种数据整理是一个重要部分;你需要根据这些变量在2个月前表明的情况,正确地捕捉2个月内真正到达患者的病例。Li728资讯网——每日最新资讯28at.com

# 安装包import pandas as pd # 用于数据处理 import networkx as nx # 用于绘图import matplotlib.pyplot as plt # 用于绘图!pip install pybbn# 用于创建贝叶斯置信网络(BBN)from pybbn.graph.dag import Bbnfrom pybbn.graph.edge import Edge, EdgeTypefrom pybbn.graph.jointree import EvidenceBuilderfrom pybbn.graph.node import BbnNodefrom pybbn.graph.variable import Variablefrom pybbn.pptc.inferencecontroller import InferenceController# 通过手动键入概率创建节点Symptom = BbnNode(Variable(0, 'Symptom', ['Non-Malignant', 'Malignant']), [0.30658, 0.69342])Stage = BbnNode(Variable(1, 'Stage', ['Stage_III_IV', 'Stage_I_II']), [0.92827, 0.07173,  0.55760, 0.44240])TreatmentTypeCat = BbnNode(Variable(2, 'TreatmentTypeCat', ['Adjuvant/Neoadjuvant', 'Treatment', 'Therapy']), [0.58660, 0.24040, 0.17300])Appointment_2weeks = BbnNode(Variable(3, 'Appointment_2weeks', ['No', 'Yes']), [0.92314, 0.07686,  0.89072, 0.10928,  0.76008, 0.23992,  0.64250, 0.35750,  0.49168, 0.50832,  0.32182, 0.67818])

上面代码中,让我们手动输入每个变量(节点)中对应级别的一些概率注意,这些概率没有被猜测,甚至是最好的猜测结果不过,在实践应用中,您将再次根据现有数据计算对应的频率。Li728资讯网——每日最新资讯28at.com

让我们以症状(symptom)变量为例。我会得到它们2级频率大约31%是非恶性的,69%是恶性的请参考下图Li728资讯网——每日最新资讯28at.com

Li728资讯网——每日最新资讯28at.com

然后,我们考虑下一个变量Stage,并使用Symptom进行交叉表计算,以获得这些频率。我们这样做是因为阶段Stage取决于症状Symptom,因为们每个变量对应两个场景,所以们实际上存在4个概率结果。Li728资讯网——每日最新资讯28at.com

Li728资讯网——每日最新资讯28at.com

依此类推,直到定义了父子对之间的所有交叉表。Li728资讯网——每日最新资讯28at.com

现在,大多数贝叶斯网络包括许多父子关系,因此计算概率可能会变得乏味(而且非常容易出错),下面的函数可以用来计算与0、1或2个父节点对应的任何子节点的概率矩阵。虽然医学洞见不能也不应该自动化处理,但数据准备部分的工作完全可以也应该通过自动化的方式来实现Li728资讯网——每日最新资讯28at.com

# 此函数有助于计算进入BBN的概率分布(注意,最多可以处理2个父节点)def probs(data, child, parent1=None, parent2=None): if parent1==None: # 计算概率 prob=pd.crosstab(data[child], 'Empty', margins=False, normalize='columns').sort_index().to_numpy().reshape(-1).tolist() elif parent1!=None: # 检查子节点是否有1个父节点或2个父节点 if parent2==None: # 计算概率 prob=pd.crosstab(data[parent1],data[child], margins=False, normalize='index').sort_index().to_numpy().reshape(-1).tolist() else:  # 计算概率 prob=pd.crosstab([data[parent1],data[parent2]],data[child], margins=False, normalize='index').sort_index().to_numpy().reshape(-1).tolist() else: print("Error in Probability Frequency Calculations") return prob 

接下来,我们创建实际的贝叶斯网络节点和网络本身:Li728资讯网——每日最新资讯28at.com

# 通过使用我们早期的函数自动计算概率来创建节点Symptom = BbnNode(Variable(0, 'Symptom', ['Non-Malignant', 'Malignant']), probs(df, child='SymptomCat'))Stage = BbnNode(Variable(1, 'Stage', ['Stage_I_II', 'Stage_III_IV']), probs(df, child='StagingCat', parent1='SymptomCat'))TreatmentTypeCat = BbnNode(Variable(2, 'TreatmentTypeCat', ['Adjuvant/Neoadjuvant', 'Treatment', 'Therapy']), probs(df, child='TreatmentTypeCat'))Appointment_2months = BbnNode(Variable(3, 'Appointment_2months', ['No', 'Yes']), probs(df, child='Appointment_2months', parent1='StagingCat', parent2='TreatmentTypeCat'))# 创建贝叶斯网络bbn = Bbn() / .add_node(Symptom) / .add_node(Stage) / .add_node(TreatmentTypeCat) / .add_node(Appointment_2months) / .add_edge(Edge(Symptom, Stage, EdgeType.DIRECTED)) / .add_edge(Edge(Stage, Appointment_2months, EdgeType.DIRECTED)) / .add_edge(Edge(TreatmentTypeCat, Appointment_2months, EdgeType.DIRECTED))# 将BBN转换为连接树join_tree = InferenceController.apply(bbn)

现在,我们准备好了一切接下来,让我们通过贝叶斯网络运行一些假设,并给出评估输出。Li728资讯网——每日最新资讯28at.com

评估贝叶斯网络输出

首先,让我们看看每个节点的概率,而不需要具体声明任何条件。Li728资讯网——每日最新资讯28at.com

# 定义打印边际概率的函数#每个节点的概率def print_probs(): for node in join_tree.get_bbn_nodes(): potential = join_tree.get_bbn_potential(node) print("Node:", node) print("Values:") print(potential) print('----------------')# 使用以上函数打印边际概率print_probs()输出结果如下:Node: 1|Stage|Stage_I_II,Stage_III_IVValues:1=Stage_I_II|0.671241=Stage_III_IV|0.32876----------------Node: 0|Symptom|Non-Malignant,MalignantValues:0=Non-Malignant|0.693420=Malignant|0.30658----------------Node: 2|TreatmentTypeCat|Adjuvant/Neoadjuvant,Treatment,TherapyValues:2=Adjuvant/Neoadjuvant|0.586602=Treatment|0.173002=Therapy|0.24040----------------Node: 3|Appointment_2weeks|No,YesValues:3=No|0.776553=Yes|0.22345----------------

上述情况表明,该数据集中的所有患者都有67%的概率为Stage_I_II,69%的概率为非恶性(Non-Malignant),58%的概率需要辅助/新辅助(Adjuvant/Neoadjuvant)治疗,其中只有22%的患者需要在2个月后预约。Li728资讯网——每日最新资讯28at.com

显然,我们可以很容易地从没有贝叶斯网络的简单频率表中得到这一点。Li728资讯网——每日最新资讯28at.com

但现在,让我们问一个更有条件的问题:考虑到患者患有阶段=Stage_I_II和TreatmentTypeCat=Therapy,患者在2个月内需要护理的可能性有多大。此外,考虑到医疗保健提供者对他们的症状一无所知(也许他们还没有见过病人)。Li728资讯网——每日最新资讯28at.com

我们将在节点中运行我们所知道的正确内容:Li728资讯网——每日最新资讯28at.com

# 添加已发生事件的证据,以便重新计算概率分布def evidence(ev, nod, cat, val): ev = EvidenceBuilder() / .with_node(join_tree.get_bbn_node_by_name(nod)) / .with_evidence(cat, val) / .build() join_tree.set_observation(ev)# 添加更多证据evidence('ev1', 'Stage', 'Stage_I_II', 1.0)evidence('ev2', 'TreatmentTypeCat', 'Therapy', 1.0)# 打印边际概率print_probs()

上述代码的执行将返回如下内容:Li728资讯网——每日最新资讯28at.com

Node: 1|Stage|Stage_I_II,Stage_III_IVValues:1=Stage_I_II|1.000001=Stage_III_IV|0.00000----------------Node: 0|Symptom|Non-Malignant,MalignantValues:0=Non-Malignant|0.576020=Malignant|0.42398----------------Node: 2|TreatmentTypeCat|Adjuvant/Neoadjuvant,Treatment,TherapyValues:2=Adjuvant/Neoadjuvant|0.000002=Treatment|0.000002=Therapy|1.00000----------------Node: 3|Appointment_2months|No,YesValues:3=No|0.890723=Yes|0.10928----------------

上面结果显示,这个病人在两个月内到达的几率只有11%。我们可以询问我们变量的已知或未知特征的任何排列,以预测患者在2个月内到达的概率。可以利用进一步的算法和函数来收集许多患者或患者组的概率,或优化这些概率。Li728资讯网——每日最新资讯28at.com

关于质量输入变量重要性的说明

Python代码编写是一回事,但贝叶斯网络在提供可靠的未来就诊估计方面的真正成功在很大程度上取决于患者护理工作流程的准确映射。所有需要时间、谈话和白板——而不是仅仅的编码工作这样的信息取得甚至可能需要几次数据挖掘,并与客户重新接触,以进行压力测试假设:“我们之前说过,护士导航仪总是在报告症状不佳后给患者打电话,但这种情况只发生了10%。下一次与患者交谈是与他们的医疗服务提供者进行的。”。Li728资讯网——每日最新资讯28at.com

在类似的情况下,表现相似的患者通常需要类似的服务,并以类似的节奏进入。这些输入的排列,其特征可以从临床到管理,最终对应于服务需求的某种确定性路径。但是,时间预测越复杂或越远,就越需要更具体、更复杂的具有高质量输入的贝叶斯网络Li728资讯网——每日最新资讯28at.com

原因如下:Li728资讯网——每日最新资讯28at.com

  1. 精确表示:贝叶斯网络的结构必须反映变量之间的实际关系。选择不当的变量或误解的依赖关系可能导致不准确的预测和见解。
  2. 有效推理:高质量的输入变量增强了模型执行概率推理的能力。当变量根据其条件依赖性准确连接时,网络可以提供更可靠的见解。
  3. 降低复杂性:包含不相关或冗余的变量会使模型不必要地复杂化,并增加计算需求。高质量的投入使网络更加高效。

译者介绍

朱先忠,51CTO社区编辑,51CTO专家博客、讲师,潍坊一所高校计算机教师,自由编程界老兵一枚。Li728资讯网——每日最新资讯28at.com

原文标题:Using Bayesian Networks to forecast ancillary service volume in hospitals,作者:Gabe VerzinoLi728资讯网——每日最新资讯28at.com


Li728资讯网——每日最新资讯28at.com


Li728资讯网——每日最新资讯28at.com


Li728资讯网——每日最新资讯28at.com


Li728资讯网——每日最新资讯28at.com


Li728资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-13844-0.html利用贝叶斯网络预测医院服务患者数量

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Kubernetes 中的 Java 应用的内存调优

下一篇: Python字符串处理:掌握文本的艺术

标签:
  • 热门焦点
Top