“Do bar”. Modelando a racionalidade limitada com ABM: o modelo El Farol (ABM – Parte 3)

Terceiro post da série. Veja os outros: Parte 1, Parte 2, Parte 4 e Parte 5.


sloppy-joes-bar-in-downtown-chicago-everettEssa é velha… Dois economistas entram num bar. Tinham preferências idênticas: detestavam aquele ambiente quando estava cheio demais. Era uma sociedade pequena, de três pessoas apenas (logo, todo mundo conhecia todos que existiam para conhecer). E pra todos era tácito: três é demais! Mas ir sozinho ou encontrar mais alguém por lá seria bom. Por isso, cada um havia feito, de antemão e sozinho, um cálculo sobre quem iria ou não. Cada um sabia exatamente como os outros dois decidiam, por isso era fácil adivinhar o que de fato ocorreria. Esse cálculo todo ocorreu da maneira a seguir.

Vamos adotar a seguinte notação: se uma pessoa decide ir ao bar, escrevemos V. Assim, o resultado V V V significa: a primeira pessoa foi, a segunda pessoa também e a terceira idem. Por conseguinte, VNV significa: a primeira e a terceira pessoa foram, mas a segunda não. E assim por diante. Usando essas siglas, podemos dizer que as preferências de cada economista da estória eram as seguintes:

  1. Preferiam ir sozinhos ou, no máximo com mais alguém. Do ponto de vista da primeira pessoa, os resultados desejados seriam: VNN, VVN ou VNV. Vamos atribuir 2 pontos de “satisfação” (pay offs) a esses resultados.
  2. Em segundo lugar, era preferível simplesmente não ir: NVV, NVN, NNV ou NNN. Não ir dá 0 pontos de satisfação para a pessoa.
  3. Por último, o pior dos mundos: chegar no bar lotado, VVV. A raiva é tanta que a satisfação diminui um ponto.

Com essas definições, desenhamos o seguinte diagrama, que representa as decisões individuais, os pay-offs e os resultados (pontos de equilíbrio). Um caso simples de teoria dos jogos.

jogo

A Pessoa 1 pensa da seguinte maneira:

  • Se as Pessoas 2 e Pessoa 3 já estiverem indo, vou ficar insatisfeito (-1 ponto). Então, nesse caso, eu não vou (então 0 pontos).
  • Se somente uma das duas pessoas estiverem indo ou se nenhum deles for, aí sim…! Estou dentro (2 pontos).

O diagrama acima apenas representa mais formalmente esse raciocínio, mostrando como pessoas avalia todas as combinações de situação e o que fariam em cada caso. Os números coloridos de azul mostram as decisões da Pessoa 1; os de vermelho, as decisões da Pessoa 2 e os de verde, as da Pessoa 3. Onde as três decisões se encontram, temos um equilíbrio de Nash – uma situação em que ninguém tem incentivo para mudar sua decisão. Nesse caso, temos três equilíbrios, que são exatamente as situações em que apenas duas pessoas vão ao bar. Qual deles de fato vai ocorrer? Boa pergunta! A princípio, qualquer um dos três . Ou então, pensando num longo prazo, os três podem acontecer em iguais proporções… Mas fato é: de acordo com esse raciocínio, sempre haverá duas pessoas.

A piada (“Dois economistas entram num bar…”) perde a graça quando começamos a trazer elementos mais realistas para a estorinha: 1) numa sociedade real, há muito mais do que três pessoas, como seria possível saber quem vai ou não, mesmo que todo mundo tivesse as mesmas preferências e decidisse utilizando as mesmas regras?; 2) e se cada pessoa decidisse utilizando regras diferentes e sem ter informação sobre o que os outros estão fazendo?; 3) e se cada pessoa tivesse acesso apenas a uma quantidade parcial de informações sobre a lotação do bar?; 4) e se tivessem preferências distintas sobre a quantidade de gente que consideram adequada?

Entram em cena os Agent-based models.


Esse joguinho do bar que eu inventei é só um uso simplificado de Teoria dos Jogos, pra ilustrar o quanto estamos exigindo dos nossos agentes mesmo numa situação tão simples quanto essa. Em especial, coloco em questão a informação completa sobre o método de decisão dos outros, sobre suas efetivas ações potenciais e sobre o comportamento da lotação do bar. Vamos suspender essas suposições. Será que mesmo assim podemos chamar nossos agentes de racionais? Será que um padrão de comportamento agregado vai ser produzido ou será que vai ser um caos? Essas foram as questões colocadas por W. Brian Arthur em seu clássico Inductive Reasoning and Bounded Rationality (veja a quantidade de citações no Google Scholar).

A noção de racionalidade limitada já fora proposta há muito tempo, por Herbert Simon — conferindo-lhe um Prêmio Nobel. Para Simon, que está na origem do desenvolvimento da cibernética e inclusive da inteligência artificial, nossa forma de pensar se parece muito mais com um algoritmo do que com uma equação. O critério de decisão parece muito mais com a tentativa de atingir um ponto de satisfação (um limite inferior) do que a maximização da utilidade. Além disso, é importante levar em consideração a cognição: isto é, a representação parcial da realidade dentro da cabeça do indivíduo. Cognição é importante justamente porque as pessoas não tem acesso completo à realidade externa e a interpretam da mesma maneira. Brian Arthur utiliza de uma simulação computacional para operacionalizar aspectos da racionalidade limitada. Traz como exemplo a decisão sobre ir ou não a um bar, o El Farol (que de fato existe na cidade de Santa Fé, Novo México, EUA – era um bar em que os pesquisadores do Instituto Santa Fé costumavam frequentar nos Happy Hours).

De forma geral, o modelo é o seguinte: o bar publica periodicamente quantas pessoas estiveram presentes das últimas vezes, formando um histórico de lotações. Cada indivíduo tem sua própria forma de calcular e decidir se vai ou não, e pode levar em conta as informações publicadas da maneira que quiser — ou seja, possuem, cada um, sua própria heurística. Alguns acham que sempre vai estar vazio, outros que sempre vai estar cheio. Alguns observam as tendências de curto prazo: a lotação têm crescido ou diminuído? Outros, as de longo prazo. Uns simplesmente julgam que a lotação da próxima vez será idêntica a da vez anterior. Outros, fazem uma média de todo o histórico do bar. E assim por diante. Depois de formarem seu próprio palpite (um chute/guess), decidem sozinhos se vão ou não. Então o bar registra a lotação daquele dia e depois publica como foi.

O que vale sublinhar é que não há um modo objetivamente correto de decidir e que cada pessoa não tem a menor ideia sobre como os outros decidem e o que vão acabar fazendo. O bar será uma surpresa.

O pseudo-código para o “Modelo El Farol” (como ficou conhecido), é:

Definimos parâmetros
  Histórico de lotações do bar (historico)
  Número de indivíduos na simulação (n)
  (Limite de) Lotação preferida (quantidade_preferida)
  Numero de rounds (rounds)

Criamos um conjunto amplo de formas de decidir (heurísticas)

Definimos a classe "Indivíduo"
  Sortearemos uma heurística para cada indivíduo, ao ser criado 

Criamos uma quantidade "n" de indivíduos.

Início de um loop:
  Rodada de decisões
    Cada indivíduo acessa o histórico de lotações e aplica sua 
    regra de decisão

  Rodada do bar
    Quem decidiu ir, de fato comparece
    Registra-se a quantidade de pessoas que estiveram presentes
    
  Se o número de repetições atingir "rounds"
    Termine o loop

Mãos à obra pra implementar no R agora. Primeiro os parâmetros:

historico = sample(1:100, 10)
n = 100
quantidade_preferida = function() 60
rounds = 100

Agora definimos as heurísticas. Trata-se de uma lista de funções. Cada uma acessa o histórico de lotações, que existe no ambiente principal e executa algum procedimento com ele. Por exemplo: estimativa_ultimo retorna o último valor do histórico. Isso significa que o indivíduo que aplica esse tipo de heurística supõe que a lotação da próxima vez será idêntica à da última. A função estimativa_espelho retorna um valor “espelhado” ao redor de 50: por exemplo, se da última vez foram 40 (i.e. 50 – 10), da próxima irão 60 (i.e. 50 +10). Alguns sempre chutam “37” (acham que vai pouca gente). Outros sempre chutam “70” (acham que vai muita). Os que observam a tendência de curto prazo “rodam mentalmente” uma regressão linear, considerando as últimas 5 vezes e estimam o valor predito para a próxima vez. O que observam a tendência de longo prazo, levam em conta as últimas 10. Seria possível ficar inventando heurísticas à vontade. Mas eu só elaborei 13. É o bastante para os fins deste exemplo.

