Estimación del efecto causal con Propensity Score Matching en Python
Supongamos que queremos estimar el efecto causal del tratamiento en el tiempo de recuperación de una enfermedad. Contamos con una muestra de pacientes que recibieron el tratamiento (grupo de tratamiento) y una muestra de pacientes que no lo recibieron (grupo de control). Para realizar el Propensity Score Matching, primero debemos estimar el propensity score, que es la probabilidad de que un individuo haya sido asignado al grupo de tratamiento en función de sus características observables. Definimos las variables de nuestro modelo, en este caso, tiempo de recuperación y variable de tratamiento:
import pandas as pd
import statsmodels.api as sm
data = pd.read_csv('datos_enfermos.csv')
X = data[['edad', 'sexo', 'indice_de_masas_corporal', 'enfermedad_previa']]
y = data['tiempo_de_recuperacion']
tratamiento = data['tratamiento']
Con esto estimamos el propensity score con una regresión logística:
modelo_logistico = sm.Logit(tratamiento, X)
propensity_scores = modelo_logistico.fit(disp=0).predict(X)
Posteriormente, realizamos el Propensity Score Matching, que consiste en encontrar los individuos del grupo de control que tengan similar propensity score a los del grupo de tratamiento:
from sklearn.metrics import pairwise_distances
from scipy.spatial.distance import cdist
def Match(groups, propensity_scores, caliper=0.05):
'''Implementación del Propensity Score Matching '''
# divide los grupos
treatment = groups[0]
control = groups[1]
# calcula la distancia entre los propensity scores
distancias = cdist(treatment.reshape(-1, 1), control.reshape(-1, 1)).diagonal()
# encuentra los matches cercanos
indices = np.argsort(distancias)
tratados_seleccionados = []
control_seleccionado = []
for indice in indices:
if distancias[indice] > caliper:
break
if indices[indice] in control_seleccionado:
continue
tratados_seleccionados.append(indice)
control_seleccionado.append(indices[indice])
match_propensity = propensity_scores[control_seleccionado]
return tratados_seleccionados, control_seleccionado, match_propensity
indices_tratamiento, indices_control, match_propensity_scores = Match([tratamiento, ~tratamiento], propensity_scores)
Una vez que tenemos los individuos de los grupos de tratamiento y control que están emparejados, podemos utilizar un modelo de regresión para estimar el efecto causal del tratamiento en el tiempo de recuperación. Aquí utilizaremos una simple regresión de mínimos cuadrados:
import statsmodels.formula.api as smf
# combinamos los datos de los individuos emparejados
datos_matching = pd.concat([X.iloc[indices_tratamiento], X.iloc[indices_control]])
datos_matching['tratamiento'] = tratamiento.iloc[indices_tratamiento + indices_control].to_numpy()
datos_matching['tiempo_de_recuperacion'] = y.iloc[indices_tratamiento + indices_control].to_numpy()
# ajustamos un modelo de regresión de mínimos cuadrados
modelo_matching = smf.ols('tiempo_de_recuperacion ~ tratamiento', data=datos_matching).fit()
print(modelo_matching.summary())
La salida del modelo nos dará la estimación del efecto causal del tratamiento en el tiempo de recuperación, junto con los intervalos de confianza correspondientes. De esta manera, podemos concluir si el tratamiento tiene un efecto causal significativo en el tiempo de recuperación de la enfermedad.