Skip to content

Regresión

Published: at 12:00 AM

Table of contents

Open Table of contents

Correlación y Causalidad1

Es importante recordar que cuando dos variables, digamos la variable A y la variable B están correlacionadas existen varias posibilidades:

Es decir, correlaciòn no implica causalidad, pero cuando si hay causalidad se hallará correlaciòn

Inferencia Causal3

Para determinar si la variable A causa el efecto B, se define una serie de condiciones:

Como menciona Chen et al., un ejemplo de éste procedimiento ocurre en los estudios de eficacia de medicinas. Se analiza cómo diferentes tratamientos se correlacionan con el resultado, para asegurar que la correlación existe y para determinar bajo que condiciones es más fuerte. Se tiene un conocimiento disciplinar sobre el tiempo de metabolización del compuesto, o del efecto biológico de la vacuna, lo que guía los análisis temporales. Finalmente se diseña el experimento teniendo en cuenta las variables de la población, de tal forma que se pueda eliminar variables de confusión que puedan afectar las conclusiones.

Regresión

En un experimento se tiene una variable explicativa xix_i (o independiente) y una variable de respuesta yiy_i (o dependiente). El análisis de regresión supone una relación lineal entre esas dos variables, y busca cuantificar esa relación.

Regresión Lineal Simple

Modelo

Es el siguiente:

yi=β0+β1xi+ϵi, i=1,...,n{\color{blue}y_i} = {\color{green} \beta_0 + \beta_1 x_i } + {\color{red}\epsilon_i},\ i = 1,...,n

Que se interpreta como:

Por ejemplo en la siguiente gráfica los datos yiy_i están marcados con cuadrados azules, la aproximación lineal yi^\hat{y_i} por círculos verdes. Las líneas verticales representan la diferencia o distancia entre los dos valores ϵi\epsilon_i4.

Ejemplo: indicadores de gobernanza global

El banco mundial ha desarrollado una base de datos llamada Worldwide Governance Indicators, donde busca resumir la calidad del gobierno en varios países del mundo. Después de descargar la base de datos5, se obtiene un archivo en formato propietario de Microsoft Excel.

Para cargarlo a Python hacemos lo siguiente. Primero cargamos las librerias pandas y numpy.

import pandas as pd
import numpy as np

Luego procedemos a usar read_excel para cargar los datos:

wgi_df = pd.read_excel("Worldwide Governance Indicators 2012-2022.xlsx")

Como siempre, podemos revisar las variables que se encuentran en el archivo y comparar con la dexcripción que hacen los autores del mismo conjunto de datos.

print(wgi_df.columns)

Esto devuelve el arreglo Index(['Country ', 'ISO3', 'ID Data', 'Year', 'Voice and Accountability', 'Political Stability', 'Government Effectiveness', 'Regulatory Quality', 'Rule of Law', 'Control of Corruption', 'Region'], dtype='object'). Intentaremos cuantificar la relación entre las variables Regulatory Quality y Government Efficiency. Primero cargamos la librería matplotlib y agregamos título.

import matplotlib.pyplot as plt
plt.ion()
plt.figure()
plt.show()
plt.title("Correlación de indicadores de gobernanza global")
plt.xlabel("Calidad regulatoria")
plt.ylabel("Efectividad del gobierno")

Ahora hacemos un diagrama de dispersión de los valores de las dos variables.

plt.plot(wgi_df['Regulatory Quality'],wgi_df['Government Effectiveness'],'.')

Pareciera que al aumentar la variable Regulatory Quality hay valores mayores en Government Effectiveness. Para cuantificar ésta relación proponemos un análisis de regresión lineal. Primero importamos la función linear_model de la librería sklearn, y creamos un modelo lineal.

from sklearn import linear_model
reg = linear_model.LinearRegression()

Para poder usar el ajuste requerimos que los datos independientes estén organizados de una forma particular. Primero los cargamos en el arreglo rq de Python, y luego los reorgamizamos.

rq = np.array(wgi_df['Regulatory Quality'])
rq=rq.reshape(-1,1)

Ahora si podemos hacer el ajuste, con el comando fit. Recibe como argumentos el arreglo correspondiente a la variable independiente que habíamos generado atrás y el vector de la variable dependiente. Luego procedemos a graficarlo y grabar la figura.

reg.fit(rq,np.array(wgi_df['Government Effectiveness']))
plt.plot(rq,reg.predict(rq),linewidth=2,color="orange")
plt.savefig('wgi_reg.svg')

Los residuales ϵi\epsilon_i se pueden calcular mediante la diferencia entre los valores de la variable Government Effectiveness y el valor por el modelo:

residuals = wgi_df['Government Effectiveness'] - reg.predict(rq)

Podemos hacer un histograma de residuales.

plt.figure()
plt.title("Histograma de residuales de la \n Correlación de indicadores de gobernanza global")
plt.hist(residuals)

Los parámetros de la recta son su pendiente y el intercepto con el eje. Se obtienen respectivamente con coef_ e intercept:

print("la pendiente es " + str(reg.coef_))
print("el intercepto es " + str(reg.intercept_))

Puede encontrar más información sobre la regresión lineal en las referencias6.

Regresión Múltiple7

En el modelo de regresión lineal simple, tenemos sólo una variable explicativa y una variable de respuesta. En la regresión múltiple hay más de una variable explicativa. En general, si son pp variables explicativas:

yi=β0+β1x1i+β2x2i+...+βpxpi+ϵi{\color{blue}y_i} = {\color{green} \beta_0 + \beta_1 x_{1i}+ \beta_2 x_{2i} +...+ \beta_p x_{pi} } + {\color{red}\epsilon_i} donde ii define cada uno de los datos a ajustar, i=1,...,ni = 1,...,n

Por ejemplo, para el caso de dos variables explicativas:

yi=β0+β1x1i+β2x2i+ϵi, i=1,...,n{\color{blue}y_i} = {\color{green} \beta_0 + \beta_1 x_{1i}+ \beta_2 x_{2i} } + {\color{red}\epsilon_i},\ i = 1,...,n

Aquí

Si son dos variables explicativas, la aproximación lineal es un plano.

Ejemplo

Volvemos a los Worldwide Governance Indicators del Banco Mundial. Si podemos tomar como variables explicativas a : Voice and Accountability y Regulatory Quality y como variable depdendiente a Government Effectiveness, tendríamos el siguiente procedimiento.

Inicialmente cargamos las librerías y cerramos las gráficas:

import pandas as pd
from sklearn import linear_model
from sklearn.metrics import mean_squared_error
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt
plt.close('all')

Ahora definimos los predictores y el modelo lineal:

predictors=['Voice and Accountability','Regulatory Quality']
outcome = 'Government Effectiveness'
lm = linear_model.LinearRegression()

Leemos los datos:

wgi_df = pd.read_excel("Worldwide Governance Indicators 2012-2022.xlsx")

La función fit hace el ajuste, toma como argumentos los nombres de las variables, predictores y de la variable objetivo.

lm.fit(wgi_df[predictors],wgi_df[outcome])

Aquí podemos generar un resumen del ajuste. Para esto usamos la librería sklearn. Primero generamos un modelo, y hacemos el ajuste. Luego imprimimos los resultados de éste proceso.

model = sm.OLS(wgi_df[outcome], wgi_df[predictors].assign(const=1))
results = model.fit()
print(results.summary())

Los resultados del análisis son:

                               OLS Regression Results                               
====================================================================================
Dep. Variable:     Government Effectiveness   R-squared:                       0.860
Model:                                  OLS   Adj. R-squared:                  0.860
Method:                       Least Squares   F-statistic:                     6093.
Date:                      jue, 10 abr 2025   Prob (F-statistic):               0.00
Time:                              13:47:39   Log-Likelihood:                -7520.6
No. Observations:                      1980   AIC:                         1.505e+04
Df Residuals:                          1977   BIC:                         1.506e+04
Df Model:                                 2                                         
Covariance Type:                  nonrobust                                         
============================================================================================
                               coef    std err          t      P>|t|      [0.025      0.975]
--------------------------------------------------------------------------------------------
Voice and Accountability     0.0332      0.014      2.392      0.017       0.006       0.060
Regulatory Quality           0.8983      0.014     65.642      0.000       0.871       0.925
const                        2.8740      0.486      5.918      0.000       1.922       3.826
==============================================================================
Omnibus:                      177.632   Durbin-Watson:                   0.341
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              363.095
Skew:                           0.576   Prob(JB):                     1.43e-79
Kurtosis:                       4.753   Cond. No.                         154.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Tenemos un valor de R20.860R^2 \approx 0.860, que es cercano a 1.

Para generar la gráfica cargamos la figura y generamos un eje con proyección 3D8. El comando scatter genera el diagrama de dispersión. Y el comando set_xlabel genera la etiqueta del eje x.

fig = plt.figure()
ax =  fig.add_subplot(projection='3d')
ax.scatter(wgi_df['Voice and Accountability'],wgi_df['Regulatory Quality'],wgi_df['Government Effectiveness'], marker='o')

Para generar una gráfica del plano construimos las variables que varíen en los mismos rangos de las variables. Generamos una malla con esos valores de los variables. Y procedemos a generar un plano con las constantes de ajuste del modelo lm. Generamos el plano con el comando plot_surface, y grabamos con savefig 9.

x=np.linspace(0,100,100)
y=np.linspace(0,100,100)
x, y = np.meshgrid(x, y)
plano = x * lm.coef_[0] +  y * lm.coef_[1]
ax.plot_surface(x,y,plano,alpha=0.4)
plt.show()
plt.savefig('3dfitwgi.svg')

En la interfaz de Python se puede mover la figura para mejorar la visualización.

Regresión de funciones no lineales10

En los dos casos anteriores ha habido una relación lineal entre variables explicativas y variables de respuesta. En los casos en los que la relación no es lineal se pueden usar los procedimientos de Regresión, pero es necesario primero llevar a cabo una transformación de los datos.

Veámos un ejemplo. Iniciamos cargando librerías y generando la figura.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.ion()
plt.close('all')

fig = plt.figure()
ax = plt.gca()

Aqui usted cargaría sus datos. Para este ejemplo propongo usemos los siguientes arreglos de datos:

x=[2.91915403e+00, 5.04227145e+00, 8.00623721e-04, 2.11632801e+00,
       1.02729124e+00, 6.46370163e-01, 1.30382148e+00, 2.41892509e+00,
       2.77737232e+00, 3.77171714e+00, 2.93436160e+00, 4.79653650e+00,
       1.43116575e+00, 6.14682205e+00, 1.91713152e-01, 4.69327257e+00,
       2.92113362e+00, 3.91082880e+00, 9.82708570e-01, 1.38671042e+00,
       5.60521198e+00, 6.77783103e+00, 2.19396925e+00, 4.84625831e+00,
       6.13472407e+00, 6.26224664e+00, 5.95309480e-01, 2.73383483e-01,
       1.18881294e+00, 6.14699752e+00, 6.88427837e-01, 2.94775338e+00,
       6.70522671e+00, 3.73215699e+00, 4.84313980e+00, 2.20860942e+00,
       4.80550649e+00, 5.84237970e+00, 1.28017941e-01, 5.25101020e+00,
       6.92202762e+00, 5.23715958e+00, 1.96310794e+00, 5.52495530e+00,
       7.22582046e-01, 3.13525468e+00, 6.36016852e+00, 2.05529904e+00,
       2.01442737e+00, 9.10200005e-01]

y=[ 0.15189155, -1.03060098, -0.06632399,  0.85358508,  0.74417029,
        0.62573434,  1.13055361,  0.73559223,  0.33703733, -0.67800824,
        0.13103516, -0.82721623,  0.99534825, -0.1996406 ,  0.20963249,
       -0.78979177,  0.23069347, -0.63386635,  0.86202009,  0.947879  ,
       -0.74146767,  0.4397856 ,  0.79114136, -0.93239056, -0.06401813,
        0.07217308,  0.58932376,  0.35850492,  0.85248734, -0.01048038,
        0.68661685,  0.1628184 ,  0.4584754 , -0.56438704, -0.87830134,
        0.95538153, -0.77711016, -0.56631783, -0.01674283, -0.90886333,
        0.61227017, -0.777822  ,  0.95559123, -0.88985753,  0.63070327,
        0.08913539,  0.09991667,  0.9611078 ,  0.88096628,  0.76955067]

Tenemos una variable explicativa xx y una variable de respuesta yy. El diagrama de dispersión resulta ser el siguiente:

plt.plot(x,y,'.',label='datos')

Una aproximación lineal simple seguiría el modelo:

yi^=β0+β1xi{\color{green} \hat{y_i} = \beta_0 + \beta_1 x_ i}

Pero esto correspondería a una recta, que claramente no se ajusta a los datos. Una aproximación lineal múltiple seguiría el modelo:

