Upload demo.ipynb
Browse files- notebooks/demo.ipynb +1074 -0
notebooks/demo.ipynb
ADDED
|
@@ -0,0 +1,1074 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"id": "intro-markdown",
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"source": [
|
| 8 |
+
"# RAG Pipeline Demo: Surgery Oral Board Simulation\n",
|
| 9 |
+
"\n",
|
| 10 |
+
"This notebook demonstrates the usage of the RAG (Retrieval-Augmented Generation) pipeline developed for simulating surgery oral board scenarios. It utilizes the custom Python modules located in the `src/` directory.\n",
|
| 11 |
+
"\n",
|
| 12 |
+
"**Pipeline Components:**\n",
|
| 13 |
+
"* `data_processing`: Loads and preprocesses raw case data from `.docx` files.\n",
|
| 14 |
+
"* `ClinicalCaseProcessor`: Creates embeddings for clinical cases.\n",
|
| 15 |
+
"* `ClinicalCaseRetriever`: Retrieves relevant cases based on semantic similarity to a query.\n",
|
| 16 |
+
"* `AnswerEvaluator`: Uses an LLM to evaluate user responses against expected answers.\n",
|
| 17 |
+
"* `OralExamSimulator`: Orchestrates the simulation flow."
|
| 18 |
+
]
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"cell_type": "markdown",
|
| 22 |
+
"id": "setup-markdown",
|
| 23 |
+
"metadata": {},
|
| 24 |
+
"source": [
|
| 25 |
+
"## 1. Setup\n",
|
| 26 |
+
"\n",
|
| 27 |
+
"Import necessary libraries and custom modules. Define constants and handle Hugging Face Hub authentication."
|
| 28 |
+
]
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
"cell_type": "code",
|
| 32 |
+
"execution_count": 1,
|
| 33 |
+
"id": "setup-code",
|
| 34 |
+
"metadata": {},
|
| 35 |
+
"outputs": [
|
| 36 |
+
{
|
| 37 |
+
"name": "stderr",
|
| 38 |
+
"output_type": "stream",
|
| 39 |
+
"text": [
|
| 40 |
+
"2025-04-22 12:59:49.329544: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:467] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
|
| 41 |
+
"WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
|
| 42 |
+
"E0000 00:00:1745341189.621398 614864 cuda_dnn.cc:8579] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
|
| 43 |
+
"E0000 00:00:1745341189.717816 614864 cuda_blas.cc:1407] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
|
| 44 |
+
"W0000 00:00:1745341190.668036 614864 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n",
|
| 45 |
+
"W0000 00:00:1745341190.668086 614864 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n",
|
| 46 |
+
"W0000 00:00:1745341190.668088 614864 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n",
|
| 47 |
+
"W0000 00:00:1745341190.668090 614864 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n",
|
| 48 |
+
"2025-04-22 12:59:50.675395: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
|
| 49 |
+
"To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
|
| 50 |
+
]
|
| 51 |
+
}
|
| 52 |
+
],
|
| 53 |
+
"source": [
|
| 54 |
+
"import os\n",
|
| 55 |
+
"import json\n",
|
| 56 |
+
"import sys \n",
|
| 57 |
+
"import re\n",
|
| 58 |
+
"import pandas as pd\n",
|
| 59 |
+
"import numpy as np\n",
|
| 60 |
+
"import torch\n",
|
| 61 |
+
"from dotenv import load_dotenv\n",
|
| 62 |
+
"from huggingface_hub import login\n",
|
| 63 |
+
"from sklearn.metrics import ndcg_score\n",
|
| 64 |
+
"from transformers import AutoTokenizer, AutoModelForCausalLM\n",
|
| 65 |
+
"from IPython.display import display, Markdown\n",
|
| 66 |
+
"\n",
|
| 67 |
+
"# --- Add project root to sys.path ---\n",
|
| 68 |
+
"project_root = os.path.abspath(os.path.join(os.getcwd(), os.pardir))\n",
|
| 69 |
+
"if project_root not in sys.path:\n",
|
| 70 |
+
" sys.path.append(project_root)\n",
|
| 71 |
+
"\n",
|
| 72 |
+
"# --- Custom Module Imports ---\n",
|
| 73 |
+
"from src.data_processing import process_all_cases, ClinicalCaseProcessor\n",
|
| 74 |
+
"from src.retriever import ClinicalCaseRetriever, DummyRetriever\n",
|
| 75 |
+
"from src.evaluator import AnswerEvaluator\n",
|
| 76 |
+
"from src.simulator import OralExamSimulator\n",
|
| 77 |
+
"from src.evaluation_utils import retrieval_metrics\n",
|
| 78 |
+
"from src.synthetic_generator import generate_synthetic_case, process_synthetic_data\n",
|
| 79 |
+
"\n",
|
| 80 |
+
"# --- Configuration ---\n",
|
| 81 |
+
"DATA_FOLDER = \"../data/\"\n",
|
| 82 |
+
"PROCESSED_DATA_PATH = \"../processed_clinical_cases\"\n",
|
| 83 |
+
"EVALUATOR_MODEL_ID = \"meta-llama/Llama-3.2-3B-Instruct\"\n",
|
| 84 |
+
"EMBEDDING_MODEL_ID = \"all-MiniLM-L6-v2\"\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"# Hugging Face Hub Authentication (using .env file in project root)\n",
|
| 87 |
+
"dotenv_path = os.path.join(project_root, 'hf_login.env')\n",
|
| 88 |
+
"load_dotenv(dotenv_path=dotenv_path)\n",
|
| 89 |
+
"hf_key = os.getenv(\"HF_KEY\")\n",
|
| 90 |
+
"\n",
|
| 91 |
+
"# --- Set Cache Directory (Optional) ---\n",
|
| 92 |
+
"cache_dir = \"/scratch/krb3ym/models/cache\" # Keep your specific path\n",
|
| 93 |
+
"os.environ['HF_HOME'] = cache_dir\n",
|
| 94 |
+
"os.makedirs(cache_dir, exist_ok=True)"
|
| 95 |
+
]
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
"cell_type": "markdown",
|
| 99 |
+
"id": "load-data-markdown",
|
| 100 |
+
"metadata": {},
|
| 101 |
+
"source": [
|
| 102 |
+
"## 2. Load and Preprocess Raw Data\n",
|
| 103 |
+
"\n",
|
| 104 |
+
"Load the clinical cases from the `.docx` files into a pandas DataFrame using the utility function from `src.data_processing`."
|
| 105 |
+
]
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"cell_type": "code",
|
| 109 |
+
"execution_count": 2,
|
| 110 |
+
"id": "load-data-code",
|
| 111 |
+
"metadata": {},
|
| 112 |
+
"outputs": [
|
| 113 |
+
{
|
| 114 |
+
"name": "stdout",
|
| 115 |
+
"output_type": "stream",
|
| 116 |
+
"text": [
|
| 117 |
+
"Processing case files from: ../data/\n",
|
| 118 |
+
"Warning: Could not parse filename format: BTK_-_45A__Breast_Cancer.docx\n",
|
| 119 |
+
"Loaded 99 cases. Displaying head:\n"
|
| 120 |
+
]
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"data": {
|
| 124 |
+
"text/html": [
|
| 125 |
+
"<div>\n",
|
| 126 |
+
"<style scoped>\n",
|
| 127 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
| 128 |
+
" vertical-align: middle;\n",
|
| 129 |
+
" }\n",
|
| 130 |
+
"\n",
|
| 131 |
+
" .dataframe tbody tr th {\n",
|
| 132 |
+
" vertical-align: top;\n",
|
| 133 |
+
" }\n",
|
| 134 |
+
"\n",
|
| 135 |
+
" .dataframe thead th {\n",
|
| 136 |
+
" text-align: right;\n",
|
| 137 |
+
" }\n",
|
| 138 |
+
"</style>\n",
|
| 139 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
| 140 |
+
" <thead>\n",
|
| 141 |
+
" <tr style=\"text-align: right;\">\n",
|
| 142 |
+
" <th></th>\n",
|
| 143 |
+
" <th>case_id</th>\n",
|
| 144 |
+
" <th>clinical_presentation</th>\n",
|
| 145 |
+
" <th>turn_id</th>\n",
|
| 146 |
+
" <th>question</th>\n",
|
| 147 |
+
" <th>answer</th>\n",
|
| 148 |
+
" </tr>\n",
|
| 149 |
+
" </thead>\n",
|
| 150 |
+
" <tbody>\n",
|
| 151 |
+
" <tr>\n",
|
| 152 |
+
" <th>0</th>\n",
|
| 153 |
+
" <td>85A</td>\n",
|
| 154 |
+
" <td>Appendicitis Pediatrics</td>\n",
|
| 155 |
+
" <td>1</td>\n",
|
| 156 |
+
" <td>You were called to the emergency department to...</td>\n",
|
| 157 |
+
" <td>Okay, well, I would begin by evaluating the pa...</td>\n",
|
| 158 |
+
" </tr>\n",
|
| 159 |
+
" <tr>\n",
|
| 160 |
+
" <th>1</th>\n",
|
| 161 |
+
" <td>85A</td>\n",
|
| 162 |
+
" <td>Appendicitis Pediatrics</td>\n",
|
| 163 |
+
" <td>2</td>\n",
|
| 164 |
+
" <td>The patient is febrile at 101.2 degrees, heart...</td>\n",
|
| 165 |
+
" <td>Okay, does he have a positive psoas or a Rovsi...</td>\n",
|
| 166 |
+
" </tr>\n",
|
| 167 |
+
" <tr>\n",
|
| 168 |
+
" <th>2</th>\n",
|
| 169 |
+
" <td>85A</td>\n",
|
| 170 |
+
" <td>Appendicitis Pediatrics</td>\n",
|
| 171 |
+
" <td>3</td>\n",
|
| 172 |
+
" <td>Yes, both are positive.</td>\n",
|
| 173 |
+
" <td>I'm concerned about acute appendicitis, but th...</td>\n",
|
| 174 |
+
" </tr>\n",
|
| 175 |
+
" <tr>\n",
|
| 176 |
+
" <th>3</th>\n",
|
| 177 |
+
" <td>85A</td>\n",
|
| 178 |
+
" <td>Appendicitis Pediatrics</td>\n",
|
| 179 |
+
" <td>4</td>\n",
|
| 180 |
+
" <td>Labs are in order. White blood cell count of 1...</td>\n",
|
| 181 |
+
" <td>Well, this is diagnostic of acute appendicitis...</td>\n",
|
| 182 |
+
" </tr>\n",
|
| 183 |
+
" <tr>\n",
|
| 184 |
+
" <th>4</th>\n",
|
| 185 |
+
" <td>85A</td>\n",
|
| 186 |
+
" <td>Appendicitis Pediatrics</td>\n",
|
| 187 |
+
" <td>5</td>\n",
|
| 188 |
+
" <td>Are there any other therapeutic options for th...</td>\n",
|
| 189 |
+
" <td>Yes, the patient has early acute appendicitis ...</td>\n",
|
| 190 |
+
" </tr>\n",
|
| 191 |
+
" </tbody>\n",
|
| 192 |
+
"</table>\n",
|
| 193 |
+
"</div>"
|
| 194 |
+
],
|
| 195 |
+
"text/plain": [
|
| 196 |
+
" case_id clinical_presentation turn_id \\\n",
|
| 197 |
+
"0 85A Appendicitis Pediatrics 1 \n",
|
| 198 |
+
"1 85A Appendicitis Pediatrics 2 \n",
|
| 199 |
+
"2 85A Appendicitis Pediatrics 3 \n",
|
| 200 |
+
"3 85A Appendicitis Pediatrics 4 \n",
|
| 201 |
+
"4 85A Appendicitis Pediatrics 5 \n",
|
| 202 |
+
"\n",
|
| 203 |
+
" question \\\n",
|
| 204 |
+
"0 You were called to the emergency department to... \n",
|
| 205 |
+
"1 The patient is febrile at 101.2 degrees, heart... \n",
|
| 206 |
+
"2 Yes, both are positive. \n",
|
| 207 |
+
"3 Labs are in order. White blood cell count of 1... \n",
|
| 208 |
+
"4 Are there any other therapeutic options for th... \n",
|
| 209 |
+
"\n",
|
| 210 |
+
" answer \n",
|
| 211 |
+
"0 Okay, well, I would begin by evaluating the pa... \n",
|
| 212 |
+
"1 Okay, does he have a positive psoas or a Rovsi... \n",
|
| 213 |
+
"2 I'm concerned about acute appendicitis, but th... \n",
|
| 214 |
+
"3 Well, this is diagnostic of acute appendicitis... \n",
|
| 215 |
+
"4 Yes, the patient has early acute appendicitis ... "
|
| 216 |
+
]
|
| 217 |
+
},
|
| 218 |
+
"metadata": {},
|
| 219 |
+
"output_type": "display_data"
|
| 220 |
+
}
|
| 221 |
+
],
|
| 222 |
+
"source": [
|
| 223 |
+
"dataframe_btk = process_all_cases(DATA_FOLDER)\n",
|
| 224 |
+
"print(f\"Loaded {dataframe_btk['case_id'].nunique()} cases. Displaying head:\")\n",
|
| 225 |
+
"display(dataframe_btk.head())"
|
| 226 |
+
]
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"cell_type": "markdown",
|
| 230 |
+
"id": "prepare-rag-markdown",
|
| 231 |
+
"metadata": {},
|
| 232 |
+
"source": [
|
| 233 |
+
"## 3. Prepare RAG Dataset with Embeddings\n",
|
| 234 |
+
"\n",
|
| 235 |
+
"Use the `ClinicalCaseProcessor` to process the DataFrame, generate embeddings for each case summary, and save the result as a Hugging Face Dataset."
|
| 236 |
+
]
|
| 237 |
+
},
|
| 238 |
+
{
|
| 239 |
+
"cell_type": "code",
|
| 240 |
+
"execution_count": 3,
|
| 241 |
+
"id": "prepare-rag-code",
|
| 242 |
+
"metadata": {},
|
| 243 |
+
"outputs": [
|
| 244 |
+
{
|
| 245 |
+
"name": "stdout",
|
| 246 |
+
"output_type": "stream",
|
| 247 |
+
"text": [
|
| 248 |
+
"Initializing ClinicalCaseProcessor with model: all-MiniLM-L6-v2\n",
|
| 249 |
+
"Using device: cuda\n",
|
| 250 |
+
"Using provided DataFrame.\n",
|
| 251 |
+
"Raw data shape: (973, 5)\n",
|
| 252 |
+
"Grouping data by case...\n"
|
| 253 |
+
]
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"name": "stderr",
|
| 257 |
+
"output_type": "stream",
|
| 258 |
+
"text": [
|
| 259 |
+
"Processing Cases: 100%|██████████| 99/99 [00:00<00:00, 6184.54it/s]\n"
|
| 260 |
+
]
|
| 261 |
+
},
|
| 262 |
+
{
|
| 263 |
+
"name": "stdout",
|
| 264 |
+
"output_type": "stream",
|
| 265 |
+
"text": [
|
| 266 |
+
"Processed data into 99 unique cases.\n",
|
| 267 |
+
"Generating embeddings for 99 case summaries...\n"
|
| 268 |
+
]
|
| 269 |
+
},
|
| 270 |
+
{
|
| 271 |
+
"name": "stderr",
|
| 272 |
+
"output_type": "stream",
|
| 273 |
+
"text": [
|
| 274 |
+
"Embedding Batches: 100%|██████████| 7/7 [00:00<00:00, 11.19it/s]\n"
|
| 275 |
+
]
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"name": "stdout",
|
| 279 |
+
"output_type": "stream",
|
| 280 |
+
"text": [
|
| 281 |
+
"Generated embeddings with shape: (99, 384)\n"
|
| 282 |
+
]
|
| 283 |
+
},
|
| 284 |
+
{
|
| 285 |
+
"data": {
|
| 286 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 287 |
+
"model_id": "ef6d95d464ea4babb9adeb1ff9b16582",
|
| 288 |
+
"version_major": 2,
|
| 289 |
+
"version_minor": 0
|
| 290 |
+
},
|
| 291 |
+
"text/plain": [
|
| 292 |
+
"Saving the dataset (0/1 shards): 0%| | 0/99 [00:00<?, ? examples/s]"
|
| 293 |
+
]
|
| 294 |
+
},
|
| 295 |
+
"metadata": {},
|
| 296 |
+
"output_type": "display_data"
|
| 297 |
+
},
|
| 298 |
+
{
|
| 299 |
+
"name": "stdout",
|
| 300 |
+
"output_type": "stream",
|
| 301 |
+
"text": [
|
| 302 |
+
"Processed dataset saved successfully to ../processed_clinical_cases\n",
|
| 303 |
+
"Dataset({\n",
|
| 304 |
+
" features: ['case_id', 'clinical_presentation', 'questions', 'answers', 'case_summary', 'embeddings'],\n",
|
| 305 |
+
" num_rows: 99\n",
|
| 306 |
+
"})\n"
|
| 307 |
+
]
|
| 308 |
+
}
|
| 309 |
+
],
|
| 310 |
+
"source": [
|
| 311 |
+
"processor = ClinicalCaseProcessor(model_name=EMBEDDING_MODEL_ID)\n",
|
| 312 |
+
"processed_dataset = processor.preprocess_data(dataframe_btk, output_path=PROCESSED_DATA_PATH)\n",
|
| 313 |
+
"print(processed_dataset)"
|
| 314 |
+
]
|
| 315 |
+
},
|
| 316 |
+
{
|
| 317 |
+
"cell_type": "markdown",
|
| 318 |
+
"id": "init-pipeline-markdown",
|
| 319 |
+
"metadata": {},
|
| 320 |
+
"source": [
|
| 321 |
+
"## 4. Initialize RAG Pipeline Components\n",
|
| 322 |
+
"\n",
|
| 323 |
+
"Instantiate the retriever, evaluator, and simulator classes."
|
| 324 |
+
]
|
| 325 |
+
},
|
| 326 |
+
{
|
| 327 |
+
"cell_type": "code",
|
| 328 |
+
"execution_count": 4,
|
| 329 |
+
"id": "init-pipeline-code",
|
| 330 |
+
"metadata": {},
|
| 331 |
+
"outputs": [
|
| 332 |
+
{
|
| 333 |
+
"name": "stdout",
|
| 334 |
+
"output_type": "stream",
|
| 335 |
+
"text": [
|
| 336 |
+
"Initializing ClinicalCaseRetriever with model: all-MiniLM-L6-v2\n",
|
| 337 |
+
"Dataset loaded successfully from disk: ../processed_clinical_cases\n",
|
| 338 |
+
"Dataset features: {'case_id': Value(dtype='string', id=None), 'clinical_presentation': Value(dtype='string', id=None), 'questions': Sequence(feature=Value(dtype='string', id=None), length=-1, id=None), 'answers': Sequence(feature=Value(dtype='string', id=None), length=-1, id=None), 'case_summary': Value(dtype='string', id=None), 'embeddings': Sequence(feature=Value(dtype='float64', id=None), length=-1, id=None)}\n",
|
| 339 |
+
"Number of cases in dataset: 99\n",
|
| 340 |
+
"Using device: cuda\n",
|
| 341 |
+
"Loaded 99 cases with embeddings of shape (99, 384)\n",
|
| 342 |
+
"Initializing AnswerEvaluator with model: meta-llama/Llama-3.2-3B-Instruct\n",
|
| 343 |
+
"Set pad_token to eos_token\n"
|
| 344 |
+
]
|
| 345 |
+
},
|
| 346 |
+
{
|
| 347 |
+
"data": {
|
| 348 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 349 |
+
"model_id": "02a5e6af243344489487ed8639da9db3",
|
| 350 |
+
"version_major": 2,
|
| 351 |
+
"version_minor": 0
|
| 352 |
+
},
|
| 353 |
+
"text/plain": [
|
| 354 |
+
"Loading checkpoint shards: 0%| | 0/2 [00:00<?, ?it/s]"
|
| 355 |
+
]
|
| 356 |
+
},
|
| 357 |
+
"metadata": {},
|
| 358 |
+
"output_type": "display_data"
|
| 359 |
+
},
|
| 360 |
+
{
|
| 361 |
+
"name": "stdout",
|
| 362 |
+
"output_type": "stream",
|
| 363 |
+
"text": [
|
| 364 |
+
"AnswerEvaluator model loaded successfully on device: cuda:0\n"
|
| 365 |
+
]
|
| 366 |
+
}
|
| 367 |
+
],
|
| 368 |
+
"source": [
|
| 369 |
+
"retriever = ClinicalCaseRetriever(dataset_path=PROCESSED_DATA_PATH, model_name=EMBEDDING_MODEL_ID)\n",
|
| 370 |
+
"evaluator = AnswerEvaluator(model_id=EVALUATOR_MODEL_ID)\n",
|
| 371 |
+
"simulator = OralExamSimulator(retriever, evaluator)"
|
| 372 |
+
]
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"cell_type": "markdown",
|
| 376 |
+
"id": "run-sim-markdown",
|
| 377 |
+
"metadata": {},
|
| 378 |
+
"source": [
|
| 379 |
+
"## 5. Run Simulation with RAG\n",
|
| 380 |
+
"\n",
|
| 381 |
+
"Demonstrate the core simulation loop: start a case based on a query, process user responses, and get feedback. \n",
|
| 382 |
+
"Let's take the example of 'bowel intussusception in a child'."
|
| 383 |
+
]
|
| 384 |
+
},
|
| 385 |
+
{
|
| 386 |
+
"cell_type": "markdown",
|
| 387 |
+
"id": "run-sim-start-markdown",
|
| 388 |
+
"metadata": {},
|
| 389 |
+
"source": [
|
| 390 |
+
"### 5.1 Start a New Case"
|
| 391 |
+
]
|
| 392 |
+
},
|
| 393 |
+
{
|
| 394 |
+
"cell_type": "code",
|
| 395 |
+
"execution_count": 5,
|
| 396 |
+
"id": "run-sim-start-code",
|
| 397 |
+
"metadata": {},
|
| 398 |
+
"outputs": [
|
| 399 |
+
{
|
| 400 |
+
"data": {
|
| 401 |
+
"text/markdown": [
|
| 402 |
+
"**➡️ Please enter the clinical scenario that you would like to be examined on:**"
|
| 403 |
+
],
|
| 404 |
+
"text/plain": [
|
| 405 |
+
"<IPython.core.display.Markdown object>"
|
| 406 |
+
]
|
| 407 |
+
},
|
| 408 |
+
"metadata": {},
|
| 409 |
+
"output_type": "display_data"
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"name": "stdin",
|
| 413 |
+
"output_type": "stream",
|
| 414 |
+
"text": [
|
| 415 |
+
" Your Answer: bowel intussusception in child\n"
|
| 416 |
+
]
|
| 417 |
+
},
|
| 418 |
+
{
|
| 419 |
+
"name": "stdout",
|
| 420 |
+
"output_type": "stream",
|
| 421 |
+
"text": [
|
| 422 |
+
"--------------------------------------------------\n",
|
| 423 |
+
"Attempting to start new case | Query: 'bowel intussusception in child' | Index: None\n",
|
| 424 |
+
"Encoding query: 'Clinical case about bowel intussusception in child'\n",
|
| 425 |
+
"Retrieved 1 cases with similarity scores:\n",
|
| 426 |
+
"- Intussusception Pediatrics: 0.7762\n",
|
| 427 |
+
"Retrieved case via query ('bowel intussusception in child') with score 0.7762: Intussusception Pediatrics\n",
|
| 428 |
+
"Case successfully started. Total questions: 12\n",
|
| 429 |
+
"--------------------------------------------------\n",
|
| 430 |
+
"\n",
|
| 431 |
+
"Case Started: Intussusception Pediatrics\n",
|
| 432 |
+
"Total Questions: 12\n",
|
| 433 |
+
"\n",
|
| 434 |
+
"--- Question 1 --- \n",
|
| 435 |
+
"You're called to the emergency department to evaluate an 18-month-old boy with an eight-hour history of intermittent intense abdominal pain. His mother notes that the pain starts abruptly, and that the kid will draw his knees up to his chest during these painful episodes. Pain lasts for 30 minutes at a time and spontaneously resolves. He's had one episode of non-bloody emesis. He's not had diarrhea or bloody stools.\n"
|
| 436 |
+
]
|
| 437 |
+
}
|
| 438 |
+
],
|
| 439 |
+
"source": [
|
| 440 |
+
"# --- Start Simulation ---\n",
|
| 441 |
+
"display(Markdown(f\"**➡️ Please enter the clinical scenario that you would like to be examined on:**\"))\n",
|
| 442 |
+
"query = input(\" Your Answer: \")\n",
|
| 443 |
+
"case_info = simulator.start_new_case(clinical_query=query)\n",
|
| 444 |
+
"\n",
|
| 445 |
+
"# Directly print the first question (assuming success)\n",
|
| 446 |
+
"print(f\"\\nCase Started: {case_info.get('clinical_presentation', 'N/A')}\")\n",
|
| 447 |
+
"print(f\"Total Questions: {case_info.get('total_questions', 'N/A')}\")\n",
|
| 448 |
+
"print(\"\\n--- Question 1 --- \")\n",
|
| 449 |
+
"print(case_info.get('current_question', 'Error: No question found'))"
|
| 450 |
+
]
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"cell_type": "markdown",
|
| 454 |
+
"id": "run-sim-turn1-markdown",
|
| 455 |
+
"metadata": {},
|
| 456 |
+
"source": [
|
| 457 |
+
"### 5.2 Process User Response (Turn 1)"
|
| 458 |
+
]
|
| 459 |
+
},
|
| 460 |
+
{
|
| 461 |
+
"cell_type": "code",
|
| 462 |
+
"execution_count": 6,
|
| 463 |
+
"id": "44c6e822-5508-4db2-8700-79f25dc14e05",
|
| 464 |
+
"metadata": {},
|
| 465 |
+
"outputs": [
|
| 466 |
+
{
|
| 467 |
+
"data": {
|
| 468 |
+
"text/markdown": [
|
| 469 |
+
"**➡️ Your Turn (Question 1/12)**"
|
| 470 |
+
],
|
| 471 |
+
"text/plain": [
|
| 472 |
+
"<IPython.core.display.Markdown object>"
|
| 473 |
+
]
|
| 474 |
+
},
|
| 475 |
+
"metadata": {},
|
| 476 |
+
"output_type": "display_data"
|
| 477 |
+
},
|
| 478 |
+
{
|
| 479 |
+
"name": "stdin",
|
| 480 |
+
"output_type": "stream",
|
| 481 |
+
"text": [
|
| 482 |
+
" Your Answer: Perform physical exam, looking specifically for abdominal signs, order labs, and get vitals\n"
|
| 483 |
+
]
|
| 484 |
+
},
|
| 485 |
+
{
|
| 486 |
+
"name": "stdout",
|
| 487 |
+
"output_type": "stream",
|
| 488 |
+
"text": [
|
| 489 |
+
"\n",
|
| 490 |
+
"⏳ Processing User Answer...\n",
|
| 491 |
+
"--------------------------------------------------\n",
|
| 492 |
+
"Processing response for Question 1/12\n",
|
| 493 |
+
"User Response: Perform physical exam, looking specifically for abdominal signs, order labs, and get vitals\n",
|
| 494 |
+
"Expected Answer: I'd begin by obtaining vital signs and performing a comprehensive history and physical examination, focusing on his history, birth history, and my exam focusing on his abdominal exam, looking for hernias, and doing a rectal exam as well.\n",
|
| 495 |
+
"Generated Feedback: The resident’s response is: \n",
|
| 496 |
+
"Perform physical exam, looking specifically for abdominal signs, order labs, and get vitals\n",
|
| 497 |
+
"\n",
|
| 498 |
+
"ASSESSMENT: Partially Correct\n",
|
| 499 |
+
"\n",
|
| 500 |
+
"The resident mentioned performing a physical exam and ordering labs, but missed the importance of getting vitals. The resident’s response is partially correct because they included some key points but omitted others, such as the importance of obtaining vital signs.\n",
|
| 501 |
+
"Next question (1/12): The patient's tachycardic, the rest of the vital signs are normal. Your exam reveals a toddler in the fetal position on the stretcher. He appears to be in moderate distress. He has diffuse abdominal tenderness and voluntary guarding.\n",
|
| 502 |
+
"--------------------------------------------------\n",
|
| 503 |
+
"\n",
|
| 504 |
+
"❓Next Question (1/12)\n",
|
| 505 |
+
"\n",
|
| 506 |
+
"The patient's tachycardic, the rest of the vital signs are normal. Your exam reveals a toddler in the fetal position on the stretcher. He appears to be in moderate distress. He has diffuse abdominal tenderness and voluntary guarding.\n"
|
| 507 |
+
]
|
| 508 |
+
}
|
| 509 |
+
],
|
| 510 |
+
"source": [
|
| 511 |
+
"display(Markdown(f\"**➡️ Your Turn (Question {simulator.current_question_idx + 1}/{len(simulator.current_case['questions'])})**\"))\n",
|
| 512 |
+
"user_answer = input(\" Your Answer: \")\n",
|
| 513 |
+
"\n",
|
| 514 |
+
"# --- Process Response ---\n",
|
| 515 |
+
"print(f\"\\n⏳ Processing User Answer...\")\n",
|
| 516 |
+
"result = simulator.process_user_response(user_answer)\n",
|
| 517 |
+
"\n",
|
| 518 |
+
"# Next question\n",
|
| 519 |
+
"q_num = result.get('question_number', '?')\n",
|
| 520 |
+
"next_q_text = result.get('next_question', '*Error: No next question found*')\n",
|
| 521 |
+
"print(f\"\\n❓Next Question ({q_num}/{len(simulator.current_case['questions'])})\\n\\n{next_q_text}\")"
|
| 522 |
+
]
|
| 523 |
+
},
|
| 524 |
+
{
|
| 525 |
+
"cell_type": "markdown",
|
| 526 |
+
"id": "run-sim-turn2-markdown",
|
| 527 |
+
"metadata": {},
|
| 528 |
+
"source": [
|
| 529 |
+
"### 5.3 Process User Response (Turn 2)"
|
| 530 |
+
]
|
| 531 |
+
},
|
| 532 |
+
{
|
| 533 |
+
"cell_type": "code",
|
| 534 |
+
"execution_count": 7,
|
| 535 |
+
"id": "run-sim-turn2-code",
|
| 536 |
+
"metadata": {},
|
| 537 |
+
"outputs": [
|
| 538 |
+
{
|
| 539 |
+
"data": {
|
| 540 |
+
"text/markdown": [
|
| 541 |
+
"**➡️ Your Turn (Question 2/12)**"
|
| 542 |
+
],
|
| 543 |
+
"text/plain": [
|
| 544 |
+
"<IPython.core.display.Markdown object>"
|
| 545 |
+
]
|
| 546 |
+
},
|
| 547 |
+
"metadata": {},
|
| 548 |
+
"output_type": "display_data"
|
| 549 |
+
},
|
| 550 |
+
{
|
| 551 |
+
"name": "stdin",
|
| 552 |
+
"output_type": "stream",
|
| 553 |
+
"text": [
|
| 554 |
+
" Your Answer: Ask for labs, get imaging\n"
|
| 555 |
+
]
|
| 556 |
+
},
|
| 557 |
+
{
|
| 558 |
+
"name": "stdout",
|
| 559 |
+
"output_type": "stream",
|
| 560 |
+
"text": [
|
| 561 |
+
"\n",
|
| 562 |
+
"⏳ Processing User Answer...\n",
|
| 563 |
+
"--------------------------------------------------\n",
|
| 564 |
+
"Processing response for Question 2/12\n",
|
| 565 |
+
"User Response: Ask for labs, get imaging\n",
|
| 566 |
+
"Expected Answer: I'd like to know a little bit more about the history. Has he recently been ill or had any sick contacts? When did he pass stool or gas last? Is this a first such episode? Is there any family history of GI conditions or malignancy?\n",
|
| 567 |
+
"Generated Feedback: The resident’s response is: \n",
|
| 568 |
+
"I'd like to know a little bit more about the patient's history. Has he recently been ill or had any sick contacts? When did he pass stool or gas last? Is this a first episode? Is there any family history of GI conditions or malignancy? Ask for labs, get imaging.\n",
|
| 569 |
+
"\n",
|
| 570 |
+
"The expected answer is: \n",
|
| 571 |
+
"I'd like to know a little bit more about the patient's history. Has he recently been ill or had any sick contacts? When did he pass stool or gas last? Is this a first episode? Is there any family history of GI conditions or malignancy? Ask for labs, get imaging.\n",
|
| 572 |
+
"\n",
|
| 573 |
+
"The resident’s response is identical to the expected answer. The resident includes all the\n",
|
| 574 |
+
"Next question (2/12): He has had a mild upper respiratory infection for the past week, but he's been eating normally. His last bowel movement was yesterday. This is the first time he's ever had symptoms like this, and his family and personal history is otherwise unremarkable.\n",
|
| 575 |
+
"--------------------------------------------------\n",
|
| 576 |
+
"\n",
|
| 577 |
+
"❓ Next Question (2/12)\n",
|
| 578 |
+
"\n",
|
| 579 |
+
"He has had a mild upper respiratory infection for the past week, but he's been eating normally. His last bowel movement was yesterday. This is the first time he's ever had symptoms like this, and his family and personal history is otherwise unremarkable.\n"
|
| 580 |
+
]
|
| 581 |
+
}
|
| 582 |
+
],
|
| 583 |
+
"source": [
|
| 584 |
+
"display(Markdown(f\"**➡️ Your Turn (Question {simulator.current_question_idx + 1}/{len(simulator.current_case['questions'])})**\"))\n",
|
| 585 |
+
"user_answer = input(\" Your Answer: \")\n",
|
| 586 |
+
"\n",
|
| 587 |
+
"print(f\"\\n⏳ Processing User Answer...\")\n",
|
| 588 |
+
"result = simulator.process_user_response(user_answer)\n",
|
| 589 |
+
"\n",
|
| 590 |
+
"q_num = result.get('question_number', '?')\n",
|
| 591 |
+
"next_q_text = result.get('next_question', '*Error: No next question found*')\n",
|
| 592 |
+
"print(f\"\\n❓ Next Question ({q_num}/{len(simulator.current_case['questions'])})\\n\\n{next_q_text}\")"
|
| 593 |
+
]
|
| 594 |
+
},
|
| 595 |
+
{
|
| 596 |
+
"cell_type": "markdown",
|
| 597 |
+
"id": "run-sim-summary-markdown",
|
| 598 |
+
"metadata": {},
|
| 599 |
+
"source": [
|
| 600 |
+
"### 5.4 Session Summary and Saving"
|
| 601 |
+
]
|
| 602 |
+
},
|
| 603 |
+
{
|
| 604 |
+
"cell_type": "code",
|
| 605 |
+
"execution_count": 8,
|
| 606 |
+
"id": "run-sim-summary-code",
|
| 607 |
+
"metadata": {},
|
| 608 |
+
"outputs": [
|
| 609 |
+
{
|
| 610 |
+
"name": "stdout",
|
| 611 |
+
"output_type": "stream",
|
| 612 |
+
"text": [
|
| 613 |
+
"\n",
|
| 614 |
+
"--- Generating Session Summary --- \n",
|
| 615 |
+
"Case: Intussusception Pediatrics\n",
|
| 616 |
+
"Case ID: 87A\n",
|
| 617 |
+
"Total Questions in Case: 12\n",
|
| 618 |
+
"Number of Interactions Logged: 8\n"
|
| 619 |
+
]
|
| 620 |
+
}
|
| 621 |
+
],
|
| 622 |
+
"source": [
|
| 623 |
+
"print(\"\\n--- Generating Session Summary --- \")\n",
|
| 624 |
+
"session_summary = simulator.generate_session_summary()\n",
|
| 625 |
+
"\n",
|
| 626 |
+
"print(f\"Case: {session_summary.get('case', 'N/A')}\")\n",
|
| 627 |
+
"print(f\"Case ID: {session_summary.get('case_id', 'N/A')}\")\n",
|
| 628 |
+
"print(f\"Total Questions in Case: {session_summary.get('total_questions_in_case', 'N/A')}\")\n",
|
| 629 |
+
"print(f\"Number of Interactions Logged: {len(session_summary.get('interaction_history', []))}\")\n",
|
| 630 |
+
"\n",
|
| 631 |
+
"# Display full session interaction\n",
|
| 632 |
+
"#print(json.dumps(session_summary, indent=2)) # Keep commented out or remove"
|
| 633 |
+
]
|
| 634 |
+
},
|
| 635 |
+
{
|
| 636 |
+
"cell_type": "markdown",
|
| 637 |
+
"id": "eval-retrieval-markdown",
|
| 638 |
+
"metadata": {},
|
| 639 |
+
"source": [
|
| 640 |
+
"## 6. Evaluate Retrieval Performance\n",
|
| 641 |
+
"\n",
|
| 642 |
+
"Creating dummy dataset to evaluate RAG performance"
|
| 643 |
+
]
|
| 644 |
+
},
|
| 645 |
+
{
|
| 646 |
+
"cell_type": "code",
|
| 647 |
+
"execution_count": 9,
|
| 648 |
+
"id": "eval-retrieval-run-code",
|
| 649 |
+
"metadata": {},
|
| 650 |
+
"outputs": [
|
| 651 |
+
{
|
| 652 |
+
"name": "stdout",
|
| 653 |
+
"output_type": "stream",
|
| 654 |
+
"text": [
|
| 655 |
+
"\n",
|
| 656 |
+
"Calculating retrieval metrics for 5 queries (k=5)...\n",
|
| 657 |
+
"\n",
|
| 658 |
+
"Processing query 1/5: 'appendix inflammation in a child' (Expected ID: '85A')\n",
|
| 659 |
+
"Encoding query: 'Clinical case about appendix inflammation in a child'\n",
|
| 660 |
+
"Retrieved 5 cases with similarity scores:\n",
|
| 661 |
+
"- Appendicitis Pediatrics: 0.7076\n",
|
| 662 |
+
"- Acute Appendicitis: 0.5978\n",
|
| 663 |
+
"- Intussusception Pediatrics: 0.5745\n",
|
| 664 |
+
"- Meckel s Diverticulum Pediatrics: 0.5277\n",
|
| 665 |
+
"- Abdominal Mass Pediatrics: 0.4705\n",
|
| 666 |
+
"Retrieved IDs: ['85A', '31A', '87A', '89A', '84A']\n",
|
| 667 |
+
"Retrieved Scores: [0.7076, 0.5978, 0.5745, 0.5277, 0.4705]\n",
|
| 668 |
+
"Hit: 1, Rank: 1, NDCG@5: 1.0000\n",
|
| 669 |
+
"\n",
|
| 670 |
+
"Processing query 2/5: 'Pyloric Stenosis in a child' (Expected ID: '90A')\n",
|
| 671 |
+
"Encoding query: 'Clinical case about Pyloric Stenosis in a child'\n",
|
| 672 |
+
"Retrieved 5 cases with similarity scores:\n",
|
| 673 |
+
"- Pyloric Stenosis Pediatrics: 0.7554\n",
|
| 674 |
+
"- Carotid Stenosis: 0.4458\n",
|
| 675 |
+
"- Pheochromocytoma: 0.4139\n",
|
| 676 |
+
"- Small Bowel Obstruction: 0.3876\n",
|
| 677 |
+
"- Intussusception Pediatrics: 0.3855\n",
|
| 678 |
+
"Retrieved IDs: ['90A', '79A', '54A', '23A', '87A']\n",
|
| 679 |
+
"Retrieved Scores: [0.7554, 0.4458, 0.4139, 0.3876, 0.3855]\n",
|
| 680 |
+
"Hit: 1, Rank: 1, NDCG@5: 1.0000\n",
|
| 681 |
+
"\n",
|
| 682 |
+
"Processing query 3/5: 'perforation of the esophagus' (Expected ID: '16A')\n",
|
| 683 |
+
"Encoding query: 'Clinical case about perforation of the esophagus'\n",
|
| 684 |
+
"Retrieved 5 cases with similarity scores:\n",
|
| 685 |
+
"- Esophageal Perforation: 0.6348\n",
|
| 686 |
+
"- Esophageal Cancer: 0.5415\n",
|
| 687 |
+
"- Esophageal Dysmotility: 0.5269\n",
|
| 688 |
+
"- ARDS: 0.4708\n",
|
| 689 |
+
"- Esophagus and Trachea Trauma Empyema: 0.4500\n",
|
| 690 |
+
"Retrieved IDs: ['16A', '14A', '15A', '65A', '71A']\n",
|
| 691 |
+
"Retrieved Scores: [0.6348, 0.5415, 0.5269, 0.4708, 0.45]\n",
|
| 692 |
+
"Hit: 1, Rank: 1, NDCG@5: 1.0000\n",
|
| 693 |
+
"\n",
|
| 694 |
+
"Processing query 4/5: 'papilloma of the breast' (Expected ID: '43A')\n",
|
| 695 |
+
"Encoding query: 'Clinical case about papilloma of the breast'\n",
|
| 696 |
+
"Retrieved 5 cases with similarity scores:\n",
|
| 697 |
+
"- Intraductal Papilloma: 0.7125\n",
|
| 698 |
+
"- Unknown: 0.4971\n",
|
| 699 |
+
"- Inflammatory Breast Cancer: 0.4842\n",
|
| 700 |
+
"- Breast Abscess: 0.4826\n",
|
| 701 |
+
"- Breast Cancer in Pregnancy: 0.4616\n",
|
| 702 |
+
"Retrieved IDs: ['43A', 'Unknown', '42A', '39A', '40A']\n",
|
| 703 |
+
"Retrieved Scores: [0.7125, 0.4971, 0.4842, 0.4826, 0.4616]\n",
|
| 704 |
+
"Hit: 1, Rank: 1, NDCG@5: 1.0000\n",
|
| 705 |
+
"\n",
|
| 706 |
+
"Processing query 5/5: 'injury to the neck vessel' (Expected ID: '66A')\n",
|
| 707 |
+
"Encoding query: 'Clinical case about injury to the neck vessel'\n",
|
| 708 |
+
"Retrieved 5 cases with similarity scores:\n",
|
| 709 |
+
"- Vascular Neck Injury: 0.6604\n",
|
| 710 |
+
"- Esophagus and Trachea Trauma Empyema: 0.4970\n",
|
| 711 |
+
"- Liver Trauma: 0.4957\n",
|
| 712 |
+
"- Carotid Stenosis: 0.4798\n",
|
| 713 |
+
"- Lower Extremity Vascular Injury: 0.4598\n",
|
| 714 |
+
"Retrieved IDs: ['66A', '71A', '72A', '79A', '68A']\n",
|
| 715 |
+
"Retrieved Scores: [0.6604, 0.497, 0.4957, 0.4798, 0.4598]\n",
|
| 716 |
+
"Hit: 1, Rank: 1, NDCG@5: 1.0000\n",
|
| 717 |
+
"\n",
|
| 718 |
+
"--- Overall Retrieval Results (k=5) --- \n",
|
| 719 |
+
"Average Hit@5: 1.0000\n",
|
| 720 |
+
"Average MRR: 1.0000\n",
|
| 721 |
+
"Average NDCG@5: 1.0000\n"
|
| 722 |
+
]
|
| 723 |
+
}
|
| 724 |
+
],
|
| 725 |
+
"source": [
|
| 726 |
+
"# Define benchmark queries and corresponding gold standard case IDs\n",
|
| 727 |
+
"benchmark_queries = [\n",
|
| 728 |
+
" \"appendix inflammation in a child\",\n",
|
| 729 |
+
" \"Pyloric Stenosis in a child\",\n",
|
| 730 |
+
" \"perforation of the esophagus\",\n",
|
| 731 |
+
" \"papilloma of the breast\",\n",
|
| 732 |
+
" \"injury to the neck vessel\"\n",
|
| 733 |
+
"]\n",
|
| 734 |
+
"\n",
|
| 735 |
+
"benchmark_gold_ids = [\n",
|
| 736 |
+
" \"85A\", # Appendicitis Pediatrics\n",
|
| 737 |
+
" \"90A\", # Pyloric Stenosis Pediatrics\n",
|
| 738 |
+
" \"16A\", # Esophageal Perforation\n",
|
| 739 |
+
" \"43A\", # Intraductal Papilloma\n",
|
| 740 |
+
" \"66A\" # Vascular Neck Injury\n",
|
| 741 |
+
"]\n",
|
| 742 |
+
"\n",
|
| 743 |
+
"# Run benchmarking at k=5 using the initialized retriever\n",
|
| 744 |
+
"k_value = 5\n",
|
| 745 |
+
"results = retrieval_metrics(retriever, benchmark_queries, benchmark_gold_ids, k=k_value)"
|
| 746 |
+
]
|
| 747 |
+
},
|
| 748 |
+
{
|
| 749 |
+
"cell_type": "markdown",
|
| 750 |
+
"id": "compare-nonrag-markdown",
|
| 751 |
+
"metadata": {},
|
| 752 |
+
"source": [
|
| 753 |
+
"## 7. Compare with Non-RAG Simulation\n",
|
| 754 |
+
"\n",
|
| 755 |
+
"This section demonstrates generating a synthetic case directly with an LLM and running the simulation using the `DummyRetriever` for comparison. \n",
|
| 756 |
+
"We will use the same example (intussusception in pediatric patient')"
|
| 757 |
+
]
|
| 758 |
+
},
|
| 759 |
+
{
|
| 760 |
+
"cell_type": "code",
|
| 761 |
+
"execution_count": 21,
|
| 762 |
+
"id": "compare-nonrag-gen-code",
|
| 763 |
+
"metadata": {},
|
| 764 |
+
"outputs": [
|
| 765 |
+
{
|
| 766 |
+
"data": {
|
| 767 |
+
"text/markdown": [
|
| 768 |
+
"**➡️ Please enter the topic that you would like to generate synthetic data about:**"
|
| 769 |
+
],
|
| 770 |
+
"text/plain": [
|
| 771 |
+
"<IPython.core.display.Markdown object>"
|
| 772 |
+
]
|
| 773 |
+
},
|
| 774 |
+
"metadata": {},
|
| 775 |
+
"output_type": "display_data"
|
| 776 |
+
},
|
| 777 |
+
{
|
| 778 |
+
"name": "stdin",
|
| 779 |
+
"output_type": "stream",
|
| 780 |
+
"text": [
|
| 781 |
+
"Answer: bowel intussusception child\n"
|
| 782 |
+
]
|
| 783 |
+
},
|
| 784 |
+
{
|
| 785 |
+
"name": "stdout",
|
| 786 |
+
"output_type": "stream",
|
| 787 |
+
"text": [
|
| 788 |
+
"Generating synthetic case for 'bowel intussusception child' using meta-llama/Llama-3.2-3B-Instruct...\n"
|
| 789 |
+
]
|
| 790 |
+
},
|
| 791 |
+
{
|
| 792 |
+
"data": {
|
| 793 |
+
"application/vnd.jupyter.widget-view+json": {
|
| 794 |
+
"model_id": "c7501d4d2b714cb7b5c8bc7199138a85",
|
| 795 |
+
"version_major": 2,
|
| 796 |
+
"version_minor": 0
|
| 797 |
+
},
|
| 798 |
+
"text/plain": [
|
| 799 |
+
"Loading checkpoint shards: 0%| | 0/2 [00:00<?, ?it/s]"
|
| 800 |
+
]
|
| 801 |
+
},
|
| 802 |
+
"metadata": {},
|
| 803 |
+
"output_type": "display_data"
|
| 804 |
+
},
|
| 805 |
+
{
|
| 806 |
+
"name": "stdout",
|
| 807 |
+
"output_type": "stream",
|
| 808 |
+
"text": [
|
| 809 |
+
"Synthetic case generation complete.\n",
|
| 810 |
+
"Processed synthetic data into DataFrame with 8 turns.\n"
|
| 811 |
+
]
|
| 812 |
+
},
|
| 813 |
+
{
|
| 814 |
+
"data": {
|
| 815 |
+
"text/html": [
|
| 816 |
+
"<div>\n",
|
| 817 |
+
"<style scoped>\n",
|
| 818 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
| 819 |
+
" vertical-align: middle;\n",
|
| 820 |
+
" }\n",
|
| 821 |
+
"\n",
|
| 822 |
+
" .dataframe tbody tr th {\n",
|
| 823 |
+
" vertical-align: top;\n",
|
| 824 |
+
" }\n",
|
| 825 |
+
"\n",
|
| 826 |
+
" .dataframe thead th {\n",
|
| 827 |
+
" text-align: right;\n",
|
| 828 |
+
" }\n",
|
| 829 |
+
"</style>\n",
|
| 830 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
| 831 |
+
" <thead>\n",
|
| 832 |
+
" <tr style=\"text-align: right;\">\n",
|
| 833 |
+
" <th></th>\n",
|
| 834 |
+
" <th>case_id</th>\n",
|
| 835 |
+
" <th>clinical_presentation</th>\n",
|
| 836 |
+
" <th>turn_id</th>\n",
|
| 837 |
+
" <th>question</th>\n",
|
| 838 |
+
" <th>answer</th>\n",
|
| 839 |
+
" </tr>\n",
|
| 840 |
+
" </thead>\n",
|
| 841 |
+
" <tbody>\n",
|
| 842 |
+
" <tr>\n",
|
| 843 |
+
" <th>0</th>\n",
|
| 844 |
+
" <td>SYNTH_01</td>\n",
|
| 845 |
+
" <td>bowel intussusception child</td>\n",
|
| 846 |
+
" <td>1</td>\n",
|
| 847 |
+
" <td>**\\nA 4-year-old boy presents to the emergency...</td>\n",
|
| 848 |
+
" <td>Intussusception\\n\\n**</td>\n",
|
| 849 |
+
" </tr>\n",
|
| 850 |
+
" <tr>\n",
|
| 851 |
+
" <th>1</th>\n",
|
| 852 |
+
" <td>SYNTH_01</td>\n",
|
| 853 |
+
" <td>bowel intussusception child</td>\n",
|
| 854 |
+
" <td>2</td>\n",
|
| 855 |
+
" <td>**\\nWhat is the typical age range for intussus...</td>\n",
|
| 856 |
+
" <td>6-36 months\\n\\n**</td>\n",
|
| 857 |
+
" </tr>\n",
|
| 858 |
+
" <tr>\n",
|
| 859 |
+
" <th>2</th>\n",
|
| 860 |
+
" <td>SYNTH_01</td>\n",
|
| 861 |
+
" <td>bowel intussusception child</td>\n",
|
| 862 |
+
" <td>3</td>\n",
|
| 863 |
+
" <td>**\\nWhat is the primary mechanism of intussusc...</td>\n",
|
| 864 |
+
" <td>Invagination of a lead point, often a tumor or...</td>\n",
|
| 865 |
+
" </tr>\n",
|
| 866 |
+
" <tr>\n",
|
| 867 |
+
" <th>3</th>\n",
|
| 868 |
+
" <td>SYNTH_01</td>\n",
|
| 869 |
+
" <td>bowel intussusception child</td>\n",
|
| 870 |
+
" <td>4</td>\n",
|
| 871 |
+
" <td>**\\nWhich of the following is a common finding...</td>\n",
|
| 872 |
+
" <td>A palpable abdominal mass\\n\\n**</td>\n",
|
| 873 |
+
" </tr>\n",
|
| 874 |
+
" <tr>\n",
|
| 875 |
+
" <th>4</th>\n",
|
| 876 |
+
" <td>SYNTH_01</td>\n",
|
| 877 |
+
" <td>bowel intussusception child</td>\n",
|
| 878 |
+
" <td>5</td>\n",
|
| 879 |
+
" <td>**\\nWhat is the most common location for intus...</td>\n",
|
| 880 |
+
" <td>Ileum\\n\\n**</td>\n",
|
| 881 |
+
" </tr>\n",
|
| 882 |
+
" <tr>\n",
|
| 883 |
+
" <th>5</th>\n",
|
| 884 |
+
" <td>SYNTH_01</td>\n",
|
| 885 |
+
" <td>bowel intussusception child</td>\n",
|
| 886 |
+
" <td>6</td>\n",
|
| 887 |
+
" <td>**\\nWhat is the primary treatment for intussus...</td>\n",
|
| 888 |
+
" <td>Reduction with air enema\\n\\n**</td>\n",
|
| 889 |
+
" </tr>\n",
|
| 890 |
+
" <tr>\n",
|
| 891 |
+
" <th>6</th>\n",
|
| 892 |
+
" <td>SYNTH_01</td>\n",
|
| 893 |
+
" <td>bowel intussusception child</td>\n",
|
| 894 |
+
" <td>7</td>\n",
|
| 895 |
+
" <td>**\\nWhat is a potential complication of intuss...</td>\n",
|
| 896 |
+
" <td>Perforation and peritonitis\\n\\n**</td>\n",
|
| 897 |
+
" </tr>\n",
|
| 898 |
+
" <tr>\n",
|
| 899 |
+
" <th>7</th>\n",
|
| 900 |
+
" <td>SYNTH_01</td>\n",
|
| 901 |
+
" <td>bowel intussusception child</td>\n",
|
| 902 |
+
" <td>8</td>\n",
|
| 903 |
+
" <td>**\\nHow often does intussusception recur after...</td>\n",
|
| 904 |
+
" <td>Less than 5% of cases, with most recurrences o...</td>\n",
|
| 905 |
+
" </tr>\n",
|
| 906 |
+
" </tbody>\n",
|
| 907 |
+
"</table>\n",
|
| 908 |
+
"</div>"
|
| 909 |
+
],
|
| 910 |
+
"text/plain": [
|
| 911 |
+
" case_id clinical_presentation turn_id \\\n",
|
| 912 |
+
"0 SYNTH_01 bowel intussusception child 1 \n",
|
| 913 |
+
"1 SYNTH_01 bowel intussusception child 2 \n",
|
| 914 |
+
"2 SYNTH_01 bowel intussusception child 3 \n",
|
| 915 |
+
"3 SYNTH_01 bowel intussusception child 4 \n",
|
| 916 |
+
"4 SYNTH_01 bowel intussusception child 5 \n",
|
| 917 |
+
"5 SYNTH_01 bowel intussusception child 6 \n",
|
| 918 |
+
"6 SYNTH_01 bowel intussusception child 7 \n",
|
| 919 |
+
"7 SYNTH_01 bowel intussusception child 8 \n",
|
| 920 |
+
"\n",
|
| 921 |
+
" question \\\n",
|
| 922 |
+
"0 **\\nA 4-year-old boy presents to the emergency... \n",
|
| 923 |
+
"1 **\\nWhat is the typical age range for intussus... \n",
|
| 924 |
+
"2 **\\nWhat is the primary mechanism of intussusc... \n",
|
| 925 |
+
"3 **\\nWhich of the following is a common finding... \n",
|
| 926 |
+
"4 **\\nWhat is the most common location for intus... \n",
|
| 927 |
+
"5 **\\nWhat is the primary treatment for intussus... \n",
|
| 928 |
+
"6 **\\nWhat is a potential complication of intuss... \n",
|
| 929 |
+
"7 **\\nHow often does intussusception recur after... \n",
|
| 930 |
+
"\n",
|
| 931 |
+
" answer \n",
|
| 932 |
+
"0 Intussusception\\n\\n** \n",
|
| 933 |
+
"1 6-36 months\\n\\n** \n",
|
| 934 |
+
"2 Invagination of a lead point, often a tumor or... \n",
|
| 935 |
+
"3 A palpable abdominal mass\\n\\n** \n",
|
| 936 |
+
"4 Ileum\\n\\n** \n",
|
| 937 |
+
"5 Reduction with air enema\\n\\n** \n",
|
| 938 |
+
"6 Perforation and peritonitis\\n\\n** \n",
|
| 939 |
+
"7 Less than 5% of cases, with most recurrences o... "
|
| 940 |
+
]
|
| 941 |
+
},
|
| 942 |
+
"metadata": {},
|
| 943 |
+
"output_type": "display_data"
|
| 944 |
+
}
|
| 945 |
+
],
|
| 946 |
+
"source": [
|
| 947 |
+
"# --- Generate and Process Synthetic Case ---\n",
|
| 948 |
+
"display(Markdown(f\"**➡️ Please enter the topic that you would like to generate synthetic data about:**\"))\n",
|
| 949 |
+
"synthetic_query = input(\"Answer: \")\n",
|
| 950 |
+
"df_synthetic_case = pd.DataFrame()\n",
|
| 951 |
+
"\n",
|
| 952 |
+
"raw_synthetic_text = generate_synthetic_case(synthetic_query, model_id=EVALUATOR_MODEL_ID)\n",
|
| 953 |
+
"df_synthetic_case = process_synthetic_data(synthetic_query, raw_synthetic_text)\n",
|
| 954 |
+
"display(df_synthetic_case)"
|
| 955 |
+
]
|
| 956 |
+
},
|
| 957 |
+
{
|
| 958 |
+
"cell_type": "code",
|
| 959 |
+
"execution_count": null,
|
| 960 |
+
"id": "9698b316-528f-4324-a6a5-ca27b1407b12",
|
| 961 |
+
"metadata": {},
|
| 962 |
+
"outputs": [
|
| 963 |
+
{
|
| 964 |
+
"name": "stdout",
|
| 965 |
+
"output_type": "stream",
|
| 966 |
+
"text": [
|
| 967 |
+
"DummyRetriever processing 1 unique presentations.\n",
|
| 968 |
+
"DummyRetriever initialized with 1 cases.\n",
|
| 969 |
+
"--------------------------------------------------\n",
|
| 970 |
+
"Attempting to start new case | Query: 'bowel intussusception child' | Index: None\n",
|
| 971 |
+
"DummyRetriever searching for exact match: 'bowel intussusception child'\n",
|
| 972 |
+
"DummyRetriever found match: bowel intussusception child\n",
|
| 973 |
+
"Retrieved case via query ('bowel intussusception child') with score 1.0000: bowel intussusception child\n",
|
| 974 |
+
"Case successfully started. Total questions: 8\n",
|
| 975 |
+
"--------------------------------------------------\n",
|
| 976 |
+
"[Q1] **\n",
|
| 977 |
+
"A 4-year-old boy presents to the emergency department with abdominal pain and vomiting. The child was playing outside and suddenly became ill, unable to continue playing. He has no history of abdominal pain or gastrointestinal symptoms.\n",
|
| 978 |
+
"\n",
|
| 979 |
+
"**Q1:**\n",
|
| 980 |
+
"What is the likely underlying cause of the child's symptoms?\n",
|
| 981 |
+
"A1: Intussusception\n",
|
| 982 |
+
"\n",
|
| 983 |
+
"**Q2:**\n",
|
| 984 |
+
"What is the typical age range for intussusception in children?\n",
|
| 985 |
+
"A2: 6-36 months\n",
|
| 986 |
+
"\n",
|
| 987 |
+
"**Q3:**\n",
|
| 988 |
+
"What is the primary mechanism of intussusception in children?\n",
|
| 989 |
+
"A3: Invagination of a lead point, often a tumor or inflammatory lesion, into the intestine\n",
|
| 990 |
+
"\n",
|
| 991 |
+
"**Q4:**\n",
|
| 992 |
+
"Which of the following is a common finding in children with intussusception?\n",
|
| 993 |
+
"A4: A palpable abdominal mass\n",
|
| 994 |
+
"\n",
|
| 995 |
+
"**Q5:**\n",
|
| 996 |
+
"What is the most common location for intussusception in children?\n",
|
| 997 |
+
"A5: Ileum\n",
|
| 998 |
+
"\n",
|
| 999 |
+
"**Q6:**\n",
|
| 1000 |
+
"What is the primary treatment for intussusception in children?\n",
|
| 1001 |
+
"A6: Reduction with air enema\n",
|
| 1002 |
+
"\n",
|
| 1003 |
+
"**Q7:**\n",
|
| 1004 |
+
"What is a potential complication of intussusception if not treated promptly?\n",
|
| 1005 |
+
"A7: Perforation and peritonitis\n",
|
| 1006 |
+
"\n",
|
| 1007 |
+
"**Q8:**\n",
|
| 1008 |
+
"How often does intussusception recur after successful treatment?\n",
|
| 1009 |
+
"A8: Less than 5% of cases, with most recurrences occurring within 6 months of initial presentation. **\n",
|
| 1010 |
+
"What is the likely underlying cause of the child's symptoms?\n"
|
| 1011 |
+
]
|
| 1012 |
+
},
|
| 1013 |
+
{
|
| 1014 |
+
"data": {
|
| 1015 |
+
"text/markdown": [
|
| 1016 |
+
"<br><b>Please enter your answer:"
|
| 1017 |
+
],
|
| 1018 |
+
"text/plain": [
|
| 1019 |
+
"<IPython.core.display.Markdown object>"
|
| 1020 |
+
]
|
| 1021 |
+
},
|
| 1022 |
+
"metadata": {},
|
| 1023 |
+
"output_type": "display_data"
|
| 1024 |
+
}
|
| 1025 |
+
],
|
| 1026 |
+
"source": [
|
| 1027 |
+
"# Initialize components and starting case\n",
|
| 1028 |
+
"dummy_retriever = DummyRetriever(df_synthetic_case)\n",
|
| 1029 |
+
"non_rag_simulator = OralExamSimulator(dummy_retriever, evaluator)\n",
|
| 1030 |
+
"non_rag_case_info = non_rag_simulator.start_new_case(clinical_query=synthetic_query)\n",
|
| 1031 |
+
"print(f\"[Q1] {non_rag_case_info.get('current_question', 'N/A')}\")\n",
|
| 1032 |
+
"\n",
|
| 1033 |
+
"display(Markdown(f\"<br><b>Please enter your answer:\"))\n",
|
| 1034 |
+
"non_rag_answer_1 = input(\"Answer :\")\n",
|
| 1035 |
+
"non_rag_result_1 = non_rag_simulator.process_user_response(non_rag_answer_1)"
|
| 1036 |
+
]
|
| 1037 |
+
},
|
| 1038 |
+
{
|
| 1039 |
+
"cell_type": "code",
|
| 1040 |
+
"execution_count": null,
|
| 1041 |
+
"id": "f5ec35c2-1bc0-4602-a194-52fa62acb94d",
|
| 1042 |
+
"metadata": {},
|
| 1043 |
+
"outputs": [],
|
| 1044 |
+
"source": [
|
| 1045 |
+
"# --- Process Turn 2 ---\n",
|
| 1046 |
+
"print(f\"[Q2] {non_rag_result_1.get('next_question', 'N/A')}\")\n",
|
| 1047 |
+
"display(Markdown(f\"<br><b>Please enter your answer:\"))\n",
|
| 1048 |
+
"non_rag_answer_2 = input(\"Answer :\")\n",
|
| 1049 |
+
"non_rag_answer_2 = non_rag_simulator.process_user_response(non_rag_answer_2)"
|
| 1050 |
+
]
|
| 1051 |
+
}
|
| 1052 |
+
],
|
| 1053 |
+
"metadata": {
|
| 1054 |
+
"kernelspec": {
|
| 1055 |
+
"display_name": "llm_course",
|
| 1056 |
+
"language": "python",
|
| 1057 |
+
"name": "llm_course"
|
| 1058 |
+
},
|
| 1059 |
+
"language_info": {
|
| 1060 |
+
"codemirror_mode": {
|
| 1061 |
+
"name": "ipython",
|
| 1062 |
+
"version": 3
|
| 1063 |
+
},
|
| 1064 |
+
"file_extension": ".py",
|
| 1065 |
+
"mimetype": "text/x-python",
|
| 1066 |
+
"name": "python",
|
| 1067 |
+
"nbconvert_exporter": "python",
|
| 1068 |
+
"pygments_lexer": "ipython3",
|
| 1069 |
+
"version": "3.11.6"
|
| 1070 |
+
}
|
| 1071 |
+
},
|
| 1072 |
+
"nbformat": 4,
|
| 1073 |
+
"nbformat_minor": 5
|
| 1074 |
+
}
|