{ "cells": [ { "cell_type": "markdown", "source": [ "# Calcola il tasso di crescita λ e lo rappresenta graficamente\r\n", "\r\n", "*Per determinare il tasso di crescita λ viene innanzitutto linearizzata la relazione esponenziale che lo coinvolge nel modello sviluppato. Su tale base si calcola il suo valore giornaliero e per rirdurre i fattori di disturbo, si esegue una media mobile di 14 giorni.* " ], "metadata": {} }, { "cell_type": "markdown", "source": [ "Carica i moduli necessari" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "import json\r\n", "import matplotlib.pyplot as plt\r\n", "import numpy as np\r\n", "from scipy.stats import linregress\r\n", "import datetime" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "La funzione `partiziona()` partiziona `xDati` in un array di array. Ciascun elemento ha lunghezza `intervalloGiorni` e il loro numero è pari a `n-intervalloGiorni+1`." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "def partiziona(xdati, intervalloGiorni):\r\n", " numElem = len(xdati)\r\n", " elementi = []\r\n", " for i in range(intervalloGiorni, numElem + 1):\r\n", " elementi = np.append(elementi, xdati[i-intervalloGiorni:i])\r\n", " return np.reshape(elementi, (numElem - intervalloGiorni + 1, intervalloGiorni))\r\n", "######### Predisposizioni ###############################################################################################" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Elementi da inserire in input per avviare l'elaborazione dei dati nazionali o regionali. Questi devono essere stati preventivamente memorizzati nella medesima cartella e devono corrispondere alla data immessa (avviare eventualmente il notebook `prelevaRinomina.ipynb`).
\r\n", "Si richiede inoltre l'unità temporale da porre in ascissa." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "print()\r\n", "print(\"Si intendono elaborare i nuovi positivi nazionali (i) o quelli di una regione (r)? \")\r\n", "scelta = input(\" :> \")\r\n", "print(\"Inserire la data nel formato (YYYMMDD) \")\r\n", "dataISO = input(\" :> \")\r\n", "print(\"Si vuole l'asse temporale espresso in mesi (m) o in giorni trascorsi (g) dall'inizio pandemia? \")\r\n", "unitaAssex = input(\" :> \")" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Vengono composti i nomi dei file e, una volta letti i dati contenuti, questi vengono caricano nell'array `nuoviPositivi`." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "if scelta == \"i\":\r\n", " regioneScelta = \"ITALIA\"\r\n", " nomeFile = 'datiNazionali' + dataISO\r\n", " # lettura del file csv: la colonna 8 corrisponde al campo nuovi_positivi\r\n", " nuoviPositivi = np.genfromtxt(nomeFile + '.csv', delimiter=',', skip_header=1, usecols=8, dtype=int)\r\n", "else:\r\n", " print(\"Inserire la regione \")\r\n", " regioneScelta = input(\" :> \")\r\n", " regioneScelta = regioneScelta.lower().capitalize()\r\n", " nomeFile = 'datiRegionali' + dataISO\r\n", " # lettura del file json e riportato l'array ad un array di Numpy\r\n", " with open(nomeFile + '.json') as f:\r\n", " datiGrezzi = json.load(f)\r\n", " nuoviPositivi = []\r\n", " for record in datiGrezzi:\r\n", " if record['denominazione_regione'] == regioneScelta:\r\n", " nuoviPositivi.append(record['nuovi_positivi'])\r\n", " nuoviPositivi = np.array(nuoviPositivi)" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Dovendo calcolare il logaritmo dei `nuoviPositivi` nel caso vi sia un valore giornaliero nullo (per cui il suo logaritmo non avrebbe significato), lo si pone pari ad 1. L'array `giorniDelFit` rappresenta i giorni nei quali si eseguirà il fit lineare." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "nuoviPositivi[nuoviPositivi == 0] = 1\r\n", "logPositivi = np.log(nuoviPositivi)\r\n", "numGiorni = len(nuoviPositivi)\r\n", "intervalloGiorni = 14\r\n", "# i giorni da 0 a 13 nel quale viene eseguito il fit\r\n", "giorniDelFit = np.arange(0, intervalloGiorni, 1)" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Per ognuno degli intervalli in cui è stato partizionato l'insieme dei `logPositivi`, viene eseguita una regressione lineare in un intervallo temporale di 14 giorni. Della retta ottimale si determina la sola pendenza in quanto questo è il termine associato, nel modello teorico, al parametro λ (o *tasso di crescita*)." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "valoriLambdaLin = []\r\n", "for i in range(intervalloGiorni, numGiorni+1):\r\n", " # fit lineare\r\n", " esito = linregress(giorniDelFit, logPositivi[i-intervalloGiorni:i])\r\n", " valoriLambdaLin = np.append(valoriLambdaLin, esito.slope)" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Per ridurre i fattori giornalieri o settimanali di distrurbo, si esegue una media mobile su un intervallo di 14 giorni dei valori giornalieri di λ." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "media14Giorni = np.mean(partiziona(valoriLambdaLin, intervalloGiorni), axis=1)" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Parte grafica comune e parte dipendente dalle scelte iniziali. Le variabili temporali `date1`, `date2` come le precedenti `xValoriMediGiornalieri` e `xMediaMobile`, tutte associate all'asse x, controllano la traslazione temporale dei valori in ordinata e sono scelte in modo da ottenere un accordo visivo soddisfacente con i dati giornalieri e in coerenza con il sito [CovidStat](https://covid19.infn.it/)." ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# parte comune\r\n", "codificaItaliana = dataISO[6:] + '-' + dataISO[4:6] + '-' + dataISO[:4]\r\n", "plt.rcParams['figure.figsize'] = [12, 6]\r\n", "fig, ax = plt.subplots()\r\n", "ax.grid(which='both', color='.85', linestyle='-', linewidth=1)\r\n", "ax.set_ylabel('tasso di crescita λ (1/giorni)')\r\n", "ax.set_title(regioneScelta + \": tasso di crescita giornaliero λ (regressione lineare)\\ne media mobile su 14 giorni\")\r\n", "# parte variabile\r\n", "if unitaAssex == \"m\":\r\n", " date1 = [datetime.date(2020, 3, 1) + datetime.timedelta(days=int(intervalloGiorni/2)) + datetime.timedelta(days=i)\r\n", " for i in range(numGiorni-intervalloGiorni+1)]\r\n", " ax.scatter(date1, valoriLambdaLin, s=4, label='λ giornaliero', zorder=3)\r\n", " date2 = [datetime.date(2020, 3, 8) + datetime.timedelta(days=int(intervalloGiorni/2)) + datetime.timedelta(days=i)\r\n", " for i in range(numGiorni-intervalloGiorni-12)]\r\n", " ax.plot(date2, media14Giorni, color='tomato', linewidth=2, label='media mobile λ su 14 giorni', zorder=4)\r\n", " ax.set_xlabel('date dal 24 febbraio 2020')\r\n", " ax.text(datetime.date(2020, 5, 13), 0.16, 'aggiornato il\\n' + codificaItaliana)\r\n", "else:\r\n", " xValoriMediGiornalieri = np.arange(intervalloGiorni-1, numGiorni)\r\n", " xMediaMobile = np.arange(intervalloGiorni+5, numGiorni-intervalloGiorni/2)\r\n", " ax.scatter(xValoriMediGiornalieri, valoriLambdaLin, s=4, label='λ giornaliero', zorder=3)\r\n", " ax.plot(xMediaMobile, media14Giorni, color='tomato', linewidth=2, label='media mobile λ su 14 giorni', zorder=4)\r\n", " ax.text(85, 0.16, 'aggiornato il\\n' + codificaItaliana)\r\n", " ax.set_xlabel('giorni dal 24 febbraio 2020')\r\n", " x_major_ticks = np.arange(0, numGiorni+20, 20)\r\n", " ax.set_xticks(x_major_ticks)\r\n", "\r\n", "plt.legend()\r\n", "plt.show()" ], "outputs": [], "metadata": {} } ], "metadata": { "orig_nbformat": 4, "language_info": { "name": "python", "version": "3.7.4", "mimetype": "text/x-python", "codemirror_mode": { "name": "ipython", "version": 3 }, "pygments_lexer": "ipython3", "nbconvert_exporter": "python", "file_extension": ".py" }, "kernelspec": { "name": "python3", "display_name": "Python 3.7.4 64-bit" }, "interpreter": { "hash": "0600588c3b5f4418cbe7b5ebc6825b479f3bc010269d8b60d75058cdd010adfe" } }, "nbformat": 4, "nbformat_minor": 2 }