Kuvitteellisen epidemian malli

Tekemäni mallin antamia tuloksia.

sairastuneet

sairastuneet

Oireettomat tartunnan saaneet kulkevat 'vapaana': "Vähän köhää, ei haittaa menoa." Oireettomat levittämät tautia. Oireettomien määrästä ei ole tilastotietoa.

Havaitut tartunnan saaneet ovat karanteenissa joko kotona tai sairaalahoidossa. Eivät levitä tautia. Karanteenissa olijoiden määrä tilastoidaan päivittäin.

Mitään testauksia ei tehdä.

Vaikka malli ei vastaa mitään todellista epidemiaa, tuloksista näkyy epidemioille tyypillinen piirre: Epidemia leviää eksponentiaalisesti, ellei laumasuoja tai ihmisten käytös pysäytä sen leviämistä, jolloin se alkaa hiipua eksponentiaalisesti.

Toinen yleinen piirre on, että rajoitustoimenpiteiden alettua havaittujen sairaustapausten määrä saattaa vielä nousta. Sairastunut levittää tautia tartunnan jälkeen ennen kuin oireet alkavat ja jos vakavat oireet kehittyvät vähitellen, sairaalaan joudutaan monen päivän, ehkä viikon parin viiveellä.

Vastaavasti epidemian hidastuminen näkyy viiveellä.

immuunit

Sekä 'oireettomasti' sairastaneet että karanteenissa olleet saavat immuniteetin joksikin aikaa.

Sisällysluettelo

Tämän jutun lähtökohta ja tarkoitus

Tämä juttu ei ole tiedettä eikä perustu epidemiologian asiantuntemukseen. Kirjallisuuskatsauksen sijaan surfailin netissä ja vilkuilin kiinnostavan näköisiä artikkeleita.

Lukaisin wikipediasta jutun epidemioiden mallintamisesta ja tein sen innoittama yksinkertaisen mallin, jonka avulla voin tarkistaa ja selittää omia uskomuksiani epidemioista ja niiden mallintamisesta. Uskomukset konkretisoituvat, kun verryttelee ajatuksiaan vaikka yksinkertaisenkin mallin kanssa leikkimällä.

Luulojaan ja uskomuksiaan on helpompi arvioida ja niistä on helpompi keskustella, kun ne kirjoittaa auki matemaattiseen muotoon ja simuloi niiden seurauksia muutenkin kuin päässälaskuna tai intuition varaisesti luulemalla.

Tämä juttu ei siis ole koko totuus — jos totuus ensinkään — epidemioista ja niiden mallintamisesta. Enintään minun totuuteni.

Paremmin epidemian leviämistä havainnollistaisi hyvin tehty pelintapainen agenttimalli, jossa simuloidaan vaikkapa muutaman tuhannen olion liikkeitä ja kohtaamisia. Sellaiseen malliin on helppo sisällyttää monenlaisia olioiden käyttäytymisen ja epidemioiden tyypillisiä piirteitä.

Työlästä toki olisi saada olioiden käytös vastaamaan kvantitatiivisesti tosimaailman ihmisten käyttäytymistä niin tarkasti, että mallilla olisi varsinaista ennustearvoa, mutta jo oikeansuuntainen kvalitatiivinen näkemys ilmiöstä auttaa tekemään parempia johtopäätöksiä.

Kokeilemalla eri strategioita epidemian hillitsemiseksi pelaaja saisi kuitenkin tuntumaa epidemioiden perusluonteeseen. Pelaaminen parantaisi ihmisten mieleensä luomia kuvitelmia ja uskomuksia — ajatusmalleja — epidemioista.

Omaa agenttimalliani en kehittänyt kiehtovaksi peliksi saakka enkä muutenkaan kovin pitkälle ja sen 'dokumentointikin' jäi kevyeksi pakinaksi. On siinä silti peruasioita kvalitatiivisesti kohdallaan.

Python-ohjelman alustuksia

Tämä juttu on samalla python-kielinen ohjelma, joten yksikään rivi mallistani ei jää pimentoon.

Ohjelmoinnista kiinnostuneille: Sovellan symbolista ja numeerista laskentaa. Kuvaajien piirtämiseen en satsannut yhtään ylimääräistä.

Symbolisen laskennan sympy modulille pitää kertoa, mitkä muuttujat ja funktiot ovat symbolisia.

Malliyhtälöt

Tartunnalle alttiit

$ N: $ Väestön suuruus

$ S(t): $ Hetkellä $t$ tartunnalle alttiiden lukumäärä

$ I(t): $ Oireettomat sairaat, jotka voivat tartuttaa muita

$ R(t): $ Parantuneet. Ovat aluksi immuuneja

