334 lines
10 KiB
Plaintext
334 lines
10 KiB
Plaintext
{
|
|
"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": [
|
|
"<function __main__.widget_handler>"
|
|
]
|
|
},
|
|
"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
|
|
}
|