ベイジアンネットワークを使用して病院の患者数を予測する

ベイジアンネットワークを使用して病院の患者数を予測する

翻訳者|朱 仙中

レビュー | Chonglou

複雑さを乗り越える: 医療における患者数の予測

医療において、入院患者数を正確に予測することは、手術の成功に不可欠であるだけでなく、非常に難しい問題でもあります。理由は簡単です。患者の重症度や特別な要望、管理上のニーズ、診察室の制限、スタッフの病欠、激しい吹雪など、考慮すべき依存関係が非常に多いからです。さらに悪いことに、予期しない状況はスケジュールやリソースの割り当てに連鎖的な影響を及ぼし、最高品質のExcelプロジェクト予測でさえ矛盾する可能性があります

これらの課題は、非常に複雑で、しばらく考え続ける必要があるため、データの観点から見ると非常に興味深いものです。ただし、小さな改善で大きな成果につながる可能性があります (例: 患者の処理能力の向上、待ち時間の短縮、医療提供者の満足度の向上、コストの削減など)。

別の予測アプローチ: ベイズモデル

では、代替案は何でしょうか? Epic は、患者がいつ診察を受けたかの実際の記録を含む、多くのデータを提供します。 「表示」と「非表示」の既知の履歴が与えられれば、教師あり学習の空間で操作することができ、ベイジアンネットワーク (BN )将来の訪問確率を予測するための優れた確率的グラフィカルモデルを提供します。

人生におけるほとんどの決定は単一の入力で決定できますが (たとえば、「レインコートを持っていくべきか?」を考えてみましょう外は雨が降っていると仮定すると、決定は「はい」になるはずです)、ベイジアン ネットワークはより複雑な決定、つまり複数の入力 (たとえば、濡れている、歩くのに 3 分しかかからない、レインコートは別の階にある、友達は傘を持っているかもしれない、など) が関係する、さまざまな確率的結果と依存関係を持つ決定を簡単に処理できます。この記事では、症状、がんのステージ、治療目標という 3 つの要素の既知の確率に基づいて、患者が 2 か月以内に到着する確率スコアを出力できる、非常にシンプルなベイジアン ネットワークPythonで構築します

ベイジアンネットワークを理解する

ベイジアン ネットワークの本質は、有向非巡回グラフ (DAG) を使用して結合確率分布をグラフィカルに表現することです。 DAG 内のノードはランダム変数を表し、有向エッジはこれらの変数間の因果関係または条件付き依存関係を表します。すべてのデータ サイエンス プロジェクトと同様に、最初にかなりの時間を費やして関係者と協議し、意思決定に関係するワークフロー (変数など)正しくマッピングすることが、高品質の予測結果を得るために重要です

そこで、乳がん専門医のパートナーと会って患者の症状、がんのステージ、現在の治療目標という3 つの変数が患者が 2 か月以内に診察を受ける必要があるかどうかを判断する上で重要であることを説明するシナリオを考案します

(実際、将来の患者数に影響を与える要因は数十あり、そのうちのいくつかは単独または複数に依存し、他のいくつかは完全に独立しているが、それでも影響を与える)。

ここで、次のワークフローに同意したとします。段階は症状によって異なりますが、治療の種類は症状とは無関係であり、 2 か月以内の予約に影響します。

これに基づいて、データ ソース (ここでは Epic )からこれらの変数のデータを取得します。このデータには、スコア ノード ( Appointment_2months )の既知の値 ( 「Yes」または「No」のラベルが付けられている) が含まれます。このデータの照合は重要な部分です。2 か月前にこれらの変数が示していた内容に基づいて、2 か月以内に実際に患者に到達したケースを正確に把握する必要があります。

 # 安装包import pandas as pd # 用于数据处理import networkx as nx # 用于绘图import matplotlib.pyplot as plt # 用于绘图!pip install pybbn # 用于创建贝叶斯置信网络(BBN) from pybbn.graph.dag import Bbn from pybbn.graph.edge import Edge, EdgeType from pybbn.graph.jointree import EvidenceBuilder from pybbn.graph.node import BbnNode from pybbn.graph.variable import Variable from 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])

上記のコードでは、各変数(ノード)の対応するレベルの確率値を手動で入力してみましょうこれらの確率値は推測されたものではなく、最善の推測でもないことに注意してくださいただし、実際のアプリケーションでは既存のデータに基づいて対応する頻度を再度計算することになります

症状変数の例を見てみましょうレベル2 の頻度を取得します約 31% が非悪性で、69% が悪性です下の図を参照してください

次に、次の変数「ステージ」を考慮し、症状を使用してクロス集計計算を行い、これらの頻度を取得します。これを実行するのは Stage がSymptom に依存しそれぞれに2 つのシナリオがあるため実際には4 つの確率的結果があるためです

親子ペア間のすべてのクロス集計が定義されるまで、これを繰り返します。

現在、ほとんどのベイジアン ネットワークには多くの親子関係が含まれているため、確率の計算は面倒 (かつエラーが発生しやすい) になる可能性がありますが、次の関数を使用して、0、1、または 2 つの親に対応する任意の子ノードの確率行列を計算できます。医療に関する洞察は自動化できず、また自動化すべきでもありませんデータ準備作業の一部は自動化でき、また自動化べきです

 # 此函数有助于计算进入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

次に、実際のベイジアンネットワークノードとネットワーク自体を作成します。

 # 通过使用我们早期的函数自动计算概率来创建节点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)

これで準備はすべて整いました次に、ベイジアンネットワークを通じていくつかの仮説を実行し、出力を評価しましょう

ベイジアンネットワーク出力の評価

まず、特に条件を定めずに各ノードの確率を見てみましょう。

 # 定义打印边际概率的函数#每个节点的概率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_IV Values: 1=Stage_I_II|0.67124 1=Stage_III_IV|0.32876 ---------------- Node: 0|Symptom|Non-Malignant,Malignant Values: 0=Non-Malignant|0.69342 0=Malignant|0.30658 ---------------- Node: 2|TreatmentTypeCat|Adjuvant/Neoadjuvant,Treatment,Therapy Values: 2=Adjuvant/Neoadjuvant|0.58660 2=Treatment|0.17300 2=Therapy|0.24040 ---------------- Node: 3|Appointment_2weeks|No,Yes Values: 3=No|0.77655 3=Yes|0.22345 ----------------

上記の状況は、データセット内のすべての患者がStage_I_IIである確率が 67%非悪性である確率が 69% 、補助療法/術前療法が必要となる確率が 58% であり、そのうち 2 か月後に診察が必要なのは患者の 22% のみであることを示しています。

明らかに、ベイジアン ネットワークを使わずに、単純な頻度表からこれを簡単に取得できます

ここで、より条件付きの質問をしてみましょう。患者の Stage = Stage_I_II および TreatmentTypeCat = Therapy の場合、患者が 2 か月以内に治療を必要とする確率はどれくらいでしょうか。また、医療提供者は患者の症状について何も知らない(おそらくまだ患者を診察していない)ことも考慮してください。

ノードで正しいとわかっているものを実行します。

 # 添加已发生事件的证据,以便重新计算概率分布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()

上記のコードを実行すると、次のような結果が返されます。

 Node: 1|Stage|Stage_I_II,Stage_III_IV Values: 1=Stage_I_II|1.00000 1=Stage_III_IV|0.00000 ---------------- Node: 0|Symptom|Non-Malignant,Malignant Values: 0=Non-Malignant|0.57602 0=Malignant|0.42398 ---------------- Node: 2|TreatmentTypeCat|Adjuvant/Neoadjuvant,Treatment,Therapy Values: 2=Adjuvant/Neoadjuvant|0.00000 2=Treatment|0.00000 2=Therapy|1.00000 ---------------- Node: 3|Appointment_2months|No,Yes Values: 3=No|0.89072 3=Yes|0.10928 ----------------

上記の結果は、この患者が 2 か月以内に到着する確率がわずか11% であることを示しています。変数の既知または未知の特徴の任意の順列を求めることで、患者が 2 か月以内に到着する確率を予測できます。さらなるアルゴリズムと関数を利用して、多数の患者または患者グループの確率を収集したり、これらの確率を最適化したりすることもできます。

品質入力変数の重要性に関する注記

