From c14972f451b3e79916873ead00bf39db3cced31c Mon Sep 17 00:00:00 2001
From: Milan anand raj <84122339+manandraj20@users.noreply.github.com>
Date: Wed, 13 Nov 2024 20:06:32 -0500
Subject: [PATCH] estimating the contact matrix
---
consumption_distribution.csv | 11 +
contact_others.csv | 17 +
demo_final_contact_matrix.ipynb | 383 +++++++++++++++++++++
fractions_offline.csv | 17 +
learnConsumptionDistribution.ipynb | 457 +++++++-------------------
src/DP_epidemiology/contact_matrix.py | 8 +-
src/DP_epidemiology/utilities.py | 3 +-
7 files changed, 556 insertions(+), 340 deletions(-)
create mode 100644 consumption_distribution.csv
create mode 100644 contact_others.csv
create mode 100644 demo_final_contact_matrix.ipynb
create mode 100644 fractions_offline.csv
diff --git a/consumption_distribution.csv b/consumption_distribution.csv
new file mode 100644
index 0000000..5ec3a7c
--- /dev/null
+++ b/consumption_distribution.csv
@@ -0,0 +1,11 @@
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,categories
+3.9831134220168636,5.06535693898893,9.412513264548464,16.47669445152705,14.597838377392605,10.783063027724065,8.839317180273994,7.246249535139835,5.8380845302932665,0.8847316368904793,10.558386678115566,0.44427993082554235,3.7403527519670887,0.797822739409194,0.4309127615318391,0.9080663936568211,Airlines
+4.269706274741251,5.51584019034016,9.925027098030341,17.24910707364407,15.888040810835838,11.597888776410938,8.590887523370377,7.160906175197589,5.825350802619889,4.207369464615332,2.825037836786188,3.4382567596816647,1.5043639705111975,0.9993647865996371,0.5543839427954547,0.42297865759171077,Bars/Discotheques
+4.6576587158892115,5.807818393798755,10.218495929523346,17.674036288476692,14.975431722296308,12.035208306568082,8.244494010171506,6.8856251154757615,5.795880276496676,5.272084848694022,0.22100688090336104,5.6014260677600305,0.5385279415745637,1.1204021150226238,0.6161864025084424,0.3266780292986436,Computer Network/Information Services
+3.868910526597812,4.964923989135904,9.287599672717272,16.246500482110903,14.083572663431884,10.511919951099278,8.924763378029258,7.287604736427168,5.85455662538091,0.0806726290741993,12.530185535397143,-0.1005902190915681,4.333120091520807,0.7607112607593921,0.4040842874523356,0.9922223266493075,Drug Stores/Pharmacies
+3.710988017220926,4.8954977568688784,9.255832460959343,16.23127099747642,14.458123509911672,10.482236347087795,8.893099426408055,7.209016831223323,5.771362634058494,-0.07031876131520942,12.88770131544909,-0.08351529778370403,4.293018885153057,0.7340303276596061,0.39595791080833265,0.974778037486566,General Retail Stores
+4.041791130614517,5.363216544428241,9.659596089925127,16.84932012720208,15.300577517432082,11.181759623457873,8.779841546983189,7.2596021356316776,5.825838817803204,2.590873282049732,7.025758974911309,1.3856593738128338,2.67898917069746,0.8916137911350646,0.49234132790982765,0.6579676081017725,Grocery Stores/Supermarkets
+4.11517400847324,5.378979996397452,9.729832790279593,16.943082788216593,15.429862724415699,11.267742311474356,8.718506744165198,7.25244112496185,5.837748421784723,2.968987668274615,5.932145378191999,2.0104969866343843,2.3764080075475964,0.924224515585339,0.510178404078296,0.5897642930716149,Hospitals
+4.5227982899972154,5.627296194410789,10.088481671119629,17.518086060822533,15.67172627772557,11.886565510005333,8.414294844499254,6.999014033181855,5.757593017266954,4.924462816946865,1.1099804201723777,4.724989197570179,0.758459085363594,1.0543691775117945,0.585157837731053,0.34479440970132724,Hotels/Motels
+4.081777443629556,5.421020222155726,9.714617326563257,16.93327276894294,15.3302614983164,11.273419109412734,8.754001008086536,7.23747397272346,5.8307354535199325,2.9646104167020213,6.122568108719801,1.8070229907660516,2.4557359179329876,0.9146719734769836,0.5049012843990994,0.6121611230626945,Restaurants
+4.214941812551088,5.459473427430981,9.854759889436918,17.138957867125974,15.729181255233387,11.47780029714453,8.633058657388395,7.185546782195898,5.8296313989687,3.7550058154974835,3.9492413438197747,2.9448213868202027,1.8135932937385926,0.9728363296577092,0.5383893712497742,0.48226511872609495,"Utilities: Electric, Gas, Water"
diff --git a/contact_others.csv b/contact_others.csv
new file mode 100644
index 0000000..8f94998
--- /dev/null
+++ b/contact_others.csv
@@ -0,0 +1,17 @@
+"V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16"
+0.86093,0.36829,0.19757,0.17076,0.28803,0.42588,0.4481,0.35819,0.24854,0.15806,0.17132,0.14242,0.09615,0.07543,0.04209,0.01827
+0.41038,1.51673,0.58945,0.19243,0.16044,0.30825,0.3445,0.35671,0.30705,0.13301,0.09596,0.09895,0.09305,0.06339,0.02689,0.01771
+0.13684,0.70604,2.65463,0.48501,0.31742,0.25982,0.27493,0.3061,0.35912,0.20688,0.12182,0.07524,0.05328,0.05058,0.03285,0.02497
+0.07835,0.24016,1.19158,4.1714,1.00423,0.45481,0.26128,0.29327,0.30599,0.24558,0.09849,0.0495,0.03703,0.03003,0.01585,0.00981
+0.11275,0.14289,0.22716,1.69957,2.73443,1.04338,0.56509,0.35195,0.27811,0.29181,0.15917,0.10494,0.04286,0.0303,0.02947,0.02098
+0.21222,0.1083,0.09967,0.47053,1.29932,1.60445,0.83465,0.51887,0.35154,0.28868,0.22139,0.11683,0.04598,0.03192,0.01807,0.00785
+0.22899,0.15882,0.25578,0.2417,0.63038,0.89336,1.02174,0.68406,0.43924,0.30117,0.27338,0.19659,0.09287,0.06097,0.02739,0.02318
+0.21426,0.24961,0.19965,0.16845,0.40542,0.69404,0.78814,0.89548,0.63465,0.3681,0.22597,0.17791,0.15505,0.09785,0.05205,0.01948
+0.16068,0.20336,0.34111,0.25528,0.45595,0.52851,0.66543,0.67371,0.74116,0.40815,0.25114,0.11688,0.11263,0.07465,0.05052,0.01849
+0.05257,0.08135,0.11177,0.25285,0.34799,0.41306,0.46408,0.48345,0.47069,0.43673,0.30403,0.13996,0.10039,0.06041,0.04813,0.0337
+0.0824,0.15325,0.18399,0.31666,0.57611,0.70835,0.47522,0.42916,0.49506,0.49795,0.3513,0.27818,0.17113,0.08579,0.05157,0.03188
+0.12014,0.10706,0.12402,0.17092,0.42346,0.68927,0.65199,0.50394,0.50296,0.31862,0.42107,0.39126,0.25783,0.13282,0.0651,0.03205
+0.09868,0.10344,0.09022,0.17186,0.3624,0.5385,0.50708,0.56803,0.49718,0.36283,0.29572,0.36425,0.32088,0.21736,0.13675,0.05194
+0.08753,0.11417,0.08027,0.10094,0.27975,0.42179,0.48736,0.40993,0.39475,0.28353,0.28199,0.30527,0.29239,0.23512,0.11122,0.06111
+0.03709,0.08269,0.12261,0.25765,0.23921,0.34653,0.32363,0.41689,0.49232,0.34191,0.24456,0.24556,0.41305,0.34529,0.28289,0.09248
+0.06364,0.05985,0.08721,0.06281,0.14629,0.17248,0.29452,0.22279,0.21608,0.24675,0.16311,0.15267,0.14362,0.18024,0.14458,0.08826
diff --git a/demo_final_contact_matrix.ipynb b/demo_final_contact_matrix.ipynb
new file mode 100644
index 0000000..f15f795
--- /dev/null
+++ b/demo_final_contact_matrix.ipynb
@@ -0,0 +1,383 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from datetime import datetime\n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import sys\n",
+ "import os\n",
+ "sys.path.append(os.path.abspath(os.path.join(os.getcwd(), 'src')))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " ID | \n",
+ " merch_category | \n",
+ " merch_postal_code | \n",
+ " transaction_type | \n",
+ " date | \n",
+ " spendamt | \n",
+ " nb_transactions | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Hospitals | \n",
+ " 111921 | \n",
+ " ONLINE | \n",
+ " 2019-01-01 | \n",
+ " 80797.323317 | \n",
+ " 398 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Bars/Discotheques | \n",
+ " 050025 | \n",
+ " OFFLINE | \n",
+ " 2019-01-01 | \n",
+ " 5331.031100 | \n",
+ " 283 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2 | \n",
+ " Bars/Discotheques | \n",
+ " 050032 | \n",
+ " OFFLINE | \n",
+ " 2019-01-01 | \n",
+ " 5180.722635 | \n",
+ " 268 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 3 | \n",
+ " Drug Stores/Pharmacies | \n",
+ " 050012 | \n",
+ " OFFLINE | \n",
+ " 2019-01-01 | \n",
+ " 5032.333763 | \n",
+ " 177 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 3 | \n",
+ " Drug Stores/Pharmacies | \n",
+ " 050031 | \n",
+ " OFFLINE | \n",
+ " 2019-01-01 | \n",
+ " 4899.182326 | \n",
+ " 150 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " ID merch_category merch_postal_code transaction_type date \\\n",
+ "0 1 Hospitals 111921 ONLINE 2019-01-01 \n",
+ "1 2 Bars/Discotheques 050025 OFFLINE 2019-01-01 \n",
+ "2 2 Bars/Discotheques 050032 OFFLINE 2019-01-01 \n",
+ "3 3 Drug Stores/Pharmacies 050012 OFFLINE 2019-01-01 \n",
+ "4 3 Drug Stores/Pharmacies 050031 OFFLINE 2019-01-01 \n",
+ "\n",
+ " spendamt nb_transactions \n",
+ "0 80797.323317 398 \n",
+ "1 5331.031100 283 \n",
+ "2 5180.722635 268 \n",
+ "3 5032.333763 177 \n",
+ "4 4899.182326 150 "
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data = pd.read_csv(r\"C:\\Users\\Milan Anand Raj\\Desktop\\KNOWLEDGEEDGEAI\\PET\\final_data\\final_technical_data.csv\")\n",
+ "data.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Public info about the column names"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "txn_channel_col = \"transaction_type\"\n",
+ "category_col = \"merch_category\"\n",
+ "time_col = \"date\"\n",
+ "postal_code_col = \"merch_postal_code\"\n",
+ "num_txns_col = \"nb_transactions\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Categorising cities in the data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def categorize_city(code):\n",
+ " if code.startswith(\"5\"):\n",
+ " return \"Medellian\"\n",
+ " elif code.startswith(\"11\"):\n",
+ " return \"Bogota\"\n",
+ " elif code.startswith(\"70\"):\n",
+ " return \"Brasilia\"\n",
+ " else:\n",
+ " return \"Santiago\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "age_groups = ['0-4', '5-9', '10-14', '15-19', '20-24', '25-29', '30-34', '35-39', '40-44', '45-49', '50-54', '55-59', '60-64', '65-69', '70-74', '75+']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "consumption_distribution_raw = pd.read_csv('consumption_distribution.csv')\n",
+ "categories = consumption_distribution_raw['categories'].values\n",
+ "consumption_distribution = {}\n",
+ "for category in categories:\n",
+ " consumption_distribution[category] = consumption_distribution_raw[consumption_distribution_raw['categories'] == category].values[0][:-1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scaling_factor = pd.read_csv('fractions_offline.csv')['0'].values"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from DP_epidemiology.contact_matrix import get_age_group_count_map\n",
+ "week =\"2021-01-05\"\n",
+ "start_date = datetime.strptime(week, '%Y-%m-%d')\n",
+ "end_date = datetime.strptime(week, '%Y-%m-%d')\n",
+ "cities = data[postal_code_col].astype(str).apply(categorize_city).unique()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "counts_per_city = []\n",
+ "for city in cities:\n",
+ " counts = get_age_group_count_map(data, age_groups, consumption_distribution, start_date, end_date, city)\n",
+ " counts_per_city.append(list(counts.values()))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "age_groups = ['0-4', '5-9', '10-14', '15-19', '20-24', '25-29', '30-34', '35-39', '40-44', '45-49', '50-54', '55-59', '60-64', '65-69', '70-74', '75+']\n",
+ "consumption_distribution_raw = pd.read_csv('consumption_distribution.csv')\n",
+ "categories = consumption_distribution_raw['categories'].values\n",
+ "consumption_distribution = {}\n",
+ "for category in categories:\n",
+ " consumption_distribution[category] = consumption_distribution_raw[consumption_distribution_raw['categories'] == category].values[0][:-1]\n",
+ "fraction_offline_raw = pd.read_csv('fractions_offline.csv')\n",
+ "fraction_offline = fraction_offline_raw['0'].values\n",
+ "from DP_epidemiology.contact_matrix import get_age_group_count_map\n",
+ "week =\"2021-01-05\"\n",
+ "start_date = datetime.strptime(week, '%Y-%m-%d')\n",
+ "end_date = datetime.strptime(week, '%Y-%m-%d')\n",
+ "cities = data[\"merch_postal_code\"].astype(str).apply(categorize_city).unique()\n",
+ "counts_per_city = []\n",
+ "for city in cities:\n",
+ " counts = get_age_group_count_map(data, age_groups, consumption_distribution, start_date, end_date, city)\n",
+ " counts_per_city.append(list(counts.values()))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "P = np.array([4136344, 4100716, 3991988, 3934088, 4090149, 4141051, 3895117, 3439202,\n",
+ " 3075077, 3025100, 3031855, 2683253, 2187561, 1612948, 1088448, 1394217]) \n",
+ "from DP_epidemiology.contact_matrix import get_contact_matrix_country\n",
+ "estimated_contact_matrix = get_contact_matrix_country(counts_per_city, P, scaling_factor)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[0.09639499, 0.12729707, 0.23459434, 0.41401698, 0.36048598,\n",
+ " 0.26723388, 0.21151241, 0.1940109 , 0.18478214, 0.13886226,\n",
+ " 0.13810061, 0.1138968 , 0.09122256, 0.06328202, 0.04659307,\n",
+ " 0.02991427],\n",
+ " [0.12620061, 0.16665576, 0.30711986, 0.54200709, 0.47192923,\n",
+ " 0.34987358, 0.27687683, 0.25394952, 0.24191389, 0.18202519,\n",
+ " 0.18046582, 0.14933275, 0.11932049, 0.0828854 , 0.06100833,\n",
+ " 0.03909869],\n",
+ " [0.22640714, 0.29897676, 0.55092938, 0.97226376, 0.84656522,\n",
+ " 0.62773045, 0.49656496, 0.45536685, 0.43398723, 0.3275752 ,\n",
+ " 0.32224618, 0.26887916, 0.21358051, 0.1488641 , 0.10948895,\n",
+ " 0.06984912],\n",
+ " [0.39377267, 0.51998324, 0.958162 , 1.69092516, 1.47231947,\n",
+ " 1.09178936, 0.86355278, 0.79186499, 0.75479419, 0.5702682 ,\n",
+ " 0.55965221, 0.46815897, 0.3712068 , 0.25899607, 0.19044626,\n",
+ " 0.12132627],\n",
+ " [0.35646004, 0.47071313, 0.86738183, 1.53072478, 1.33282797,\n",
+ " 0.98832319, 0.78176311, 0.7168841 , 0.68327506, 0.51598867,\n",
+ " 0.50698298, 0.42356656, 0.33614752, 0.23441478, 0.17239101,\n",
+ " 0.10990033],\n",
+ " [0.26753799, 0.35331497, 0.65117025, 1.1492258 , 1.00062289,\n",
+ " 0.74162317, 0.58725333, 0.53876943, 0.51286585, 0.38402453,\n",
+ " 0.38534348, 0.31480214, 0.25383525, 0.17540956, 0.12926391,\n",
+ " 0.083426 ],\n",
+ " [0.19917724, 0.26299497, 0.48451514, 0.85499845, 0.74448603,\n",
+ " 0.55237678, 0.43636769, 0.39992833, 0.38175352, 0.29121348,\n",
+ " 0.2789736 , 0.23944631, 0.18644949, 0.13145362, 0.09643546,\n",
+ " 0.06056907],\n",
+ " [0.16131218, 0.21298322, 0.39231044, 0.69225286, 0.60279203,\n",
+ " 0.44745571, 0.35311759, 0.3234834 , 0.30915709, 0.23773022,\n",
+ " 0.22314176, 0.19571837, 0.15011226, 0.10676955, 0.07817335,\n",
+ " 0.04850929],\n",
+ " [0.13737235, 0.18140828, 0.33430565, 0.58998432, 0.51370339,\n",
+ " 0.38084582, 0.30138285, 0.27642513, 0.26332769, 0.19816065,\n",
+ " 0.19641011, 0.16257702, 0.1298715 , 0.0902256 , 0.06640984,\n",
+ " 0.04255421],\n",
+ " [0.10155641, 0.13428006, 0.24823415, 0.43850527, 0.38162848,\n",
+ " 0.28053569, 0.22616776, 0.20910597, 0.19494009, 0.12503586,\n",
+ " 0.1771629 , 0.09967098, 0.10622315, 0.06321094, 0.04828421,\n",
+ " 0.03768237],\n",
+ " [0.1012249 , 0.13342699, 0.24474114, 0.4313031 , 0.37580511,\n",
+ " 0.28212779, 0.2171456 , 0.19671234, 0.19364945, 0.1775585 ,\n",
+ " 0.09782913, 0.14995707, 0.0807196 , 0.0716148 , 0.05012645,\n",
+ " 0.02221963],\n",
+ " [0.07388504, 0.09771405, 0.18072971, 0.31930881, 0.2778716 ,\n",
+ " 0.20398053, 0.16494884, 0.15269876, 0.14186158, 0.08840781,\n",
+ " 0.13271504, 0.07005195, 0.0785104 , 0.04557405, 0.03503114,\n",
+ " 0.02815644],\n",
+ " [0.04824427, 0.06365251, 0.11703953, 0.20641061, 0.17978397,\n",
+ " 0.13409158, 0.10471307, 0.09548137, 0.09238852, 0.07681386,\n",
+ " 0.05824126, 0.06400674, 0.04217825, 0.03286025, 0.02359547,\n",
+ " 0.01285376],\n",
+ " [0.02467653, 0.03260159, 0.06014799, 0.10618654, 0.09244134,\n",
+ " 0.06832239, 0.05443427, 0.05007375, 0.04732539, 0.03370333,\n",
+ " 0.0380991 , 0.02739532, 0.02422875, 0.01589938, 0.01185784,\n",
+ " 0.00819294],\n",
+ " [0.01226062, 0.01619337, 0.02985305, 0.05269095, 0.04587575,\n",
+ " 0.03397617, 0.02694784, 0.02474051, 0.02350629, 0.01737293,\n",
+ " 0.01799559, 0.0142102 , 0.01174022, 0.00800189, 0.00591531,\n",
+ " 0.00388865],\n",
+ " [0.01008305, 0.0132933 , 0.02439507, 0.0429973 , 0.03746194,\n",
+ " 0.02808803, 0.02168008, 0.01966516, 0.01929376, 0.01736716,\n",
+ " 0.01021783, 0.01463007, 0.0081922 , 0.0070819 , 0.00498106,\n",
+ " 0.00230539]])"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "estimated_contact_matrix"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".venv",
+ "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.12.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/fractions_offline.csv b/fractions_offline.csv
new file mode 100644
index 0000000..7e4b3c2
--- /dev/null
+++ b/fractions_offline.csv
@@ -0,0 +1,17 @@
+0
+0.09639499267221661
+0.16665576151505287
+0.5509293775800783
+1.6909251559357241
+1.3328279709246307
+0.7416231743835766
+0.4363676927094427
+0.3234834001840291
+0.2633276881700197
+0.12503585760156408
+0.09782912908619215
+0.07005194670140537
+0.04217824580741681
+0.0158993752169871
+0.0059153120403053466
+0.0023053870404303937
diff --git a/learnConsumptionDistribution.ipynb b/learnConsumptionDistribution.ipynb
index dcf9b7d..32f695e 100644
--- a/learnConsumptionDistribution.ipynb
+++ b/learnConsumptionDistribution.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
@@ -13,7 +13,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
@@ -24,7 +24,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 27,
"metadata": {
"id": "7L6EQkQ50gkR"
},
@@ -130,7 +130,7 @@
"4 4899.182326 150 "
]
},
- "execution_count": 3,
+ "execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
@@ -142,7 +142,7 @@
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
@@ -163,7 +163,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
@@ -179,7 +179,7 @@
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
@@ -194,36 +194,6 @@
" return \"Santiago\""
]
},
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [],
- "source": [
- "data_t = data\n",
- "data_t[\"city\"] = data[postal_code_col].astype(str).apply(categorize_city)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "array(['70640-000', '70000-000'], dtype=object)"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "data_t[data_t[\"city\"]==\"Brasilia\"][\"merch_postal_code\"].unique()"
- ]
- },
{
"cell_type": "markdown",
"metadata": {},
@@ -233,7 +203,7 @@
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 32,
"metadata": {},
"outputs": [
{
@@ -241,26 +211,9 @@
"output_type": "stream",
"text": [
"City: Bogota\n",
- "{'Airlines': 694.2645988925163, 'Bars/Discotheques': 938.8304299835585, 'Computer Network/Information Services': 138.27595054301423, 'Drug Stores/Pharmacies': 745.0404457585972, 'General Retail Stores': 1098.1383922062796, 'Grocery Stores/Supermarkets': 4105.163373337119, 'Hospitals': 1536.995204166018, 'Hotels/Motels': 211.33068313976673, 'Restaurants': 5750.492793907174, 'Utilities: Electric, Gas, Water': 1164.8615359779465}\n",
"City: Santiago\n",
- "{'Airlines': 775.690312082757, 'Bars/Discotheques': 1192.1697652298033, 'Computer Network/Information Services': 130.0848846505698, 'Drug Stores/Pharmacies': 1080.6051216491312, 'General Retail Stores': 1432.3301065873393, 'Grocery Stores/Supermarkets': 5128.047125312137, 'Hospitals': 2178.9284555521135, 'Hotels/Motels': 281.88545031373854, 'Restaurants': 7335.879379150183, 'Utilities: Electric, Gas, Water': 1422.6421925557495}\n",
"City: Brasilia\n"
]
- },
- {
- "ename": "OpenDPException",
- "evalue": "\n FFI(\"Continued stack trace from Exception in user-defined function:\nTraceback (most recent call last):\n File \"c:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\opendp\\_convert.py\", line 629, in wrapper_func\n py_out = func(py_arg)\n ^^^^^^^^^^^^\n File \"c:\\Users\\Milan Anand Raj\\Desktop\\KNOWLEDGEEDGEAI\\PET\\src\\DP_epidemiology\\utilities.py\", line 279, in compute_private_sum\n return dp_sum/dp_dataset_size\n ~~~~~~^~~~~~~~~~~~~~~~\nZeroDivisionError: float division by zero\n\")",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[1;31mOpenDPException\u001b[0m Traceback (most recent call last)",
- "Cell \u001b[1;32mIn[8], line 9\u001b[0m\n\u001b[0;32m 7\u001b[0m end_date \u001b[38;5;241m=\u001b[39m datetime\u001b[38;5;241m.\u001b[39mstrptime(week, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124mY-\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124mm-\u001b[39m\u001b[38;5;132;01m%d\u001b[39;00m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m 8\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCity: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcity\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 9\u001b[0m transactions_per_category \u001b[38;5;241m=\u001b[39m get_private_counts(data, categories\u001b[38;5;241m=\u001b[39mcategories, start_date\u001b[38;5;241m=\u001b[39mstart_date, end_date\u001b[38;5;241m=\u001b[39mend_date, city\u001b[38;5;241m=\u001b[39mcity, epsilon\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1.0\u001b[39m)\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(transactions_per_category)\n\u001b[0;32m 11\u001b[0m transactions_per_city\u001b[38;5;241m.\u001b[39mappend(\u001b[38;5;28mlist\u001b[39m(transactions_per_category\u001b[38;5;241m.\u001b[39mvalues()))\n",
- "File \u001b[1;32mc:\\Users\\Milan Anand Raj\\Desktop\\KNOWLEDGEEDGEAI\\PET\\src\\DP_epidemiology\\contact_matrix.py:73\u001b[0m, in \u001b[0;36mget_private_counts\u001b[1;34m(df, categories, start_date, end_date, city, epsilon)\u001b[0m\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m category \u001b[38;5;129;01min\u001b[39;00m categories:\n\u001b[0;32m 65\u001b[0m m_count \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 66\u001b[0m t_pre\n\u001b[0;32m 67\u001b[0m \u001b[38;5;66;03m# TODO: The scale has to be equal to bound/epsilon, which can be equal to the mean itself in cases where number of entries\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 71\u001b[0m \u001b[38;5;241m>>\u001b[39m make_private_nb_transactions_avg_count(merch_category\u001b[38;5;241m=\u001b[39mcategory, upper_bound\u001b[38;5;241m=\u001b[39mUPPER_BOUND, dp_dataset_size\u001b[38;5;241m=\u001b[39mdp_count, scale\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m3\u001b[39m\u001b[38;5;241m*\u001b[39mUPPER_BOUND\u001b[38;5;241m*\u001b[39mnumber_of_timesteps)\u001b[38;5;241m/\u001b[39mepsilon)\n\u001b[0;32m 72\u001b[0m )\n\u001b[1;32m---> 73\u001b[0m nb_transactions_avg_count_map[category] \u001b[38;5;241m=\u001b[39m m_count(df)\n\u001b[0;32m 75\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m nb_transactions_avg_count_map\n",
- "File \u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\opendp\\mod.py:74\u001b[0m, in \u001b[0;36mMeasurement.__call__\u001b[1;34m(self, arg)\u001b[0m\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__call__\u001b[39m(\u001b[38;5;28mself\u001b[39m, arg):\n\u001b[0;32m 73\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mopendp\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mcore\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m measurement_invoke\n\u001b[1;32m---> 74\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m measurement_invoke(\u001b[38;5;28mself\u001b[39m, arg)\n",
- "File \u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\opendp\\core.py:370\u001b[0m, in \u001b[0;36mmeasurement_invoke\u001b[1;34m(this, arg)\u001b[0m\n\u001b[0;32m 367\u001b[0m lib_function\u001b[38;5;241m.\u001b[39margtypes \u001b[38;5;241m=\u001b[39m [Measurement, AnyObjectPtr]\n\u001b[0;32m 368\u001b[0m lib_function\u001b[38;5;241m.\u001b[39mrestype \u001b[38;5;241m=\u001b[39m FfiResult\n\u001b[1;32m--> 370\u001b[0m output \u001b[38;5;241m=\u001b[39m c_to_py(unwrap(lib_function(c_this, c_arg), AnyObjectPtr))\n\u001b[0;32m 372\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output\n",
- "File \u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\opendp\\_lib.py:254\u001b[0m, in \u001b[0;36munwrap\u001b[1;34m(result, type_)\u001b[0m\n\u001b[0;32m 252\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpolars\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mstr\u001b[39m(message)\u001b[38;5;241m.\u001b[39mlower() \u001b[38;5;129;01mand\u001b[39;00m pl\u001b[38;5;241m.\u001b[39m__version__ \u001b[38;5;241m!=\u001b[39m _EXPECTED_POLARS_VERSION:\n\u001b[0;32m 253\u001b[0m message \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mInstalled python polars version (\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpl\u001b[38;5;241m.\u001b[39m__version__\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m) != expected version (\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m_EXPECTED_POLARS_VERSION\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m). \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmessage\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;66;03m# pragma: no cover\u001b[39;00m\n\u001b[1;32m--> 254\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m OpenDPException(variant, message, backtrace)\n",
- "\u001b[1;31mOpenDPException\u001b[0m: \n FFI(\"Continued stack trace from Exception in user-defined function:\nTraceback (most recent call last):\n File \"c:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\opendp\\_convert.py\", line 629, in wrapper_func\n py_out = func(py_arg)\n ^^^^^^^^^^^^\n File \"c:\\Users\\Milan Anand Raj\\Desktop\\KNOWLEDGEEDGEAI\\PET\\src\\DP_epidemiology\\utilities.py\", line 279, in compute_private_sum\n return dp_sum/dp_dataset_size\n ~~~~~~^~~~~~~~~~~~~~~~\nZeroDivisionError: float division by zero\n\")"
- ]
}
],
"source": [
@@ -273,13 +226,12 @@
" end_date = datetime.strptime(week, '%Y-%m-%d')\n",
" print(f\"City: {city}\")\n",
" transactions_per_category = get_private_counts(data, categories=categories, start_date=start_date, end_date=end_date, city=city, epsilon=1.0)\n",
- " print(transactions_per_category)\n",
" transactions_per_city.append(list(transactions_per_category.values()))"
]
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 33,
"metadata": {
"id": "Oo1El4A40gkU"
},
@@ -289,65 +241,6 @@
"contact_others = np.array(contact_others)"
]
},
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[[665.827343044052,\n",
- " 2376.0030054715944,\n",
- " 4287.216254772609,\n",
- " 63941.44098236439,\n",
- " 21478.388863581316,\n",
- " 40690.41606936624,\n",
- " 2963.936491985296,\n",
- " 5094.1112587002735,\n",
- " 33376.344825964065,\n",
- " 3277.412704119104],\n",
- " [-10.471957055996297,\n",
- " 6140.521392653215,\n",
- " -2593.3432371460517,\n",
- " 3218.708044630042,\n",
- " 2882.8266155488673,\n",
- " -118.73193866793521,\n",
- " -1502.70368483887,\n",
- " 2643.1117283735766,\n",
- " 2515.2197469338525,\n",
- " 2010.369461726336],\n",
- " [909.4191757659195,\n",
- " 14061.87451760006,\n",
- " 10965.389937129481,\n",
- " 174970.32876629836,\n",
- " 40193.28386099822,\n",
- " 98156.80895732576,\n",
- " 4871.752947048472,\n",
- " 10026.12926489293,\n",
- " 74465.54906523543,\n",
- " 2910.016018267648],\n",
- " [-3542.2378675749783,\n",
- " 1250.3608001315356,\n",
- " 1736.475733452081,\n",
- " 59610.73284853197,\n",
- " 14309.168756153636,\n",
- " 37408.784637817975,\n",
- " 302.2175965746237,\n",
- " 2275.2427407967584,\n",
- " 22940.966562785838,\n",
- " 2720.585656936167]]"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "transactions_per_city"
- ]
- },
{
"cell_type": "markdown",
"metadata": {
@@ -359,7 +252,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 39,
"metadata": {
"colab": {
"background_save": true,
@@ -373,58 +266,27 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "Step: 0, Loss: 94.10587900174727\n",
- "Step: 100, Loss: 33.359764471824434\n",
- "Step: 200, Loss: 31.544671445447932\n",
- "Step: 300, Loss: 31.413592926334598\n",
- "Step: 400, Loss: 31.40243082658344\n",
- "Step: 500, Loss: 31.40212694394862\n",
- "Step: 600, Loss: 31.402122757334677\n",
- "Step: 700, Loss: 31.402123427405275\n",
- "Step: 800, Loss: 31.402122713168243\n",
- "Step: 900, Loss: 31.402122705699163\n",
- "Step: 1000, Loss: 31.40212491914406\n",
- "Step: 1100, Loss: 31.4021226954282\n",
- "Step: 1200, Loss: 31.402122691606444\n",
- "Step: 1300, Loss: 31.40213079580314\n",
- "Step: 1400, Loss: 31.402122686265916\n",
- "Step: 1500, Loss: 31.402122684024533\n",
- "Step: 1600, Loss: 31.402140614669783\n",
- "Step: 1700, Loss: 31.40212268161008\n",
- "Step: 1800, Loss: 31.40212268005513\n",
- "Step: 1900, Loss: 31.40216548637534\n",
- "Step: 2000, Loss: 31.402122681491136\n",
- "Step: 2100, Loss: 31.4021226778284\n",
- "Step: 2200, Loss: 31.402122677259698\n",
- "Step: 2300, Loss: 31.402123758030374\n",
- "Step: 2400, Loss: 31.402122676221257\n",
- "Step: 2500, Loss: 31.402122675537353\n",
- "Step: 2600, Loss: 31.402124518646147\n",
- "Step: 2700, Loss: 31.40215292226199\n",
- "Step: 2800, Loss: 31.402126098246065\n",
- "Step: 2900, Loss: 31.402146506092766\n",
- "Step: 3000, Loss: 31.402192845670616\n"
+ "Step: 0, Loss: 85.82141824079703\n",
+ "Step: 100, Loss: 32.142649946338636\n",
+ "Step: 200, Loss: 31.41479591356331\n",
+ "Step: 300, Loss: 31.404196453643934\n",
+ "Step: 400, Loss: 31.402196832687252\n",
+ "Step: 500, Loss: 31.402123071842432\n",
+ "Step: 600, Loss: 31.402122728475618\n",
+ "Step: 700, Loss: 31.40212229653494\n",
+ "Step: 800, Loss: 31.402117143215843\n",
+ "Step: 900, Loss: 31.402044592763584\n"
]
},
{
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
- "\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_4520\\139899758.py\u001b[0m in \u001b[0;36m?\u001b[1;34m()\u001b[0m\n\u001b[0;32m 35\u001b[0m \u001b[1;31m# with tf.device('/GPU:0'):\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mstep\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5000\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;31m# Adjust max iterations as needed\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 37\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mtf\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mGradientTape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mtape\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 38\u001b[0m \u001b[0mloss\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mloss_fn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 39\u001b[1;33m \u001b[0mgrads\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtape\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgradient\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mloss\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mW\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mP_var\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 40\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 41\u001b[0m \u001b[1;31m# Apply gradients\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 42\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapply_gradients\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mzip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrads\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mW\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mP_var\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\eager\\backprop.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(self, target, sources, output_gradients, unconnected_gradients)\u001b[0m\n\u001b[0;32m 1062\u001b[0m \u001b[0moutput_gradients\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1063\u001b[0m output_gradients = [None if x is None else ops.convert_to_tensor(x)\n\u001b[0;32m 1064\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moutput_gradients\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1065\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1066\u001b[1;33m flat_grad = imperative_grad.imperative_grad(\n\u001b[0m\u001b[0;32m 1067\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_tape\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1068\u001b[0m \u001b[0mflat_targets\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1069\u001b[0m \u001b[0mflat_sources\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\eager\\imperative_grad.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(tape, target, sources, output_gradients, sources_raw, unconnected_gradients)\u001b[0m\n\u001b[0;32m 63\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 64\u001b[0m raise ValueError(\n\u001b[0;32m 65\u001b[0m \u001b[1;34m\"Unknown value for unconnected_gradients: %r\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0munconnected_gradients\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 66\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 67\u001b[1;33m return pywrap_tfe.TFE_Py_TapeGradient(\n\u001b[0m\u001b[0;32m 68\u001b[0m \u001b[0mtape\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_tape\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;31m# pylint: disable=protected-access\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 69\u001b[0m \u001b[0mtarget\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 70\u001b[0m \u001b[0msources\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\eager\\backprop.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(op_name, attr_tuple, num_inputs, inputs, outputs, out_grads, skip_input_indices, forward_pass_name_scope)\u001b[0m\n\u001b[0;32m 144\u001b[0m \u001b[0mgradient_name_scope\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"gradient_tape/\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 145\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mforward_pass_name_scope\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 146\u001b[0m \u001b[0mgradient_name_scope\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[0mforward_pass_name_scope\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;34m\"/\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 147\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mname_scope\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgradient_name_scope\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 148\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mgrad_fn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmock_op\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0mout_grads\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 149\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 150\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mgrad_fn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmock_op\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0mout_grads\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\ops\\math_grad.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(op, grad)\u001b[0m\n\u001b[0;32m 175\u001b[0m \u001b[0mnew_shape\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconstant_op\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconstant\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mrank\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mdtypes\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mint32\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 176\u001b[0m \u001b[0mctx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mones_rank_cache\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrank\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnew_shape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 177\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 178\u001b[0m \u001b[0mnew_shape\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mrank\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 179\u001b[1;33m \u001b[0mgrad\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0marray_ops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrad\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnew_shape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 180\u001b[0m \u001b[1;31m# If shape is not fully defined (but rank is), we use Shape.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 181\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mNone\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0minput_0_shape\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 182\u001b[0m \u001b[0minput_shape\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mconstant_op\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconstant\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput_0_shape\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mdtypes\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mint32\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\ops\\weak_tensor_ops.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 86\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 87\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mis_auto_dtype_conversion_enabled\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 88\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 89\u001b[0m \u001b[0mbound_arguments\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0msignature\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbind\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 90\u001b[0m \u001b[0mbound_arguments\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapply_defaults\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 91\u001b[0m \u001b[0mbound_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mbound_arguments\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marguments\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\util\\traceback_utils.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 151\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 152\u001b[0m \u001b[0mfiltered_tb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_process_traceback_frames\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__traceback__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 153\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwith_traceback\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfiltered_tb\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 154\u001b[0m \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 155\u001b[1;33m \u001b[1;32mdel\u001b[0m \u001b[0mfiltered_tb\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\util\\dispatch.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 1257\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1258\u001b[0m \u001b[1;31m# Fallback dispatch system (dispatch v1):\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1259\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1260\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mdispatch_target\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1261\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mTypeError\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1262\u001b[0m \u001b[1;31m# Note: convert_to_eager_tensor currently raises a ValueError, not a\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1263\u001b[0m \u001b[1;31m# TypeError, when given unexpected types. So we need to catch both.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1264\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdispatch\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mop_dispatch_handler\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\ops\\array_ops.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(tensor, shape, name)\u001b[0m\n\u001b[0;32m 195\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 196\u001b[0m \u001b[0mReturns\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 197\u001b[0m \u001b[0mA\u001b[0m \u001b[1;33m`\u001b[0m\u001b[0mTensor\u001b[0m\u001b[1;33m`\u001b[0m\u001b[1;33m.\u001b[0m \u001b[0mHas\u001b[0m \u001b[0mthe\u001b[0m \u001b[0msame\u001b[0m \u001b[0mtype\u001b[0m \u001b[1;32mas\u001b[0m \u001b[1;33m`\u001b[0m\u001b[0mtensor\u001b[0m\u001b[1;33m`\u001b[0m\u001b[1;33m.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 198\u001b[0m \"\"\"\n\u001b[1;32m--> 199\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgen_array_ops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mshape\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 200\u001b[0m \u001b[0mshape_util\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmaybe_set_static_shape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mshape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 201\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
- "\u001b[1;32mc:\\Users\\Public\\anaconda3\\envs\\.venv\\Lib\\site-packages\\tensorflow\\python\\ops\\gen_array_ops.py\u001b[0m in \u001b[0;36m?\u001b[1;34m(tensor, shape, name)\u001b[0m\n\u001b[0;32m 10882\u001b[0m \u001b[0m_ctx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"Reshape\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtensor\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mshape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10883\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0m_result\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10884\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0m_core\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_NotOkStatusException\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10885\u001b[0m \u001b[0m_ops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mraise_from_not_ok_status\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0me\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m> 10886\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[0m_core\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_FallbackException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 10887\u001b[0m \u001b[1;32mpass\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10888\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10889\u001b[0m return reshape_eager_fallback(\n",
- "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
- ]
+ "data": {
+ "image/png": "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7b56rQl6qbmkARERUU2j9wnxqHwd/F3ValfL2lzPlRAREVV/DDK6pu6wFw6PISIiemYMMjp2+26hTtsRERFRxdQKMrm5ufquo9pQ986lq7fz9VwJERFR9adWkHFwcEBGRgYAoEOHDsjOztZnTUYtxNsRbnZPH/+y/lgKSp42ex4RERE9kVpBxsbGBnfu3AEA7N27F8XFT769uCaTSSWICKn31HapOQU4mpxZCRURERFVX2rNIxMeHo4XX3wRDRs2BAD06dMHZmZm5bbdvXu37qozUl61rNVqx1WwiYiIno1aQWbNmjVYtWoVrly5gn379qFRo0awsrLSd21GS91bq3kLNhER0bNRK8hYWlrinXfeAQAcP34cc+fOhb29vT7rMm68BZuIiKhSaHz79Z49e5QhRgiBaj4xsFbUvbU65kK6nishIiKq3rSaR2b16tUICgqCpaUlLC0t0bhxY/z0008aH2fGjBmQSCQqD39/f+X+goICjB49Gk5OTrCxsUG/fv2Qnl71P/w1WTySdy4RERFpT+Mgs2DBAowaNQovv/wyoqOjER0djS5duuCdd97BwoULNS6gUaNGSE1NVT4OHjyo3Ddu3Dhs2bIFGzduxL59+3Dz5k307dtX49eobKWLRz5N6eKRREREpB21V78utWjRIixZsgSDBw9WbuvZsycaNWqEGTNmYNy4cZoVYGICNze3MttzcnLwww8/4Oeff0aHDh0AACtWrEDDhg1x+PBhtGrVStPSK41MKkGv5z2w4tC1p7ZNy7lfCRURERFVTxr3yKSmpqJ169Zltrdu3RqpqakaF5CUlAQPDw/4+Phg4MCBSElJAQCcOHECxcXFCA8PV7b19/dHvXr1EBcXV+HxCgsLkZubq/IwhDoO6t3VlXmvSM+VEBERVV8aB5n69esjOjq6zPYNGzbAz89Po2O1bNkSK1euxLZt27BkyRIkJyejbdu2yMvLQ1paGszMzMrcHeXq6oq0tLQKjxkVFQW5XK581K1bV6OadMXRRr1bq29ks0eGiIhIWxpfWpo5cyYGDBiA/fv3IywsDAAQGxuLmJiYcgPOk3Tt2lX598aNG6Nly5bw9PREdHQ0LC0tNS0NADB58mRERkYqn+fm5hokzLjZqTfg949TN/FxtwDIpLwXm4iISFMa98j069cPR44cQa1atbB582Zs3rwZtWrVwtGj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REaLQYaIiIiMFoMMERERGS0GGS19++238PLygoWFBVq2bImjR48auiSjEhUVhRYtWsDW1hYuLi7o3bs3EhMTVdoUFBRg9OjRcHJygo2NDfr164f09HSVNikpKejWrRusrKzg4uKCDz/8EA8ePKjMt2JU5syZA4lEgrFjxyq38Tzrxr///otBgwbByckJlpaWCAoKwvHjx5X7hRCYNm0a3N3dYWlpifDwcCQlJakcIzMzEwMHDoSdnR3s7e0xfPhw3L17t7LfSpVVUlKCqVOnwtvbG5aWlvD19cWnn36qshYPz7N29u/fjx49esDDwwMSiQSbN29W2a+r83rmzBm0bdsWFhYWqFu3Lj7//PNnL16QxtavXy/MzMzEjz/+KBISEsTbb78t7O3tRXp6uqFLMxqdO3cWK1asEOfOnROnTp0SL7/8sqhXr564e/euss0777wj6tatK2JiYsTx48dFq1atROvWrZX7Hzx4IAIDA0V4eLg4efKk+Ouvv0StWrXE5MmTDfGWqryjR48KLy8v0bhxY/HBBx8ot/M8P7vMzEzh6ekphg4dKo4cOSL++ecfsX37dnH58mVlmzlz5gi5XC42b94sTp8+LXr27Cm8vb3F/fv3lW26dOkinn/+eXH48GFx4MABUb9+fREREWGIt1QlzZo1Szg5OYmtW7eK5ORksXHjRmFjYyO++uorZRueZ+389ddfYsqUKWLTpk0CgPjtt99U9uvivObk5AhXV1cxcOBAce7cObFu3TphaWkpvvvuu2eqnUFGCyEhIWL06NHK5yUlJcLDw0NERUUZsCrjlpGRIQCIffv2CSGEyM7OFqampmLjxo3KNhcuXBAARFxcnBDi4T88qVQq0tLSlG2WLFki7OzsRGFhYeW+gSouLy9P+Pn5iZ07d4r27dsrgwzPs2589NFHok2bNhXuVygUws3NTcybN0+5LTs7W5ibm4t169YJIYQ4f/68ACCOHTumbPP3338LiUQi/v33X/0Vb0S6desm3nzzTZVtffv2FQMHDhRC8DzryuNBRlfndfHixcLBwUHl/42PPvpIPPfcc89ULy8taaioqAgnTpxAeHi4cptUKkV4eDji4uIMWJlxy8nJAQA4OjoCAE6cOIHi4mKV8+zv74969eopz3NcXByCgoLg6uqqbNO5c2fk5uYiISGhEquv+kaPHo1u3bqpnE+A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",
+ "text/plain": [
+ "