$ \lambda_{RS} $: vauhti, jolla immuniteetti häviää ja parantuneet tulevat uudestaan alttiiksi tartunnalle

$ \beta: $ 'Todennäköisyys' tartunnalle. Riippuu osin viruksen ominaisuuksista, osin ihmisten käyttäytymisestä. Rajoituksilla vaikutetaan tähän.

Tartunnat

$ \lambda_{I}: $ 'Vauhti', jolla oireettomat parantuvat. Keskimääräisen sairauden keston käänteisluku.

$ \lambda_{IQ}: $ 'Vauhti', jolla oireettomia saadaan karanteeniin.

Malliin voisi lisätä ulkopuolelta tulevan taudinkantajien virran.

Sairaalaan tai karanteeniin joutuneet

$ Q(t): $ Sairastuneet, jotka ovat karanteenissa joko kotonaan tai sairaalahoidossa

$ \lambda_Q: $ 'Vauhti', jolla karanteenista tai sairaalasta vapaudutaan. Keskimääräisen sairauden keston käänteisluku.

Tällaista ryhmää ei wikipedian esittelemissä malleissa ollut. Ainakin covid19-pandemiassa tyypillistä on, että moni sairastaa taudin huomaamattaan, mutta tartuttaa kuitenkin muita. Minun mallissani I edustaa heitä ja Q edustaa karanteeniin ja tautitilastoon päässeitä.

Ryhmän I suuruutta tietyllä hetkellä voidaan arvioida positiivisten testien perusteella, mikäli testaukset suunnataan tilastollisesti edustavasti. Käytännössä testaus suunnataan vaikuttavuuden perusteella, joten testitulosten perusteella ei voi päätellä sairastuneiden kokonaismäärää.

Jälkikäteen oireettomien osuutta voidaan arvioida vasta-ainetestien perusteella. En tiedä, miten tarkasti.

Tässä jutussa oletukseni on, että mitään testauksia ei tehdä.

Parantumiset

Mallissani kaikki parantuvat ja tulevat immuuneiksi. Immuniteetti ei kuitenkaan ole pysyvä, vaan kerran sairastuneet tulevat vähitellen uudelleen altiiksi taudille.

$ R(t) $: Parantuneet

Tartuttavuus ja sen hallinta

Rajoitustoimet eivät todellisuudessa vaikuta silmänräpäyksessä, joten suodatan rajoitusten aiheuttamaa tarttuttavuuden $\beta_0$ muutosta.

Käytännön merkitystä tällä ei liene, mutta simuloinnin tulokset näyttivät hassuilta, kun epidemian jyrkkä kasvu kääntyi hetkessä jyrkäksi laskuksi.

Puutteita

Malli olettaa, että kenen hyvänsä kahden ihmisen tartuntaan johtava kohtaaminen on yhtä todennäköistä. Todellisuudessa kohtaamiset riippuvat asuinpaikasta, iästä, työstä, harrastuksista, ... Epidemia ei leviä tasavauhtia koko väestöön ja usein esiintyy jollain seudulla tai jossain erityisryhmässä tartuntaryppäitä.

R:n, I:n ja Q:n pitäisi siis olla jakaumia tai jaettuna useaan ryhmään. Webistä löytyy monenlaisia malleja, joissa tällaista on kokeiltu. Sellaisen kokeilu ei kuulu tämän jutun piiriin.

Agenttimallissa, jossa simuloidaan erikseen tuhansien olioiden 'elämää', tulee automaattisesti erille sijainnin ja liikkumisen vaikutus. Olioille on myös helppo antaa erilaisia ominaisuuksia niin, että ne edustavat eri ryhmiä.

Numeerinen simulointi

Mallini on differentiaaliyhtälöryhmä. Simulointi tarkoittaa differentiaaliryhmän ratkaisemista. Poikkeustapauksissa differentiaaliyhtälöryhmälle löytyy analyyttinen ratkaisu, mutta yleensä pitää tyytyä numeeriseen ratkaisemiseeen.

Periaate

Differentiaaliyhtälön $ \frac{d}{dt}y(t) = f(y(t), u(t), t) $ numeerista ratkaisua varten tarvitaan funktio f(y, u, t), joka laskee derivaatan arvon. Sen jälkeen simulointi tehdään seuraavasti:

Tf =  # simuloinnin loppuaika
dt =  # Integroinnin aika-askel
u =   # Parametreja ja ohjauksia, voivat olla ajan funktioita
N = int(Tf/dt) # Integrointiaskelten lukumäärä
# taulukko, johon talletetaan simuloinnin tulos ajan funktiona
yy = [0 for i in range(N)]
y[0] = y0

for i in range(N)
    t = i*dt
    u = laske_u(y(t), t)  # jos u ei ole vakio vaan riippuu y:stä ja t:stä
    y[i+1] = rk4(f, y[i], u, dt)

