Agent-baseret SIR simulation i Python

I denne artikel implementerer jeg en SIR-model i Python ved hjælp af et bibliotek, som jeg udviklede til agentbaseret modellering i Python. Med andre ord bruger jeg en eksisterende ramme til at implementere en agent-baseret SIR-model.

Introduktion af agentbaseret SIR-model

SIR står for modtagelig , inficeret og genvundet . Som illustreret i nedenstående figur, i en SIR-model, kan agenter opleve følgende tilstandsovergange: Fra modtagelig til inficeret, fra inficeret til genoprettet og fra genoprettet til modtagelig.

generel sir model

Tilstandsovergangene illustreret i ovenstående figur er normalt implementeret med en tilfældig fordeling og en vis specificeret sandsynlighed. Desuden behøver du ikke at tillade alle statsovergange. I denne artikel vil jeg for eksempel ikke tillade, at agenter falder tilbage fra deres genoprettede tilstand til en modtagelig tilstand. Nedenfor er SIR-modellen implementeret i denne artikel.

sir model brugt til denne artikels agent-baserede sir model

På samme måde kunne du også formulere en SIR-model, hvor du giver mulighed for at falde tilbage fra genoprettet tilstand til inficeret tilstand, ikke kun den modtagelige tilstand.

Agentbaseret modelleringsramme i Python

Jeg lavede en ramme for agent-baseret modellering. Rammerne er beregnet til at blive udvidet og opgraderet over tid. Det understøtter i øjeblikket en opsætning, der gør det muligt at placere agenter, simuleringsmiljø og populationer i en grid-baseret model. Simuleringsresultater kan skrives ind i en SQLite-database i standardiseret format, og visualiseringer og animationer genereres baseret på de data, der er gemt i den pågældende database. Rammen kommer i form af flere Python-filer (moduler), der kan redigeres for at tilføje brugerdefineret funktionalitet.

ramme for agent-baseret sir model

Hvis du vil tjekke rammerne ud, kan du følge den på GitHub . Her er linket:

Den særlige ting at bemærke her er, at rammen understøtter grid-baseret agent-baseret modellering. Agenter interagerer i et 2D-gitter. Dette 2D-gitter letter simuleringsmiljøet. En eller flere agenter kan være placeret i samme celle, afhængigt af modelindstillinger. Agenter kan interagere med andre agenter inden for et specificeret kvarter. I denne artikel refererer ineraktioner til sygdomsoverførsel, hvilket resulterer i sygdomsspredning.

gitter for denne artikels agent-baserede sir-model

Agenter har attributter og funktionalitet, repræsenteret ved indre dynamik, variabler og tilstande. En agents indre virke påvirker dens handlinger, beslutninger og interaktioner med andre agenter. Disse interaktioner kan også påvirkes af interaktionsmiljøet.

Jeg vil nu fortsætte med at dokumentere relevant ABM-modelimplementering i Python.

Implementering af den agent-baserede SIR-model i Python

I nedenstående kode gør jeg brug af den agent-baserede modelleringsramme. Jeg satte en simuleringskørsel op, der varer i 300 iterationer. Sandsynligheden for, at modtagelige agenser bliver inficeret, er 7 %, for hvert møde med et inficeret agens. For hver iteration har et inficeret agens på den anden side en 3% sandsynlighed for at komme sig.

__author__ = "Linnart Felkl"
__email__ = "LinnartSF@gmail.com"