Python コードを書くことは重要ですが、将来の診察の信頼できる推定値を提供するベイジアン ネットワークが本当に成功するかどうかは、患者ケアのワークフローを正確にマッピングできるかどうかに大きく依存します。これらすべてには、コーディングだけでなく、時間、会話、ホワイトボードが必要ですこのような情報取得には、仮説をストレステストするために、複数のデータマイニングとクライアントとの再エンゲージメントが必要になる場合もあります。「看護師ナビゲーターは悪い症状を報告した後、必ず患者に電話をかけると前に言いましたが、実際に電話をかけたのは 10% のケースだけでした。患者との次の会話は、医療提供者との会話でした。」

症状が似ていて、状況が似ている患者は、同じようなサービスを必要とし、同じようなペースで来院することがよくあります。臨床から管理までの範囲にわたるこれらの入力の順列は、最終的にはサービス需要の決定論的な経路に対応します。ただし、予測が複雑になるほど、または予測期間が長くなるほど、高品質の入力を持つより具体的で複雑なベイジアンネットワークが必要になります

理由は次のとおりです。

  1. 正確な表現: ベイジアン ネットワークの構造は、変数間の実際の関係を反映する必要があります。変数の選択が不適切であったり、依存関係が誤解されていたりすると、予測や洞察が不正確になる可能性があります。
  2. 効果的な推論: 高品質の入力変数により、モデルの確率的推論を実行する能力が向上します。変数が条件依存関係に従って正確に接続されると、ネットワークはより信頼性の高い洞察を提供できます。
  3. 複雑さを軽減する: 無関係な変数や冗長な変数を含めると、モデルが不必要に複雑になり、計算要件が増加する可能性があります。高品質の入力により、ネットワークの効率が向上します。

翻訳者紹介

Zhu Xianzhong 氏は、51CTO のコミュニティ エディターであり、51CTO の専門ブロガー兼講師であり、濰坊の大学のコンピューター教師であり、フリーランス プログラミング コミュニティのベテランです。

原題:ベイジアンネットワークを用いた病院の付帯サービス量の予測、著者: Gabe Verzino

<<:  AI 異常検出は企業にどのようなメリットをもたらすのでしょうか?

>>:  NVIDIA が Tensor RT-LLM を発表、RTX 搭載 PC プラットフォームで大規模言語モデルを 4 倍高速化

ブログ    

推薦する

人工知能はあらゆる点で人間よりも優れているのに、なぜ人間の言っていることを理解できないのでしょうか?

9月8日、英国の新聞「ガーディアン」は、熱心な読者でも記者でもなく、サンフランシスコの人工知能スタ...

AIを活用して、ナスダックは金融業界向けのSaaSプロバイダーに変革したいと考えている

Nasdaq の CIO 兼 CTO である Brad Peterson 氏は、10 年以上にわたっ...

...

顔認識アクセス制御システムの登場により、私たちのプライバシーを誰が守るのでしょうか?

最近は「顔カード」、つまり「顔を売る」という言葉をよく耳にしますが、あなたの「顔」が身分証明書や電話...

ボストン・ダイナミクスのロボット犬はまもなく腕が生え、走って充電できるようになる

ボストン・ダイナミクスの創業者マーク・レイバート氏は、スポットロボット犬は将来「家庭で使用できるよう...

...

すべては可能だ:コンピュータビジョンCVとNLPの分野はますます融合している

[[347900]] 2020年10月、ディープラーニング分野のトップカンファレンスであるICLR ...

...

Java プログラミング スキル - データ構造とアルゴリズム「単方向リンク リスト」

[[386512]]基本的な紹介リンクリストは順序付きリストですが、メモリ内に次のように保存されま...

2022年、どのような技術トレンドが世界を変え続けるのでしょうか?以下は百度研究所の予測です。

あっという間に2021年が過ぎ去りました。今年、新型コロナウイルス感染症のパンデミックは世界経済と社...

...

スマートビルディングテクノロジーを導入する前に考慮すべき7つのこと

スマートビルディングの設備やシステムを評価する際には、体系的なアプローチを取る必要があります。これら...

...

人工知能の未来を見据えて:2020年のAIの8つの主要トレンド

人工知能は、最も急速に成長し、最も予測不可能な産業の 1 つです。ディープラーニング、AI 駆動型機...