Differentiaaliyhtälöiden numeeriseen ratkaisemiseen tarvitaan integrointirutiini. Niitä on valmiina, mutta kun en heti onnistunut niitä soveltamaan käytin omaa, kauan sitten uteliaisuudesta koodaamaani Runge-Kutta rutiinia.

Funktio epidemian simulointiin

Vilkaistaan uudestaan epidemiayhtälöitäni ja 'copy-pastetaan' niistä simuloinnissa tarvittava funktio

Epidemian simulointi

'Strategia' pandemian hillitsemiseen

Seuraava 'viranomainen' muuttelee parametriä $\beta_0$, joka kuvaa tartuntojen todennäköisyyttä.

Alussa epidemian annetaan levitä, kunnes self.ylim osa väestöstä on sairaana, jolloin epidemiaa aletaan hillitä rajoitustoimin niin, että altistusten määrä vähenee perusarvosta self.ry = r0 arvoon self.ra1.

Rajoitustoimista luovutaan, kun sairastuneiden määrä on laskenut self.alim osaan väestöstä.

Toistetaan sama rajoituksella self.ra2.

Toisen aallon jälkeen luovutaan rajoituksista ja annetaan epidemian levitä vapaasti, kunnes saavutetaan laumasuoja, joka sekin vähitellen häviää ja tulee seuraava aalto.

Funktio kuvaajien piirtämiseen

Funktio, jolla piirretään epidemian etenemistä tietyllä aikavälillä havainnollistavat kuvaajat.

Simuloinnin tuloksia

koko kausi

Epidemiat ovat epästabiileja ilmiöitä, jotka joko leviävät tai taantuvat eksponentiaalisesti.

Ensimmäinen aalto

Toinen aalto

Mallin parametrien estimointi

Ydinvoimaloista voidaan tehdä tarkkoja malleja fysiikan lakien perusteella. Meteorologian ilmiöistäkin voidaan tehdä tarkkoja malleja luonnonlakien perusteella. Esimerkiksi kaikki mallinnuksessa tarvittavat vesihöyryn ominaisuudet on selvitetty kokeellisesti aika päiviä sitten.

Viruksen — erityisesti uudenlaisen viruksen — käyttäytymisestä ei ole tarkkoja tietoja. Kaikki epidemiat leviävät jossain määrin samantyyppisesti, mutta toiset tarttuvat paljon toisia herkemmin ja tartuntamekanismit ovat erilaisia. Toisista parantuu nopeammin, toisista hitaammin. Toiset tappavat herkemmin kuin toiset. Joillekin tulee immuuniksi, toisille ei.

Epidemian leviäminen riippuu ihmisten käytöksestä. Sen vaikutusta on vaikea mallintaa varsinkin, jos väestöllä ei ole aiempaa kokemusta vastaavasta. Epidemian kestäessä ihmisten käytös muuttuu. Epidemioita ei siis voi mallintaa tarkasti luonnonlakien pohjalta.

(Talous on muuten pitkälti ihmistiede. Silti taloudesta on onnistuttu laatimaan hyödyllisiä malleja. Olisi toki hyvä tietää, mihin talousmallit perustuvat.)

Epidemioista kannattaa tehdä melko yksinkertainen malli, joka kuvaa epidemioiden tyyppilliset peruspiirteet ja sitten sovittaa mallin parametrit kulloisenkin epidemian etenemisestä kerättyyn dataan.

Jos mallin saa sovitettua kohtuullisen hyvin dataan, sillä voi ennustaa lähitulevaisuutta olettaen, ettei virus eikä väestön käytös isommin muutu.

Parametrien estimointia kannattaa tehdä jatkuvasti sekä tuoreinta että pitkän aikavälin dataa käyttäen. Jos ennustevirhe alkaa kasvaa voi arvella tilanteen muuttuneen ja mallin ennustearvon huonontuneen. Estimoimalla parametreja eri ajanjaksoilta, voi saada tunnuslukuja erilaisten rajoitustoimien vaikutuksesta. Näkeehän sen datasta suoraankin, mutta parametrien estimointi voi antaa lisävihjeitä rajoitusten vaikutuksesta.

Jos malliin lisäisi parametrin kuvaamaan ulkopuolelta tulevien tartuttajien virtaa, parametrien estimaateista voisi ehkä päätellä, johtuuko tartuntojen lisääntyminen tai vähentyminen 1) viruksen ja ihmisten käytöksen muutoksesta vai 2) ulkopuolelta tulevan virran muutoksesta. Mallin pitäisi rakenteltaan vastata melko hyvin epidemiaa ja estimointivirheen pitäisi olla pieni.

Parametrien estimoinnin perusidea