if __name__ == "__main__":

    print("demo starts")

    import sys
    from pathlib import Path
    file = Path(__file__).resolve()
    parent, root = file.parent, file.parents[1]
    sys.path.append(str(root))

    # remove the current file's directory from sys.path, unless already removed
    try:
        sys.path.remove(str(parent))
    except ValueError:
        pass

    import data
    import stats
    import config
    import framework
    import random
    import animation

    # setup database manager and connection
    db = data.Database("sqlite3", config.path_databasefile)
    db_manager = data.Manager(db)

    # create an empty environment
    env = framework.Environment(1, True, 20, 20, db_manager) # Environment constructor implicitly resets environment table in database

    # create initial population of healthy humans
    pops = framework.Populations(amount = 1, env = env, db_manager = db_manager, attributes = ["infected","recovered"], datatypes = ["INTEGER","INTEGER"])
    pops.add_population(name = "humans", 
                        size = 200, 
                        attributes = ["infected","recovered"], 
                        datatypes = ["INTEGER","INTEGER"], 
                        initialvals = [0, 0]
                        )

    # randomly infect 5%
    pop = pops.Populations["humans"]
    sampleagents = pop.get_agents(int(0.05*pop.Size))
    for agent in sampleagents: agent.Attributes["infected"] = 1

    _prob_infection = 0.07
    _prob_recovery = 0.03
    
    # setup simulation
    sim = framework.Simulation(300)

    # make sure that environment and agents tables in database are setup at this time
    pops.write_env_to_db(sim.Iteration)
    pops.write_agents_to_db(sim.Iteration)

    # execute simulation run, store every 10th run into the database
    while sim.run():

        # look at every agent
        for agent in pop.get_agents():
            if agent.get_attr_value("infected") == 1:
                
                neighbours = env.get_neighbourhood(agent)
                for neighbour in neighbours:
                    if neighbour.get_attr_value("infected") == 0 and neighbour.get_attr_value("recovered") == 0:
                        
                        # this neighbour is not resistant and not infected; infect with specified probability
                        if random.uniform(0, 1) < _prob_infection: neighbour.set_attr_value("infected", 1)
            
                # the infected agent recovers with a specified probability
                if random.uniform(0, 1) < _prob_recovery: 
                    agent.set_attr_value("recovered", 1)
                    agent.set_attr_value("infected", 0)
                
        # update results in database, for agents and for environment
        pops.write_agents_to_db(sim.Iteration)
        pops.write_env_to_db(sim.Iteration)
        pops.write_density_to_db(sim.Iteration)

    # get dataframes with simulation results 
    humans_df = db_manager.get_populationdf(pop = "humans")
    env_df = db_manager.get_environmentdf()
    density_df = db_manager.get_densitydf()
    
    # visualize simulation data
    stats.set_fontsizes(8,10,12)

    stats.plot_agentattr_lines("infected", humans_df)
    stats.save_plot("infection_curves")
    
    stats.plot_agentattr_lines("recovered", humans_df)
    stats.save_plot("recovery_curves")

    stats.plot_grid_occupation(env_df, ["humans"])
    stats.save_plot("human_locations")

    stats.plot_density_markersize(density_df, "infected", 50, "red")
    stats.save_plot("infection_density")

    stats.plot_density_markersize(density_df, "recovered", 50, "green")
    stats.save_plot("recovery_density")

    stats.plot_avgattr_lines(["infected","recovered"], humans_df)
    stats.save_plot("avginfectedavgrecovered")

    # create and save animations
    animation.animate_density(
        df = density_df,
        filename = "infectionanimation",
        attr = "infected",
        defaultsize = 50,
        color = "red",
        tpf = 0.05
    )

    animation.animate_density(
        df = density_df,
        filename = "recoveryanimation",
        attr = "recovered",
        defaultsize = 50,
        color = "green",
        tpf = 0.05
    )

    # end program
    db.close()
    print("demo ends")

Ovenstående agentbaserede SIR-modelimplementering genererer resultater, der er gemt i en SQLite-database. Denne database bruges så senere til visualiseringer. Disse visualiseringer kan implementeres i et separat script, af en anden analytiker og på et andet tidspunkt. Dvs. modeludførelse og datavisualisering er to separate aktiviteter, der er afkoblet af databasen.

Agent-baserede SIR model simuleringsresultater

Jeg kan nu endelig gennemgå de resultater, der blev genereret af den grid-baserede agent-baserede SIR-model. Nedenfor er en visualisering af agentplaceringer i hele denne simuleringskørsel.

Nedenstående animation viser, hvilke midler der var inficeret gennem tiden. Animationen viser desuden agentplaceringer. I dette simple eksempel er agentplaceringerne statiske.

Dernæst en animation af agentgendannelse gennem simuleringstiden.

Nedenstående diagram visualiserer den gennemsnitlige sandsynlighed for, at et middel bliver inficeret eller genoprettet på det givne simuleringstidspunkt.

Agentgendannelse sikrer, at ikke alle midler er inficerede. Agenter i denne model har dog statiske placeringer. I en anden simuleringskørsel kunne vi tillade dynamiske agentplaceringer eller endda en form for diffusion/migrering. Dette vil højst sandsynligt øge den samlede mængde af midler, der er inficeret gennem simuleringskørslen.

Den agentbaserede modelleringsramme, der anvendes i denne artikel, kan levere yderligere diagrammer. Desuden forbliver simuleringsresultaterne gemt i en SQLite-database, der kan analyseres på enhver brugerdefineret måde. Dette ville dog kræve en vis yderligere tilpasning/tilpasning, dvs. kodning.

Afsluttende bemærkninger og relateret indhold

Agentbaseret simulering er en simuleringsmetode, der søger at forklare kompleks makroskopisk systemadfærd ved at beskrive agentdynamik og interaktioner på det mikroskopiske systemniveau. Det er en metode, der er ret abstrakt og ofte bruges til at forstå komplekse systemer. Komplekse systemer er, ja, mere komplekse end komplicerede systemer, og på den anden side mindre komplekse end kaotiske systemer. Den amerikanske økonomi, synlig på det makroskopiske plan i form af f.eks. bruttonationalproduktet, er et eksempel på et komplekst system. Agentbaserede modeller kan fx bruges til at forstå fremkomsten af ​​visse fænomener og tendenser i amerikansk økonomi.

I denne artikel implementerede jeg en for nylig meget populær model for sygdomsspredning. Dette er faktisk et andet interessant område, hvor agent-baseret modellering ofte anvendes. Ved at bruge en ramme for agent-baseret modellering implementerede jeg en agent-baseret SIR-model. Frameworkets visualiserings- og animationsfunktioner blev brugt til at gennemgå simuleringsresultater. Selve rammeværket kan bruges til at implementere andre typer Agent-baserede simuleringsmodeller – og rammeværket vil blive opgraderet og løbende udvidet over tid.

Her er nogle andre SCDA relateret til Agent-baseret simulering :

You May Also Like

Leave a Reply

Leave a Reply

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.