{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "*This is a Jupyter Notebook. It is an interactive document that contains both rich text elements such as figures, links, equations, etc. and executable code (in this case Python code) contained in cells.\n", "**Instructions:** You can execute the blocks of code one at the time by placing the mouse in the grey box and pressing shift + enter. An asterisk will appear in the brackets at the top left of the box while the code is being exectued (this may take few seconds) and turns into a number when the execution is over. Alternatively,you can run the whole notebook in a single step by clicking on the menu Cell -> Run All.*\n", "\n", "# Using GSA to enhance model-informed decisions\n", "Mathematical models are often used to inform decision-makers dealing with complex management problems. The model is used to predict the consequences of alternative actions, hence providing a quantitative assessment of their benefits and costs, possibly under different uncertain scenarios. In this context, Global Sensitivity Analysis (GSA) can be used to investigate the space of possible actions in a more comprehensive and structured way, including a range of actions possibly larger than the few ones that decision-makers would test in a traditional 'what-if?' analysis. GSA can also help quantifying the importance of these actions relative to other factors that influence the system response, but that are not controllable and potentially highly uncertain (Ref. 1).\n", "\n", "# A flu model example\n", "In this Notebook we will use a flu model, which provides a simple mathematical description of the spread of an infectious deasease, such as flu, within a population. The model divides the population into three \"compartments\":\n", "\n", "- **Vulnerable**: individuals who are vulnerable but not yet infected with the flu;\n", "\n", "- **Sick**: individuals who are infected with the flu;\n", "\n", "- **Immune**: individuals have immunity to the flu. This includes individuals who either have recovered from the flu or have been vaccinated.\n", "\n", "\n", "\n", "The model describes the change in the number of individuals in each compartment over time, using five parameters: \n", "\n", "- **Initial number of vaccinated individuals**: people who are immune at the start of the flu season because they were previously vaccinated.\n", "- **Recovery time**: the average number of days to get fully recovered\n", "- **Contact rate per day**: number of times that an infected individual comes into contact with a vulnerable individual in a day\n", "- **Contagion ratio**: proportion of contacts that result in infection\n", "- **Vaccination rate**: number of inviduals who are vaccinated per day during the outbreak\n", "\n", "Let's imagine the following problem. In a city with a population of 100,000 people, we would like to simulate and compare three possible actions to be taken during the flu season:\n", "\n", "- Implementing social distancing and isolation measures to reduce the daily contact rate. It is estimated that a reduction of 0.1 points of this rate costs £20,000.\n", "- Distribute face masks to reduce the contagion rate. It is estimated that reducing this rate by 0.1 points costs £5,000.\n", "- Increase of the number of daily vaccinations during the flu season. The vaccination cost is of £7 per person.\n", "\n", "We don't know how many people are already vaccinated at the start of the flu season, but we have estimated that this number should range between 0 and 50,000 people (half of the population). The recovery time is also uncertain, but it is estimated to vary between 7 and 21 days.\n", "\n", "The objective is to keep the sick population below **40%** (40,000 people) at any time, because above this number the healthcare system is overwhelmed. The total available budget to achieve this goal is **£300,000**.\n", "\n", "# Finding combinations of actions that achieve the desired outputs\n", "Now use the model to determine a **robust** combination of actions that maintain the sick population below 40,000 at all time for a total cost within the available budget of £300,000. Here, **robust** means that the combination should maintain the sick population below 40,000 under as many scenarios of **Initial number of vaccinated individuals** and **Recovery time** as possible." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "bfea281b7b314588ab78bf0900e1d596", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(VBox(children=(IntSlider(value=0, description='Initial number of vaccinated individuals: ', lay…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from ipywidgets import widgets\n", "from util.flu.flu_interactive import flu_interactive\n", "\n", "immune_ini,contact_rate,contagion_rate,recovery_time,vaccination_rate,fig1 = flu_interactive()\n", "\n", "widgets.VBox([widgets.VBox([immune_ini,recovery_time],\n", " layout=dict(border='solid 1px',width = '750px',height = '80px')),\n", " widgets.VBox([contact_rate,contagion_rate,vaccination_rate],\n", " layout=dict(border='solid 1px', width = '750px',height = '110px')),\n", " fig1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that it is difficult to find a combination of parameters that achieve the set objectives by varying the parameter values one at the time.\n", "In order to facilitate this search we can apply Global Sensitivity Analysis (GSA).\n", "\n", "## Plot sensitivity indices and identify the most influential parameters\n", "Here we use one particular GSA method, PAWN (Ref. 2). It provides a sensitivity index for each model parameter and each output of interest - in our case: the maximum number of individuals who are sick at the same time during the flu season, called **outbreak peak**; and the **total cost** of actions. The sensitivity index measures the relative importance of that parameter on that output: the lower the index, the smaller the influence. The method also provides a threshold value (Ref. 3): if the index of a parameter is above the threshold, then the parameter definitely has an effect on that output, whereas if the index is below the threshold the effect could be negligible.\n", "\n", "First, run the cell below to obtain the sensitivity indices of the outbreak peak. They tell us which parameters have the most influence in attenuating the peak of the sick individuals curve, and hence which actions are more effective (regardless of their cost).\n", "\n", "\n", " \n", "We observe that, among the 3 parameters connected to our possible actions, the *Contact rate per day* has the highest sensitivity index. Hence, reducing the contact rate by social distancing measure is potentially the most effective action. Among all parameters, we observe that the *Recovery time* has quite low sensitivity. This means that the uncertainty around the recovery time should have limited influence on the population dynamics and the efficacy of the possible actions, and hence we may neglect the uncertainty in this variable when assessing the robustness of our solutions.\n", "\n", "Now run the cell below to obtain the sensitivity indices of the total cost.\n", "\n", "\n", "\n", "We observe that *Contact rate per day* has a disproportionally high sensitivity index, which means that acting on it is likely to be very costly. In this sense, acting on the *Vaccination rate* and *Contagion ratio* may be more interesting given that their effects on the total costs are much lower.\n", "\n", "## Finding combinations of actions that achieve the desired outputs, again...\n", "Now taking into account what learnt so far through the GSA, can you find a combination of **two actions** only that flattens the Sick curve so that the **peak stays below 40,000** individuals (blue dashed line) with a **cost lower than £300,000**?" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "bba4d4fe5348430cb81cbc795f2e61da", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(VBox(children=(IntSlider(value=0, description='Initial number of vaccinated individuals: ', lay…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "immune_ini,contact_rate,contagion_rate,recovery_time,vaccination_rate,fig4 = flu_interactive()\n", "\n", "widgets.VBox([widgets.VBox([immune_ini,recovery_time],\n", " layout=dict(border='solid 1px',width = '750px',height = '80px')),\n", " widgets.VBox([contact_rate,contagion_rate,vaccination_rate],\n", " layout=dict(border='solid 1px', width = '750px',height = '110px')),\n", " fig4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### References" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. [What has Global Sensitivity Analysis ever done for us? A systematic review to support scientific advancement and to inform policy-making in earth system modelling - Wagener and Pianosi (2019)](https://www.sciencedirect.com/science/article/pii/S0012825218300990)\n", "2. [PAWN method - Pianosi and Wagener (2018)](https://doi.org/10.1016/j.envsoft.2018.07.019)\n", "3. [Dummy parameter - Zadeh et al. (2017)](https://www.sciencedirect.com/science/article/pii/S1364815217301159)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }