Método de Controle Sintético
O método de controle sintético é um dos métodos utilizados em inferência causal. Essa área da estatística procura desenvolver métodos que possam reproduzir, ou chegar o mais próximo possível, inferência estatística de causalidade em dados observacionais. Este método em específico pode ser utilizado quando se existe uma série de tempo sobre uma variável de interesse em unidades que sofreram uma intervenção, chamado aqui de tratamento, e unidades similares que não sofreram intervenção. Vejamos o exemplo que iremos utilizar nesta análise:
Programa de redução de crime em Seattle
A cidade de Seattle nos Estados Unidos implementou um programa cujo objetivo era a redução do crime em vizinhanças. Nesse caso, esse programa foi implementado em algumas vizinhanças apenas, para que fosse possível avaliar a efetividade desse método quando comparado com as vizinhanças cujo método não foi implementado.
No entanto, existem diferenças importantes entre essas vizinhanças e os resultados de uma avaliação entre vizinhanças tratadas (que receberam o programa) x vizinhanças controle (que não receberam o programa) deve levar em consideração essas características prévias. Por exemplo: uma vizinhança que tinha uma escolaridade maior média da população e que recebeu o tratamento não pode ser comparada diretamenta com uma vizinhança de escolaridade menor média da população que não foi tratada, pois a escolaridade média pode ser uma variável que influencia a criminalidade.
O método de controle sintético busca comparar uma vizinhança que recebeu o tratamento com um conjunto de vizinhanças que não recebeu o tratamento mas que possuem um conjunto semelhante de características da vizinhança que recebeu o tratamento.
Essa seleção de vizinhanças que serão parte do grupo controle pode ser feita de forma manual, através de conhecimento especialista (cujo método aplicado se simplifica a diferenças-em-diferenças), ou através de um conjunto de variáveis que descrevem essa vizinhança. Cada vizinhança candidata ao controle receberá um peso que será proporcional ao quão semelhante cada vizinhança é à vizinhança que recebeu o tratamento, desta forma, eliminando o componente de subjetividade de seleção das vizinhanças de controle.
Por fim, esta análise é baseada no tutorial de Jacquelyn Fede postado no Kaggle.
Pacote microsynth e Base de Dados
O pacote utilizado para o método de controle sintético (Synthetic Control Method) é o microsynth e a base de dados utilizada será seattledmi, que vem com esse pacote:
library(microsynth)
data(seattledmi)
df = seattledmi
library(skimr) # Este pacote auxilia na descrição de conjunto de dados
skim(df)| Name | df |
| Number of rows | 154272 |
| Number of columns | 22 |
| _______________________ | |
| Column type frequency: | |
| numeric | 22 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| ID | 0 | 1 | 5.30e+14 | 3.43e+07 | 5.3e+14 | 5.30e+14 | 5.3e+14 | 5.30e+14 | 5.30e+14 | ▆▇▂▁▁ |
| time | 0 | 1 | 8.50e+00 | 4.61e+00 | 1.0e+00 | 4.75e+00 | 8.5e+00 | 1.22e+01 | 1.60e+01 | ▇▆▆▆▆ |
| Intervention | 0 | 1 | 0.00e+00 | 3.00e-02 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 1.00e+00 | ▇▁▁▁▁ |
| i_robbery | 0 | 1 | 3.00e-02 | 2.00e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 7.00e+00 | ▇▁▁▁▁ |
| i_aggassau | 0 | 1 | 3.00e-02 | 1.80e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 5.00e+00 | ▇▁▁▁▁ |
| i_burglary | 0 | 1 | 4.30e-01 | 1.24e+00 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 5.40e+01 | ▇▁▁▁▁ |
| i_larceny | 0 | 1 | 2.70e-01 | 8.30e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 5.70e+01 | ▇▁▁▁▁ |
| i_felony | 0 | 1 | 1.00e-01 | 3.90e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 1.40e+01 | ▇▁▁▁▁ |
| i_misdemea | 0 | 1 | 1.00e-01 | 4.10e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 2.40e+01 | ▇▁▁▁▁ |
| i_drugsale | 0 | 1 | 1.00e-02 | 1.10e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 4.00e+00 | ▇▁▁▁▁ |
| i_drugposs | 0 | 1 | 2.00e-02 | 1.60e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 7.00e+00 | ▇▁▁▁▁ |
| any_crime | 0 | 1 | 1.48e+00 | 3.81e+00 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 2.00e+00 | 2.40e+02 | ▇▁▁▁▁ |
| i_drugs | 0 | 1 | 3.00e-02 | 2.00e-01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 0.00e+00 | 9.00e+00 | ▇▁▁▁▁ |
| TotalPop | 0 | 1 | 6.11e+01 | 8.01e+01 | 0.0e+00 | 1.90e+01 | 4.7e+01 | 7.40e+01 | 2.77e+03 | ▇▁▁▁▁ |
| BLACK | 0 | 1 | 4.89e+00 | 1.64e+01 | 0.0e+00 | 0.00e+00 | 0.0e+00 | 4.00e+00 | 6.71e+02 | ▇▁▁▁▁ |
| HISPANIC | 0 | 1 | 4.08e+00 | 9.74e+00 | 0.0e+00 | 0.00e+00 | 1.0e+00 | 4.00e+00 | 2.47e+02 | ▇▁▁▁▁ |
| Males_1521 | 0 | 1 | 2.50e+00 | 1.70e+01 | 0.0e+00 | 0.00e+00 | 1.0e+00 | 2.00e+00 | 1.27e+03 | ▇▁▁▁▁ |
| HOUSEHOLDS | 0 | 1 | 2.86e+01 | 4.02e+01 | 0.0e+00 | 8.00e+00 | 2.0e+01 | 3.10e+01 | 8.51e+02 | ▇▁▁▁▁ |
| FAMILYHOUS | 0 | 1 | 1.22e+01 | 1.31e+01 | 0.0e+00 | 4.00e+00 | 1.0e+01 | 1.60e+01 | 2.00e+02 | ▇▁▁▁▁ |
| FEMALE_HOU | 0 | 1 | 2.08e+00 | 3.72e+00 | 0.0e+00 | 0.00e+00 | 1.0e+00 | 3.00e+00 | 7.50e+01 | ▇▁▁▁▁ |
| RENTER_HOU | 0 | 1 | 1.49e+01 | 3.43e+01 | 0.0e+00 | 1.00e+00 | 4.0e+00 | 1.10e+01 | 5.67e+02 | ▇▁▁▁▁ |
| VACANT_HOU | 0 | 1 | 2.52e+00 | 1.01e+01 | 0.0e+00 | 0.00e+00 | 1.0e+00 | 2.00e+00 | 3.57e+02 | ▇▁▁▁▁ |
Em geral, o conjunto de dados parece bem limpo, sem dados faltantes e apenas com dados numéricos, necessários para a análise. Em seguida, só para ajudar o entendimento dos dados, vamos realizar uma matriz de correlações:
As colunas que começam com i_ são índices de criminalidade como venda de drogas, uso de drogas, furto/roubo, etc. Outras variáveis descrevem a vizinhança como por exemplo HOUSEHOLD (número de casas), BLACK (número de residentes afro-americanos), RENTER_HOU (número de casa alugadas), VACANT_HOU (número de casas desocupadas), entre outros.
Dados que já entendemos melhor o conjunto de dados, vamos prosseguir com a análise dos dados.
Análise dos Dados
Etapa 1: Definir os tipos de variáveis
Neste etapa, precisamos definir dois grupos de variáveis:
- Variáveis de interesse, ou resposta: neste caso serão os índices de criminalidade.
- Covariáveis descritivas: as demais variáveis que descrevem as vizinhanças. Estas serão utilizadas para construir os pesos que comporão o controle sintético.
# Para variável resposta, vamos selecionar apenas uma para simplificar:
resposta = c("any_crime")
# Para covariável, temos que adicionar todas:
covariaveis = c("TotalPop", "BLACK", "HISPANIC","Males_1521","HOUSEHOLDS",
"FAMILYHOUS","FEMALE_HOU","RENTER_HOU","VACANT_HOU")Note também que temos três variáveis importantes que ainda não comentamos:
- time: que mede as variáveis ao longo to tempo.
- ID: uma identificação numérica arbitrária da vizinhança.
- Intervention: coluna que indica as vizinhanças que receberam o programa de redução de crime.
O código abaixo mostra um resumo da quantidade de vizinhanças totais, quando e quantas receberam o programa:
library(tidyverse)
library(ggplot2)
df %>%
count(time, Intervention) %>%
pivot_wider(names_from = Intervention, values_from = n) %>%
knitr::kable()| time | 0 | 1 |
|---|---|---|
| 1 | 9642 | NA |
| 2 | 9642 | NA |
| 3 | 9642 | NA |
| 4 | 9642 | NA |
| 5 | 9642 | NA |
| 6 | 9642 | NA |
| 7 | 9642 | NA |
| 8 | 9642 | NA |
| 9 | 9642 | NA |
| 10 | 9642 | NA |
| 11 | 9642 | NA |
| 12 | 9642 | NA |
| 13 | 9603 | 39 |
| 14 | 9603 | 39 |
| 15 | 9603 | 39 |
| 16 | 9603 | 39 |
Note que até o período de tempo 12, nenhuma vizinhança tinha recebido o programa contra crime. A partir do tempo 13, 39 vizinhanças passaram a ter o programa contra crime e temos 9603 vizinhanças para utilizar na seleção de controle sintético.
Etapa 2: Rodar o modelo
Em seguida, podemos rodar o modelo baseado nas informações acima.
mod1 <- microsynth(df,
idvar = "ID", # Coluna indicadora da vizinhança
timevar = "time", # Coluna indicadora de tempo
intvar = "Intervention", # Coluna indicadora de tratamento
start.pre = 1, # Tempo de início do estudo
end.pre = 12, # Tempo de pré-intervenção
end.post = 16, # Tempo de fim dos dados
match.out = resposta, # Nome das variáveis resposta
match.covar = covariaveis, # Nome das covariáveis
result.var = resposta,
omnibus.var = resposta,
test="twosided"
)Vamos observar os resultados por partes. Nesta primeira saída, vamos verificar o balanceamento:
Targets Weighted.Control All.scaled
Intercept 39 39 39.0
TotalPop 2994 2994 2384.7
BLACK 173 173 190.5
HISPANIC 149 149 159.3
Males_1521 49 49 97.4
HOUSEHOLDS 1968 1968 1113.6
FAMILYHOUS 519 519 475.2
FEMALE_HOU 101 101 81.2
RENTER_HOU 1868 1868 581.9
VACANT_HOU 160 160 98.4
any_crime.12 272 272 65.3
any_crime.11 227 227 64.2
any_crime.10 183 183 55.7
any_crime.9 176 176 53.2
any_crime.8 228 228 55.8
any_crime.7 246 246 55.8
any_crime.6 200 200 52.8
any_crime.5 270 270 50.7
any_crime.4 250 250 57.3
any_crime.3 236 236 58.9
any_crime.2 250 250 51.5
any_crime.1 242 242 55.1
Esta primeira tabela indica a qualidade da seleção de pesos. Para todas as covariáveis e para a variável resposta antes do período de intervenção, são apresentadas as médias por grupos de tratamento e controle. Dessa forma, é possível verificar o balanceamento das covariáveis entre grupos e verificar se os pesos foram estimados de forma a encontrar grupos balanceados. Neste caso encontramos um match exato, mostrando números idênticos entre grupo controle e tratamento. Para verificar os pesos de cada vizinhança, podemos utilizar o código abaixo:
mod1$w$Weights %>%
data.frame(.) %>%
mutate(
peso_igual_zero = ifelse(Main == 0, "sim", "nao")
) %>%
count(peso_igual_zero) peso_igual_zero n
1 nao 1398
2 sim 8244
Essa informação é interessante: do total de possíveis vizinhanças controle (9603), apenas 1398 tiveram peso acima de zero. Isso significa que 8244 vizinhanças não contribuíram em nada com o valor do controle. Isso pode acontecer para o caso de vizinhanças que sejam muito diferentes das vizinhanças tratadas para aquele grupo de covariáveis.
Finalmente, vamos verificar qual foi o tamanho do efeito e o gráfico final:
$`16`
Trt Con Pct.Chng Linear.pVal Linear.Lower Linear.Upper
any_crime 788 1006 -0.217 0.0137 -0.338 -0.0723
Ao dia 16, a diferença para any_crime foi de 21.6% inferior ao grupo tratado com o programa anti-crime, indicando que a iniciativa foi bem sucedida e estatisticamente significativa (p-value = 0.014) a 5% de significância.
Note também que antes do período de intervenção (linha vertical tracejada em vermelho), o grupo tratamento e o grupo controle sintético tiveram comportamento bem semelhante, indicando um ótimo ajuste dos pesos do grupo de controle sintético.