{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# SIR Model for Viral Marketing" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from decimal import Decimal\n", "from datetime import timedelta\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "%matplotlib inline\n", "import pandas as pd\n", "from tabulate import tabulate\n", "\n", "from __future__ import print_function\n", "from ipywidgets import interact, interactive, fixed, interact_manual\n", "import ipywidgets as widgets\n", "from IPython.display import clear_output\n", "\n", "from SimCAD.configuration import Configuration\n", "from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \\\n", " ep_time_step\n", "from SimCAD.engine import ExecutionMode, ExecutionContext, Executor" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sim_config = {\n", " 'N': 1,\n", " 'T': range(50)\n", "}\n", "\n", "seed = {}\n", "env_processes = {}\n", "initial_condition = {\n", " 'Budget': float(50),\n", " 'Ps': float(1000),\n", " 'Pi': float(10),\n", " 'Pr': float(0),\n", " 'beta': float(0.05), # contact rate between S and I\n", " 'gamma': float(0.20), # recover rate from I to R\n", " 'timestamp': '2019-01-01 00:00:00'\n", "}\n", "\n", "# Parameters\n", "epsilon = 0.03\n", "subscription_fee = 1.0\n", "incentive_cost = 10.0\n", "stickiness_cost = 5.0\n", "delta_beta = 0.1\n", "delta_gamma = 0.1\n", "\n", "ts_format = '%Y-%m-%d %H:%M:%S'\n", "t_delta = timedelta(days=0, minutes=0, seconds=1)\n", "def time_model(step, sL, s, _input):\n", " y = 'timestamp'\n", " x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta)\n", " return (y, x)\n", "\n", "exogenous_states = exo_update_per_ts(\n", " {\n", " 'timestamp': time_model\n", " }\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Behaviors choose actions depending on states\n", "# 1) increase contact rate, beta (create incentive to spread)\n", "# 2) decrease recover rate, gamma (improve stickiness)\n", "\n", "def add_incentive(step, sL, s):\n", " delta = 0.0\n", " potential_delta = s['beta'] * delta_beta\n", " if (s['Ps'] > 3 * s['Pi']) and s['Budget'] > \\\n", " abs(potential_delta * incentive_cost * s['Ps']):\n", " delta = potential_delta\n", " return {'delta': delta}\n", "\n", "def add_stickiness(step, sL, s):\n", " delta = 0.0\n", " potential_delta = s['gamma'] * delta_gamma\n", " if (s['Pr'] > 2 * s['Pi']) and s['Budget'] > \\\n", " abs(potential_delta * stickiness_cost * s['Pi']):\n", " delta = potential_delta\n", " return {'delta': delta}\n", "\n", "def dummy_behavior(step, sL, s):\n", " return {'delta': 0.0}\n", "\n", "# Mechanisms incur cost to modify beta or gamma\n", "# 1) incur cost to create incentive to spread\n", "# 2) incur cost to improve stickiness\n", "\n", "def incur_incentive_cost(step, sL, s, _input):\n", " y = 'Budget'\n", " x = s['Budget'] - abs(_input['delta'] * s['Ps'] * incentive_cost)\n", " return (y, x)\n", "\n", "def incur_stickiness_cost(step, sL, s, _input):\n", " y = 'Budget'\n", " x = s['Budget'] - abs(_input['delta'] * s['Pi'] * stickiness_cost)\n", " return (y, x)\n", "\n", "def update_beta(step, sL, s, _input):\n", " y = 'beta'\n", " x = s['beta'] + _input['delta']\n", " return (y, x)\n", "\n", "def update_gamma(step, sL, s, _input):\n", " y = 'gamma'\n", " x = s['gamma'] - _input['delta']\n", " return (y, x)\n", "\n", "def S_model(step, sL, s, _input):\n", " y = 'Ps'\n", " x = s['Ps'] - s['beta'] * s['Ps']\n", " return (y, x)\n", "\n", "def I_model(step, sL, s, _input):\n", " y = 'Pi'\n", " x = s['Pi'] + s['beta'] * s['Ps'] - s['gamma'] * s['Pi']\n", " return (y, x)\n", " \n", "def R_model(step, sL, s, _input):\n", " y = 'Pr'\n", " x = s['Pr'] + s['gamma'] * s['Pi']\n", " return (y, x)\n", "\n", "def collect_subscription(step, sL, s, _input):\n", " y = 'Budget'\n", " x = s['Budget'] + s['Pi'] * epsilon * subscription_fee\n", " return (y, x)\n", "\n", "mechanisms = {\n", " 'spread': {\n", " 'behaviors': {\n", " 'dummy': dummy_behavior\n", " },\n", " 'states': {\n", " 'Ps': S_model,\n", " 'Pi': I_model,\n", " 'Pr': R_model,\n", " 'Budget': collect_subscription\n", " } \n", " },\n", " 'create_incentive': {\n", " 'behaviors': {\n", " 'action': add_incentive,\n", " },\n", " 'states': {\n", " 'beta': update_beta,\n", " 'Budget': incur_incentive_cost,\n", " }\n", " },\n", " 'improve_stickiness': {\n", " 'behaviors': {\n", " 'action': add_stickiness\n", " },\n", " 'states': {\n", " 'gamma': update_gamma,\n", " 'Budget': incur_stickiness_cost,\n", " }\n", " }\n", "}" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c288ce264eca4566ab9fdc7db7e801f3" } }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def widget_handler(beta=float(0.05), gamma=float(0.20),\n", " subscription_fee=float(1.0), \n", " incentive_cost=float(10.0), \n", " stickiness_cost=float(5.0)):\n", " initial_condition['beta'] = beta\n", " initial_condition['gamma'] = gamma\n", " subscription_fee = subscription_fee\n", " incentive_cost = incentive_cost\n", " stickiness_cost = stickiness_cost\n", " \n", " config = Configuration(\n", " sim_config=sim_config,\n", " state_dict=initial_condition,\n", " seed=seed,\n", " exogenous_states=exogenous_states,\n", " env_processes=env_processes,\n", " mechanisms=mechanisms)\n", "\n", " exec_mode = ExecutionMode()\n", " exec_context = ExecutionContext(exec_mode.single_proc)\n", " executor = Executor(exec_context, [config]) # Pass the configuration object inside an array\n", " raw_result, tensor = executor.main()\n", " df = pd.DataFrame(raw_result)\n", " df['timestamp'] = pd.to_datetime(df['timestamp'], format=ts_format)\n", " \n", " fig = plt.figure(figsize=(7, 14))\n", " \n", " sir = fig.add_subplot(3, 1, 1)\n", " sir.plot('timestamp', 'Ps', data=df, marker='', color='skyblue', linewidth=2)\n", " sir.plot('timestamp', 'Pi', data=df, marker='', color='orange', linewidth=2)\n", " sir.plot('timestamp', 'Pr', data=df, marker='', color='green', linewidth=2)\n", " sir.legend()\n", " \n", " beta_gamma = fig.add_subplot(3, 1, 2)\n", " beta_gamma.plot('timestamp', 'beta', data=df, marker='', color='skyblue', linewidth=2)\n", " beta_gamma.plot('timestamp', 'gamma', data=df, marker='', color='orange', linewidth=2)\n", " beta_gamma.legend()\n", " \n", " budget_pi = fig.add_subplot(3, 1, 3)\n", " budget_pi.plot('timestamp', 'Budget', data=df, marker='', color='skyblue', linewidth=2)\n", " budget_pi.plot('timestamp', 'Pi', data=df, marker='', color='orange', linewidth=2)\n", " budget_pi.legend()\n", " \n", " plt.show()\n", " \n", "sliders = interact_manual(widget_handler, \n", " beta=(0, 1, 0.01),\n", " gamma=(0, 1, 0.01),\n", " subscription_fee=(0, 10, 0.1),\n", " incentive_cost=(0, 20, 0.5),\n", " stickiness_cost=(0, 20, 0.5)\n", " )\n", "sliders" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# config = Configuration(\n", "# sim_config=sim_config,\n", "# state_dict=initial_condition,\n", "# seed=seed,\n", "# exogenous_states=exogenous_states,\n", "# env_processes=env_processes,\n", "# mechanisms=mechanisms)\n", "\n", "# from SimCAD.engine import ExecutionMode, ExecutionContext, Executor\n", "# exec_mode = ExecutionMode()\n", "# exec_context = ExecutionContext(exec_mode.single_proc)\n", "# executor = Executor(exec_context, [config]) # Pass the configuration object inside an array\n", "# raw_result, tensor = executor.main()\n", "# df = pd.DataFrame(raw_result)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# df.plot('timestamp', ['Ps','Pi', 'Pr'])\n", "# df.plot('timestamp', ['beta', 'gamma'])\n", "# df.plot('timestamp', ['Budget', 'Pi'])\n", "# df[['Ps','Pi', 'Pr']].describe()" ] } ], "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.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }