El ejemplo en el post anterior sirve para ilustrar el modelo de resultados potenciales en individuos. Pero lo que en realidad deseamos es obtener conclusiones generales para tomar decisiones. Yo no soy Alicia o Bob, pero quiero saber si debería asistir a la fiesta. Aquí está el post anterior, por si te lo perdiste o quieres usarlo como repaso. También te dejo al final de este post un enlace para el notebook de Google Colab donde puedes correr todo el código, clonar el proyecto y revisar los resultados.
Este tipo de preguntas requieren que hagamos inferencia sobre lo que pasaría si yo fuera. Para eso, podemos estimar lo que se espera que pase con mi calificación si asisto a la fiesta. En otras palabras, queremos conocer el valor esperado del efecto de ir a la fiesta para tomar la decisión de si ir o no.
El principio para entender el modelo de resultados potenciales en un conjunto de datos es el mismo que usamos en la sección anterior, así que podemos comenzar con una extensión de la ecuación que nos muestra el efecto promedio del tratamiento. Veamos nuevamente lo que tenemos. Imagina que en lugar de ver el caso de Alicia y Bob únicamente, tenemos una base de datos de 1000 estudiantes donde indica si asistieron a la fiesta o no (creo que lo deberíamos cambiar a concierto o festival en este punto). La base de datos también nos indica la calificación que se sacaron en econometría.
Veamos cómo se vería esta base de datos creando una simulación en Python. No podemos usar para esto datos reales porque queremos ver los datos contrafactuales que vienen de universos paralelos. Supongamos que la calificación del estudiante $i$ se genera a partir de la siguiente función lineal
De ahí, $\beta_0$ es un parámetro fijo que nos indica para este caso la calificación que el estudiante se sacaría si no fuera a la fiesta y $\varepsilon$ es un término de error estocástico o aleatorio. Es importante incluir este término de error porque bien sabemos que ir a la fiesta no es lo único que puede influir en la calificación de econometría: algunos tendrán mayor calificación que otros.
Un supuesto crítico es que $\varepsilon$ tiene una distribución normal. Esto se representa de la siguiente manera:
Las distribuciones se representan como funciones: con un paréntesis que nos indican sus parámetros. En el caso de la distribución normal nos interesan dos cosas: en dónde está centrada y qué tan dispersa es. El centro de la distribución es el primer parámetro, que hemos definido que debe ser cero para nuestro término de error. El valor de $\sigma^2$ nos indica la varianza o la dispersión de nuestra calificación.
Creando la base de datos
Lo primero que haremos será crear la columna $D_i$ que nos muestra la elección de cada estudiante de manera aleatoria: un 1 significa que si asistieron a la fiesta y un 0 significa que no. También haremos el valor de $\beta_0$ que básicamente es la calificación si deciden no ir a la fiesta.
import numpy as np
np.random.seed(42)
n = 1000 # Determinamos el número de observaciones de nuestra base de datos
b0 = np.random.choice([6,7,8,9],n)
Haremos un poco de trampa a continuación. Vamos a crear nuestra base de datos y vamos a crear el valor de $D_i$. Pero aquí está el secreto: este valor va a depender de $\beta_0$.
Esto refleja una situación parecida a la que encontramos en el modelo individual. Las personas que tienen mayor calificación son las que están más dispuestas a asistir a la fiesta si piensan que no les va a afectar de manera significativa. En el siguiente bloque de código crearemos nuestra base de datos en pandas
y generaremos la columna $D_i$ conforme a la regla que establecimos arriba.
import pandas as pd
df = pd.DataFrame({"b0":b0})
df['Di'] = np.where(df['b0']>7,1,0)
Y aquí llega el momento de la verdad. Vamos a crear nuestra variable $Y$, que contiene las calificaciones de los alumnos. Digamos que el efecto real de asistir a la fiesta es de $\delta = -1$, por lo que al crear la variable en python tendremos como resultado
df['e'] = np.random.normal(0,1,1000)
df['Y'] = df['b0'] + (-1)*df['Di'] + df['e']
Esta es la razón por la que estamos haciendo los datos por medio de una simulación. En la realidad $\delta$ es un parámetro de nuestro modelo que tenemos que estimar, no lo conocemos realmente hasta que hacemos el proceso de inferencia. El resultado de $Y$ contiene nuestro error aleatorio $\varepsilon$, que tiene una desviación estándar de 1.
Empieza a escribir también usando Substack. Usa el botón abajo para crear tu publicación y conectarla con Marionomics: Econometría y Datos
Gracias al término aleatorio no es sencillo entender el patrón que nos dan los datos con sólo velos a simple vista. Por eso necesitamos la estadística. Hagamos la diferencia de medias de las calificaciones de aquellos que asistieron a la fiesta y los que no.
El siguiente bloque de código muestra los resultados de esta operación. Verifica por tu cuenta propia la operación y observa el resultado. ¿Encuentras algo extraño?
print(df[df['Di'] == 1]['Y'].mean() - df[df['Di'] == 0]['Y'].mean())
El sesgo de selección
Nuevamente nos topamos con el mismo efecto. Si no supiéramos que el efecto real era $\delta = -1$, podríamos caer en la ilusión de que asistir a la fiesta en realidad aumenta nuestras calificaciones. Lo peor es que los seres humanos somos muy buenos para encontrar motivos a lo que vemos: tal vez en la fiesta fluyen las ideas de manera libre y eso hace que los alumnos hagan un mejor examen. Tal vez los resultados muestran lo importante que es descansar y pasar un buen rato con los amigos. Pero estudiar econometría requiere dedicarle tiempo y esfuerzo. ¿Qué sucedió en realidad?
Bueno, los datos son inventados, pero eso no significa que no podamos aprender algo de ellos. Para comenzar, veamos que el modelo individual que hicimos anteriormente se puede extender para un conjunto de datos y sus valores esperados.
Hicimos el mismo truco que en la sección pasada: agregamos un elemento que suma 0 para mostrar que el efecto real está contaminado con un sesgo de selección. El dato de $E[Y^0_i |D_i=1]$ no existe en la vida real, es el contrafactual de lo que hubieran sacado como calificación los alumnos que fueron a la fiesta si no hubieran ido. Podemos observar que, en efecto, el resultado de esto es $-1$, como lo esperaríamos de un estimador sin sesgos. Veamos en python este resultado.
Primero creamos las columnas de $Y^0_i$ y $Y_i^1$ independientes de lo que el estudiante haya decidido en la realidad.
df['Y0'] = df['b0'] + df['e']
df['Y1'] = df['b0'] + (-1) + df['e']
Puedes observar que cuando la decisión coincide, la calificación debe ser la misma, pero cuando no, entonces se trata de un contrafactual. Es decir, la primera fila muestra a alguien que si fue a la fiesta ($D_i =1$) y su calificación fue de 7.3. Su calificación si no hubiera ido a la fiesta según nuestros datos habría sido de 8.3.
Veamos entonces la primera parte de la ecuación anterior
Esta es la que nos genera el efecto real de asistir a la fiesta. Podemos extraer estos datos de nuestra simulación en python usando el siguiente código
df[df['Di'] == 1]['Y1'].mean() - df[df['Di'] == 1]['Y0'].mean()
Que lástima que el dato de $E[Y_i^0 | D_i = 1]$ es un contrafactual y no podemos medirlo en la realidad. Pero al menos podemos encontrar ahí el efecto real de -1 que estábamos buscando. Aprovechando que ya estamos aquí, podemos medir nuestro sesgo de selección, que está en el extremo de la derecha en nuestra ecuación y podemos examinarlo de la siguiente manera.
df[df['Di'] == 1]['Y0'].mean() - df[df['Di'] == 0]['Y0'].mean()
Como esperamos, nuestro sesgo de selección tiene un valor muy cercano a 2.
Bueno, y ¿Cómo solucionamos el sesgo de selección?
Para solucionar el sesgo de selección hay que comprender primero de dónde se origina. En nuestro ejemplo es claro que fuimos nosotros quienes lo creamos de manera artificial, pero se dio por las mismas razones que podemos esperar en la vida real.
La decisión que tomaron los estudiantes de nuestra base de datos simulada fue una respuesta a su propia calificación. Esto nos generó un problema de endogeneidad. Veremos más adelante cómo podemos lidiar con estos problemas y por qué es tan importante entenderlos.
De momento consideremos que nuestra muestra contiene este sesgo y lo que debemos hacer para eliminarlo y encontrar el verdadero efecto es seleccionar nuestros datos por un proceso verdaderamente aleatorio que incluya de igual manera a los que asisten a la fiesta y a los que no lo hacen.
Comencemos por crear una copia de la base de datos
df2 = df.copy()
En esta copia vamos a trabajar. Lo primero es sustituir el valor de $D_i$ para que se genere a partir de un proceso aleatorio.
df2['Di'] = np.random.choice([0,1], n)
Ahora toca sustituir los valores de $Y$. El siguiente código genera el valor usando los mismos valores de $\beta_0$ y $\varepsilon$ de la base de datos anterior.
df2['Y'] = df2['b0'] + (-1)*df2['Di'] + df2['e']
df2['Y0'] = df2['b0'] + df2['e']
df2['Y1'] = df2['b0'] + (-1) + df2['e']
df2
Finalmente, hagamos el cálculo de una diferencia de medias simples. Nota que esta vez el sesgo de selección ha desaparecido y tenemos un valor muy cercano al $-1$ que sabemos es el efecto real de asistir a la fiesta.
df2[df2['Di'] == 1]['Y'].mean() - df2[df2['Di'] == 0]['Y'].mean()
Listo. Hemos mostrado cómo solucionar el sesgo de selección en nuestro modelo simulado. El proceso de aleatorización que hicimos aquí se puede simular cuando tenemos la opción de crear un experimento aleatorizado y logramos asegurarnos del control de variables que nos pueden afectar nuestro resultado.
Pero seamos sinceros, los economistas rara vez tenemos la oportunidad de controlar nuestras variables de esa manera. Normalmente a lo que nos enfrentamos son a datos que se recolectaron, en muchas ocasiones por alguien más y normalmente con un propósito diferente a los que nosotros deseamos. En los capítulos siguientes aprenderemos a usar técnicas de regresión para obtener resultados de inferencia causal con este tipo de datos, pero que mantengan el espíritu de estos modelos como si hubiéramos hecho un experimento.