heuristicas = list(
      estimativa_ultimo =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(min(x[tamanho]))
        },

      estimativa_penultimo =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(min(x[tamanho-1]))
        },

      estimativa_espelho =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(n - x[tamanho])
        },

      estimativa_min3 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(min(x[(tamanho-2):tamanho]))
        },

      estimativa_max2 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(max(x[(tamanho-1):tamanho]))
        },

      estimativa_37 =
        function(){
          return(37)
        },

      estimativa_70 =
        function(){
          return(70)
        },

      estimativa_media2 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(mean(x[(tamanho-1):tamanho]))
        },

      estimativa_media5 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(mean(x[(tamanho-4):tamanho]))
        },

      estimativa_media10 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          return(mean(x[(tamanho-9):tamanho]))
        },

      estimativa_media_todos =
        function(){
          x = get("historico", envir=.GlobalEnv)
          return(mean(x))
        },

      estimativa_regr5 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          beta = coef(lm(x[(tamanho-4):tamanho]~c(1:5)))
          pred = c(1,6)
          return(as.numeric(pred%*%beta))
        },

       estimativa_regr10 =
        function(){
          x = get("historico", envir=.GlobalEnv)
          tamanho = length(x)
          beta = coef(lm(x[(tamanho-9):tamanho]~c(1:10)))
          pred = c(1,11)
          return(as.numeric(pred%*%beta))
        }
)

Definimos a classe “Indivíduo”:

Individuo = setRefClass("Individuo",
  fields = c("decisao",
             "estrategia_adotada",
             "quantidade_preferida"),

  methods = list(

    initialize = function(decisao = NULL,
    estrategia = sample(length(heuristicas),1),
    ...){

      .self$decisao            = decisao
      .self$estrategia_adotada = estrategia
      callSuper(...)
    },

    decide = function(){
      chute = heuristicas[[estrategia_adotada]]()

      if(chute > quantidade_preferida){
        .self$decisao = 0
      }else{
        .self$decisao = 1
    }}
))

Instanciamos os indivíduos:

pessoas = list()
for(i in 1:n)
pessoas[[i]] = Individuo$new(quantidade_preferida =
quantidade_preferida() )

E os rounds são bem simples:

for(t in 1:rounds){
  print(t)

  #Rodada de decisão
  for(pessoa in pessoas)
    pessoa$decide()

  # Rodada do bar
  decisoes = sapply(pessoas, function(x) x$decisao)
  quantos_foram = sum(decisoes)
  historico = c(historico, quantos_foram)
}

Aí, ó:rounds

Depois é só plotar os resultados:

# Excluindo os 10 primeiros rounds, que
# foram pré-definidos como parâmetros
historico = historico[-(1:10)]

# Gráfico
plot(historico, type = "l", ylim = c(0, 100), col = "red")
abline(h = mean(historico), col = "blue", lwd=2)

E então obtemos:

farol1As preferências eram todas iguais… certo? Estabelecemos nos parâmetros que ninguém gostava do bar com mais de 60 pessoas. E, de fato, um padrão emergente se estabelece em torno de 60, como se vê no gráfico acima. Mas não se trata de um ponto de equilíbrio: situações não desejadas por ninguém ocorrem frequentemente, sem padrão algum. Há uma instabilidade dinâmica.

Podemos testar o que ocorreria se as pessoas tivessem diferentes limites de tolerância à lotação. Pra isso, é só fazer:

quantidade_preferida = function() sample(0:100, 1)

Um número aleatório entre 0 e 100 será sorteado para cada pessoa. Assim:farol2

De uma forma bizarra, obtivemos um ponto de equilíbrio!! Mas isso foi completamente aleatório, dado ao acaso. Nem foi preciso assumir aquela quantidade toda de supostos tradicionais da escolha racional.

Mas poderíamos tornar o exemplo cada vez mais complexo. Cada agente poderia ter, por exemplo, mais de uma estratégia. Assim, fariam um chute a partir de cada uma delas e, na medida em que uma desse resultados melhores, tenderiam a utilizá-la mais vezes. Seria um aprendizado com a experiência. Poderíamos estabelecer uma regra diferente para a decisão. A atual é um limite superior de lotação: todo mundo gosta de ver no bar no máximo X pessoas. Mas poderia haver pessoas que gostasse de ver no mínimo X pessoas… ou então uma quantidade entre X e Y. E assim por diante…

Padrões emergem. Não combinados por ninguém e sem que ninguém tivesse informação prévia sobre o resto. A sociedade é exatamente isso, uma propriedade emergente, fruto da ação de todos, mas não presente completamente na cabeça de ninguém. Nada parecida com o diagrama de Teoria dos Jogos exposto acima. Escolha Racional tem muitas utilidades, sem dúvida. Mas também limitações… e algumas delas podem ser contornadas com ABM.

 

 

Anúncios

3 respostas em ““Do bar”. Modelando a racionalidade limitada com ABM: o modelo El Farol (ABM – Parte 3)

  1. Pingback: Simulando a segregação racial: o modelo de Schelling (ABM – Parte 4) | SOCIAIS & MÉTODOS

  2. Pingback: Sociedade, caos e complexidade (ABM – Parte 5, final) | SOCIAIS & MÉTODOS

  3. Pingback: Simulando o trânsito e os limites de velocidade | SOCIAIS & MÉTODOS

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s