yi^=β0+β1x1i+β2x1i+...+βpxpi{\color{green} \hat{y_i} = \beta_0 + \beta_1 x_{1i}+ \beta_2 x_{1i} +...+ \beta_p x_{pi} }

La estrategia consiste en llevar a cabo transformaciones no lineales (polinomiales o trascendentes) de la variable xx. En este caso, si usamos:

x1=xx_1=x

x2=x2x_2=x^2

x3=x3x_3=x^3

Obtendríamos:

yi^=β0+β1xi+β2xi2+β3xi3{\color{green} \hat{y_i} = \beta_0 + \beta_1 x_{i}+ \beta_2 x_{i}^2 + \beta_3 x_{i}^3 }

yi^=β0+β1x1i+β2x2i+β3x3i{\color{green} \hat{y_i} = \beta_0 + \beta_1 x_{1i}+ \beta_2 x_{2i} + \beta_3 x_{3i} }

De esta forma se usa el modelo lineal para encontrar los coeficientes β\beta. Una forma de hacer éste proceso de manera eficiente es la siguiente. Primero cargamos librerías:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

Ahora definimos la transformación polinomial. En este caso el númro 3 indica que vamos hasta potencias al cubo.

from sklearn.pipeline import make_pipeline
poly_model = make_pipeline(PolynomialFeatures(3), LinearRegression())

Ahora hacemos el ajuste al modelo y generamos los datos de la predicción. Primero construimos un vector ordenado que tenga valores extremos (mínimo y máximo) similares a los de la variable xx. Ese arreglo lo llamamos xfit. Luego hacemos una predicción, es decir y^\color{green} \hat{y}, usando el modelo polinomial que habíamos construido. Finalmente graficamos el ajuste e imprimimos la leyenda.

xfit = np.linspace(0,7,50)
yfit = poly_model.predict(xfit[:, np.newaxis])
plt.plot(xfit,yfit,'g-',label='ajuste cúbico')
plt.legend()

A manera de cierre

Hasta aquí la presentación de algunos conceptos de estadística y su implementación en el software Python en el ámbito de la administración pública. Presenté los temas más relefantes, usando ejemplos basados en datos reales de Colombia y el algunos casos fuentes internacionales. Aunque quedan diferente temas por estudiar, esperamos que esta introducción le permita comenzar a desarrollar sus propios análisis. Recuerde siempre que éstas herramientas son útiles al ser usadas en el contexto, incluyendo el análisis disciplinar.

Temas avanzados

En una revisión más a profundidad se pueden tratar temas como:

Bibliografía

Footnotes

  1. La bibliografía para ésta sección es: Data Science for Public Policy. Chen, Rubin, Cornwall.

  2. https://www.nationalgeographic.com/science/article/nick-cage-movies-vs-drownings-and-more-strange-but-spurious-correlations visitado el 5 de Abril del 2025.

  3. La bibliografía para ésta sección es: Data Science for Public Policy. Chen, Rubin, Cornwall, página 166.

  4. Los datos de la gráfica vienen de: Estadística con Aplicaciones en R. Manuel Ricardo Contento Rubio. Editorial UTADEO. 2010. https://www.utadeo.edu.co/es/publicacion/libro/editorial/235/estadistica-con-aplicaciones-en-r, página 368.

  5. Handoyo, Worldwide governance indicators: Cross country data set 2012–2022, Data in Brief, Volume 51, 2023. Los datos mismos se pueden descargar de https://data.mendeley.com/datasets/bfrkzf5k64/1

  6. Página web de Scikit-learn, en: https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html y el libro Practical Statistics for Data Science. Bruce, Bruce, Gedeck, pg. 141.

  7. Practical Statistics for Data Science. Bruce, Bruce, Gedeck, pg. 150. y Python Data Science Handbook. Jake VanderPlas, pg. 419.

  8. La información sobre los diagramas de dispersión se encuentra en https://matplotlib.org/stable/gallery/mplot3d/scatter3d.html

  9. para generar un plano se sigue la información aquí https://www.tutorialspoint.com/how-to-plot-a-plane-using-some-mathematical-equation-in-matplotlib

  10. Python Data Science Handbook. Jake VanderPlas, pg. 422.

  11. La bibliografía para ésta sección es: Data Science for Public Policy. Chen, Rubin, Cornwall, pg. 165


Previous Post
Taller Final
Next Post
Unir Bases