Parametrien estimointi on oma tieteen — vähän taiteenkin — -alansa. Käytän ns. härmäläistä lähestymistapaa periaatteen havainnollistamiseksi.

Arvelemme, että sairastuneiden määrä noudattaa yhtälöä $ \frac{d}{dt}y(t) = f(\theta, y(t), u(t), t) $

Merkitään tilastoitua sairastuneiden määrää hetkellä $ t=k \cdot dt $ seuraavasti $ y_m(k dt) = y_m(k)$

Malliyhtälön voidaan ennustaa suurinpiirtein oikein yhden aika-askelen päähän: $ y_e(k+1) = y_m(k) + f(\theta, y_m(k), u(k), k) dt $

Summataan ennustevirheiden neliöt $$ e² = \sum_{k=k_0}^{k_f} (y_m(k+1) - y_e(k+1))^2 = \sum_{k=k_0}^{k_f} (y_m(k+1) - (y_m(k) + f(\theta, y_m(k), u(k), k) dt))^2 $$ Paras parametrien arvo löytyy derivoimalla ennustevirheen neliö $ \theta$:n suhteen ja ratkaisemalla derivaatan 0-kohta.

Ennuste yhden aika-askeleen päähän

Kirjoitetaan funktio estep(), joka kertoo epidemiamallini muuttujien muutoksen yhdellä aika-askelella.

Korvataan $S(t)$ muuttujalla Se ja samoin muut niin selvitään myöhemmin vähemmällä käsityöllä.

Sijoitetaan tunnetuilla parametreille numeroarvot. Estimoimalla ei kannata yrittää hakea arvoa parametrille, jonka muutenkin tietää. Mitä monimutkaisempi malli ja mitä enemmän parametreja, sen paremmin se sopii tilastoituun dataan, mutta sitä vähemmän voi luottaa siihen, että se ennustaa kelvollisesti tulevaisuutta.

Kun mallin muuttujilla, parametreillä ja yhtälöillä on järkeenkäypä tulkinta eikä parametrejä ole tolkuttoman montaa, estimoimmin voi toivoa löytävän jotain oikeasti oleellista.

Tulostetaan yhtälöt ja copy-pastetaan funktionestep() sisuksiin

Ennustevirheen neliö välillä T0 — Tf

Fuskaan pikkuisen. Oletan muuttujien arvot hetkellä T0 tunnetuiksi,vaikka alussa tekemäni oletuksen mukaan tilastotietoa on vain karanteenissa olevista. Muuttujien arvot hetkellä T0 voisi estimoida samalla kun parametritkin, mutta se vaatisi pikkuisen koodaamista.

Koska kukaan ei kuole eikä lapsia synny eikä kukaan kulje rajan yli, pätee $ N = S(t) + I(t) + Q(t) + R(t) $. Lisäsin minimoitavaksi termin $ \sum_{k=k_0}^{k_f}(N - (S(k) + I(k) + Q(k) + R(k)))²$, koska arvelin sen helpottavan numeerisen minimoinnin algoritmia. (En kuitenkaan jaksanut kunnolla kokeilla, mikä sen vaikutus on.)

Ennustevirheen minimointi parametrien suhteen

Numeerinen minimointi vaatii alkuarvauksen estimoitaville parametreille. Käytin arvoja, jotka ovat lähellä simuloinnissa käyttämiäni. Vähän fuskua sekin.

Systemaattisesti en alkuarvauksen vaikutusta selvitellyt, mutta eri alkuarvauksilla todennäköisesti tulee jonkin verran erilaisia tuloksia, koska käytän parametrien estimointiin ainoana 'tilastotietona' karanteeniin päätyneiden määrää. Suurin piirtein samanlaiseen karanteenipotilaiden määrään voidaan päätyä pienellä tai isolla oireettomien määrällä.

Esimerkiksi oireettomien ja havaittujen suhteesta pitäisi olla jotain lisätietoa, että parametrien estimointi toimisi 'vakaammin'.

Estimoinnin tuloksia

Huomioita

Koska käytin 'mittausdatana' samanalaisella mallilla luotua dataa kuin mitä käytin estimoinnin pohjana, tuloksesta ei voi päätellä muuta kuin, että algoritmissani ei ole varsinaisia virheitä.

Mallini ja algoritmieni heikkoudet tulisivat esille, jos kaivaisin käyttööni todellista dataa covid-19 pandemiasta ja yrittäisin sovittaa malliani siihen. Siinä vaiheessa tämä puuha muuttuisi huvista työksi. Turhaksi työksi. Maailmalla näyttää tehdyn riittävän paljon työtä epidemiasta kertyvän datan hyödyntämiseen.

Linkkejä

Tämä notebook | Agenttimallini | Etusivulle