Neste artigo implemento um modelo SIR em Python, usando uma biblioteca que desenvolvi para modelagem baseada em agente em Python. Em outras palavras, eu uso uma estrutura existente para implementar um modelo SIR baseado em agente.
Apresentando o modelo SIR baseado em agente
SIR significa suscetível , infectado e recuperado . Conforme ilustrado na figura abaixo, em um modelo SIR, os agentes podem experimentar as seguintes transições de estado: De suscetível a infectado, de infectado a recuperado e de recuperado a suscetível.
As transições de estado ilustradas na figura acima são geralmente implementadas com uma distribuição aleatória e alguma probabilidade especificada. Além disso, você não precisa permitir todas as transições de estado. Neste artigo I, por exemplo, não permitirei que os agentes retornem de seu estado recuperado para um estado suscetível. Abaixo está o modelo SIR implementado neste artigo.
Da mesma forma, você também pode formular um modelo SIR no qual permita o retorno do estado recuperado para o estado infectado, não apenas o estado suscetível.
Estrutura de modelagem baseada em agente em Python
Criei um framework para modelagem baseada em agente. A estrutura deve ser expandida e atualizada ao longo do tempo. Atualmente suporta uma configuração que permite que agentes, ambiente de simulação e populações sejam colocados em um modelo baseado em grade. Os resultados da simulação podem ser gravados em um banco de dados SQLite em formato padronizado, e as visualizações e animações são geradas com base nos dados armazenados nesse banco de dados. A estrutura vem na forma de vários arquivos Python (módulos) que podem ser editados para adicionar funcionalidades personalizadas.
Se você quiser conferir o framework, você pode segui-lo no GitHub . Aqui está o link:
A coisa especial a ser observada aqui é que a estrutura suporta modelagem baseada em agente baseada em grade. Os agentes interagem em uma grade 2D. Esta grade 2D facilita o ambiente de simulação. Um ou vários agentes podem estar localizados na mesma célula, dependendo das configurações do modelo. Os agentes podem interagir com outros agentes dentro de uma determinada vizinhança. Neste artigo, as inerações referem-se à transferência de doenças, resultando na disseminação da doença.
Os agentes possuem atributos e funcionalidades, representados por dinâmicas internas, variáveis e estados. O funcionamento interno de um agente afeta suas ações, decisões e interações com outros agentes. Essas interações também podem ser influenciadas pelo ambiente de interação.
Agora vou continuar documentando a implementação relevante do modelo ABM em Python.
Implementando o modelo SIR baseado em agente em Python
No código abaixo, faço uso da estrutura de modelagem baseada em agente. Eu configurei uma simulação que dura 300 iterações. A probabilidade de agentes susceptíveis serem infectados é de 7%, para cada encontro com um agente infectado. Para cada iteração, um agente infectado, por outro lado, tem 3% de probabilidade de recuperação.
__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")
A implementação do modelo SIR baseado em agente acima gera resultados que são armazenados em um banco de dados SQLite. Esse banco de dados é posteriormente usado para visualizações. Essas visualizações podem ser implementadas em um script separado, por outro analista e em um momento diferente. Ou seja, execução de modelo e visualização de dados são duas atividades separadas que são desacopladas pelo banco de dados.
Resultados da simulação do modelo SIR baseado em agente
Agora posso finalmente revisar os resultados que foram gerados pelo modelo SIR baseado em agente baseado em grade. Abaixo está uma visualização das localizações dos agentes ao longo desta simulação.
A animação abaixo mostra quais agentes foram infectados ao longo do tempo. A animação também mostra as localizações dos agentes. Neste exemplo simples, as localizações dos agentes são estáticas.
A seguir, uma animação de recuperação do agente ao longo do tempo de simulação.
O gráfico abaixo mostra a probabilidade média de um agente ser infectado ou recuperado, no momento da simulação.
A recuperação do agente garante que nem todos os agentes sejam infectados. No entanto, os agentes neste modelo têm localizações estáticas. Em outra simulação, poderíamos permitir localizações dinâmicas de agentes, ou até mesmo algum tipo de difusão/migração. Isso provavelmente aumentaria a quantidade total de agentes infectados durante a execução da simulação.
A estrutura de modelagem baseada em agente aplicada neste artigo pode fornecer gráficos adicionais. Além disso, os resultados da simulação permanecem armazenados em um banco de dados SQLite que pode ser analisado de qualquer forma personalizada. No entanto, isso exigiria alguma personalização/adaptação adicional, ou seja, codificação.
Considerações finais e conteúdo relacionado
A simulação baseada em agentes é um método de simulação que procura explicar o comportamento de sistemas macroscópicos complexos, descrevendo a dinâmica e as interações dos agentes no nível microscópico do sistema. É um método bastante abstrato e frequentemente usado para entender sistemas complexos. Sistemas complexos são, bem, mais complexos que sistemas complicados e, por outro lado, menos complexos que sistemas caóticos. A economia dos EUA, visível no nível macroscópico na forma, por exemplo, do produto interno bruto, é um exemplo de sistema complexo. Modelos baseados em agentes podem, por exemplo, ser usados para entender o surgimento de certos fenômenos e tendências na economia dos EUA.
Neste artigo, implementei um modelo recentemente muito popular para propagação de doenças. Esta é, de fato, outra área interessante na qual a modelagem baseada em agentes é frequentemente aplicada. Usando uma estrutura para modelagem baseada em agente, implementei um modelo SIR baseado em agente. Os recursos de visualização e animação do framework foram usados para revisar os resultados da simulação. A própria estrutura pode ser usada para implementar outros tipos de modelos de simulação baseados em agentes – e a estrutura será atualizada e expandida regularmente ao longo do tempo.
Aqui estão alguns outros SCDA relacionados à simulação baseada em agente :
- Link : Métodos de simulação para analistas de SCM
- Link : Uma simulação simples baseada em agente visualizada usando Matplotlib em Python
- Link : Modelagem baseada em agente em Python
- Link : Desenvolvendo um modelo simples de simulação baseado em agente em Python
- Link : Visualizando grades e matrizes 2D usando Matplotlib em Python
Cientista de dados com foco em simulação, otimização e modelagem em R, SQL, VBA e Python
Leave a Reply