Más sobre ciencia de datos: cienciadedatos.net
La correlación lineal es un método estadístico que permite cuantificar la relación lineal existente entre dos variables. Existen varios estadísticos, llamados coeficientes de correlación lineal, desarrollados con el objetivo de medir este tipo de asociación, algunos de los más empleados son Pearson, Spearman y Kendall.
Con frecuencia, los estudios de correlación lineal preceden a análisis más complejos, como la creación de modelos de regresión. Primero, se analiza si las variables están correlacionadas y, en caso de estarlo, se procede a generar modelos.
Es importante destacar que, la existencia de correlación entre dos variables, no implica necesariamente causalidad. La asociación observada puede deberse a un tercer factor (confounder).
Correlación lineal con Python
Existen múltiples implementaciones que permiten calcular correlaciones lineales en Python, tres de las más utilizadas están disponibles en las librerías: SciPy, Pandas y Pingouin. A lo largo de este documento se muestran ejemplos de cómo utilizarlas.
Para estudiar la relación lineal existente entre dos variables continuas es necesario disponer de parámetros que permitan cuantificar dicha relación. Uno de estos parámetros es la covarianza, que mide el grado de variación conjunta de dos variables aleatorias.
$$\text{Covarianza muestral} = Cov(X,Y)=\dfrac {\sum _{i=1}^{n}\left( x_{i}-\overline {x}\right) \left( y_{i}-\overline {y}\right) }{N-1}$$donde $\overline{x}$ e $\overline{y}$ son la media de cada variable, y $x_i$ e $y_i$ son el valor de las variables para la observación $i$.
Valores positivos indican que las dos variables cambian en la misma dirección y, valores negativos, que lo hacen en direcciones opuestas.
La principal limitación de la covarianza es que, su magnitud, depende de las escalas en que se miden las variables estudiadas. Esto implica que no puede utilizarse para comparar el grado de asociación entre pares de variables medidas en distintas escalas. Una forma de evitar esta limitación y poder hacer comparaciones consiste en estandarizar la covarianza, generando lo que se conoce como coeficientes de correlación.
Los coeficientes de correlación lineal son estadísticos que cuantifican la asociación lineal entre dos variables numéricas. Existen diferentes tipos, de entre los que destacan el Pearson, Rho de Spearman y Tau de Kendall. Todos ellos comparten que:
Su valor está comprendido en el rango [+1 , -1]. Siendo +1 una correlación positiva perfecta y -1 una correlación negativa perfecta.
Se emplean como medida de la fuerza de asociación entre dos variables (tamaño del efecto):
0: asociación nula.
0.1: asociación pequeña.
0.3: asociación mediana.
0.5: asociación moderada.
0.7: asociación alta.
0.9: asociación muy alta.
Desde el punto de vista práctico, las principales diferencias entre estos tres coeficientes son:
La correlación de Pearson funciona bien con variables cuantitativas que tienen una distribución normal o próxima a la normal. Es más sensible a los valores extremos que las otras dos alternativas.
La correlación de Spearman se emplea con variables cuantitativas (continuas o discretas). En lugar de utilizar directamente el valor de cada variable, los datos son ordenados y reemplazados por su respectivo orden ranking. Es un método no paramétrico muy utilizado cuando no se satisface la condición de normalidad necesaria para aplicar la correlación de Pearson.
La correlación de Kendall es otra alternativa no paramétrica que, al igual que la correlación de Spearman, utiliza la ordenación de las observaciones ranking. Es recomendable cuando se dispone de pocos datos y muchos de ellos ocupan la misma posición en el rango, es decir, cuando hay muchas ligaduras.
Además del valor obtenido para el coeficiente de correlación, es necesario calcular su significancia estadística. Por muy cercano que sea el valor del coeficiente de correlación a $+1$ o $-1$, si no es significativo, no se dispone de evidencias suficiente para afirmar que existe una correlación real, ya que el valor observado podría deberse a simple aleatoriedad.
El test paramétrico de significancia estadística empleado para el coeficiente de correlación es el t-test. Donde el estadístico t se obtiene acorde a la ecuación:
$$t=\dfrac {r\sqrt{N-2}}{\sqrt{1-r^{2}}}$$$r$ es el calor del coeficiente de correlación y N es el número de observaciones disponibles. Los grados de libertad se calculan como $df= N-2$.
En este test, se considera como hipótesis nula ($H_0$) que las variables son independientes (coeficiente de correlación poblacional = 0), y como hipótesis alternativa ($H_a$), que sí existe relación (coeficiente de correlación poblacional $\neq$ 0)
También se puede calcular la significancia de un coeficiente de correlación recurriendo a métodos no paramétricos como el bootstrapping.
La correlación lineal, además del valor del coeficiente de correlación y de sus significancia, también tiene un tamaño de efecto asociado conocido como coeficiente de determinación $R^2$.
$R^2$ se interpreta como la cantidad de varianza de $Y$ explicada por $X$. En el caso del coeficiente de Pearson y el de Spearman, $R^2$ se obtiene elevando al cuadrado el coeficiente de correlación. En el caso de Kendall no se puede calcular de este modo.
El coeficiente de correlación de Pearson es la covarianza estandarizada.
$$\rho=\dfrac {Cov(X,Y)}{\sigma_{x}\sigma_{y}}$$La anterior ecuación se corresponde con el coeficiente de Pearson poblacional ($\rho$). En la práctica, raramente se tiene acceso a toda la población, por lo que su valor se estima a partir de una muestra mediante el coeficiente de Pearson muestral ($r$).
$$r_{xy}=\dfrac {\sum _{i=1}^{n}\left( x_{i}-\overline {x}\right) \left( y_{i}-\overline {y}\right) } {\sqrt {\sum _{i=1}^{n}\left( x_{i}-\overline {x}\right) ^{2}\sum _{i=1}^{n}}\overline {\left( y_{i}-\overline {y}\right) ^{2}}}$$Condiciones
Las condiciones que se deben de cumplir para que el coeficiente de correlación de Pearson sea válido son:
La relación que se quiere estudiar es de tipo lineal (de lo contrario, el coeficiente de Pearson no la puede detectar).
Las dos variables deben de ser numéricas.
Normalidad: ambas variables se tienen que distribuir de forma normal. En la práctica, se suele considerar válido aun cuando se alejan moderadamente de la normalidad.
Homocedasticidad: la varianza de $Y$ debe ser constante a lo largo de la variable $X$. Esto se puede contrastar si en un scatterplot los valores de $Y$ mantienen la misma dispersión en las distintas zonas de la variable $X$.
Características
Toma valores entre [-1, +1], siendo +1 una correlación lineal positiva perfecta y -1 una correlación lineal negativa perfecta.
Es independiente de las escalas en las que se midan las variables.
No varía si se aplican transformaciones a las variables.
No tiene en consideración que las variables sean dependientes o independientes.
El coeficiente de correlación de Pearson no equivale a la pendiente de la recta de regresión.
Es sensible a outliers, por lo que se recomienda, en caso de poder justificarlos, excluirlos antes de realizar el cálculo.
El coeficiente de Spearman es el equivalente al coeficiente de Pearson pero con una previa transformación de los datos a ranking. Esto significa que, en lugar de utilizar directamente el valor de cada variable, los datos son ordenados y reemplazados por su respectivo orden (primero, segundo, tercero...). Se emplea como alternativa no paramétrica al coeficiente de Pearson cuando los valores son ordinales, o bien, cuando los valores son continuos pero no satisfacen la condición de normalidad.
$$r_{s}=1-\frac{6\sum d_{i}^{2}}{n (n^{2}-1)},$$Siendo $d_{i}$ la distancia entre los rangos de cada observación ($x_{i} - y_{i}$) y n el número de observaciones.
El coeficiente de Spearman requiere que la relación entre las variables sea monótona, es decir, que cuando una variable crece la otra también lo hace o cuando una crece la otra decrece (que la tendencia sea constante).
Al trabajar con el orden de las observaciones en lugar de su valor real, tiene la característica de ser menos sensible que Pearson a valores extremos.
La correlación de Kendall es un método no paramétrico que, al igual que la correlación de Spearman, utiliza la ordenación de las observaciones ranking.
Es otra alternativa al coeficiente de correlación de Pearson cuando no se cumple la condición de normalidad. Suele utilizarse en lugar del coeficiente de Spearman cuando el número de observaciones es pequeño o los valores se acumulan en una región por lo que el número de ligaduras al generar el ranking es alto.
$$\tau= \frac{C-D}{\frac{1}{2}n(n-1)}$$siendo $C$ el número de pares concordantes, aquellos en los que el rango de la segunda variable es mayor que el rango de la primera variable. $D$ el número de pares discordantes, cuando el rango de la segunda es igual o menor que el rango de la primera variable.
El coeficiente de correlación de Pearson resulta efectivo en ámbitos muy diversos. Sin embargo, tiene la desventaja de no ser robusto frente a outliers a pesar de que se cumpla la condición de normalidad. Si dos variables tienen un pico o un valle común en una única observación, por ejemplo por un error de lectura, la correlación va a estar dominada por este registro a pesar de que entre las dos variables no haya correlación real alguna. Lo mismo puede ocurrir en la dirección opuesta. Si dos variables están altamente correlacionadas excepto para una observación en la que los valores son muy dispares, entonces la correlación existente quedará enmascarada. Una forma de evitarlo es recurrir a la Jackknife correlation, que consiste en calcular todos los posibles coeficientes de correlación entre dos variables si se excluye cada vez una de las observaciones. El promedio de todas las Jackknife correlations calculadas atenúa en cierta medida el efecto del outlier.
$$\bar{\theta}_{(A,B)} = \text{Promedio Jackknife correlation (A,B)} = \frac{1}{n} \sum_{i=1}^n \hat r_i$$donde $n$ es el número de observaciones y $\hat r_i$ es el coeficiente de correlación de Pearson estimado entre las variables $A$ y $B$, habiendo excluido la observación $i$.
Además del promedio, se puede estimar su error estándar ($SE$) y así obtener intervalos de confianza para la Jackknife correlation y su correspondiente p-value.
$$SE = \sqrt{\frac{n-1}{n} \sum_{i=1}^n (\hat r_i - \bar{\theta})^2}$$Intervalo de confianza del 95% $(Z=1.96)$
$$\text{Promedio Jackknife correlation (A,B)} \pm \ 1.96 *SE$$$$\bar{\theta} - 1.96 \sqrt{\frac{n-1}{n} \sum_{i=1}^n (\hat r_i - \bar{\theta})^2} \ , \ \ \bar{\theta}+ 1.96 \sqrt{\frac{n-1}{n} \sum_{i=1}^n (\hat r_i - \bar{\theta})^2}$$P-value para la hipótesis nula de que $\bar{\theta} = 0$:
$$Z_{calculada} = \frac{\bar{\theta} - H_0}{SE}= \frac{\bar{\theta} - 0}{\sqrt{\frac{n-1}{n} \sum_{i=1}^n (\hat r_i - \bar{\theta})^2}}$$ $$p_{value} = P(Z > Z_{calculada})$$Cuando se emplea este método es conveniente calcular la diferencia entre el valor de correlación obtenido por Jackknife correlation $(\bar{\theta})$ y el que se obtiene si se emplean todas las observaciones $(\bar{r})$. A esta diferencia se le conoce como Bias. Su magnitud es un indicativo de cuanto está influenciada la estimación de la correlación entre dos variables debido a un valor atípico u outlier.
$$Bias = (n-1)*(\bar{\theta} - \hat{r})$$Si se calcula la diferencia entre cada correlación $(\hat r_i)$ estimada en el proceso de Jackknife y el valor de correlación $(\hat r)$ obtenido si se emplean todas las observaciones, se puede identificar que observaciones son más influyentes.
Cuando el estudio requiere minimizar al máximo la presencia de falsos positivos, a pesar de que se incremente la de falsos negativos, se puede seleccionar como valor de correlación el menor de entre todos los calculados en el proceso de Jackknife.
$$\text{Correlacion}= min \{ \hat r_1, \hat r_2,..., \hat r_n \}$$A pesar de que el método de Jackknife permite aumentar la robustez de la correlación de Pearson, si los outliers son muy extremos su influencia seguirá siendo notable. Siempre es conveniente una representación gráfica de los datos para poder identificar si hay valores atípicos y eliminarlos. Otras alternativas robustas son la correlación de Spearman o el método de Bootstrapping.
Como se ha explicado, la correlación estudia la relación (lineal o monotónica) existente entre dos variables. Puede ocurrir que, la relación que muestran dos variables, se deba a una tercera variable que influye sobre las otras dos. A este fenómeno se le conoce como confounding. Por ejemplo, si se correlaciona el tamaño del pie de una persona con su inteligencia, se encuentra una correlación positiva alta. Sin embargo, dicha relación se debe a una tercera variable que está relacionada con las otras dos, la edad. La correlación parcial permite estudiar la relación lineal entre dos variables bloqueando el efecto de una tercera (o más) variables. Si el valor de correlación de dos variables es distinto al valor de correlación parcial de esas mismas dos variables, cuando se controla una tercera, significa que la tercera variable influye en las otras dos. La función en partial_corr()
del paquete pingouin
permite estudiar correlaciones parciales.
Un estudio pretende analizar si existe una correlación lineal positiva entre la altura y el peso de las personas. Los datos utilizados en este ejemplo se han obtenido del libro Statistical Rethinking by Richard McElreath. El set de datos contiene información recogida por Nancy Howell a finales de la década de 1960 sobre el pueblo !Kung San, que viven en el desierto de Kalahari entre Botsuana, Namibia y Angola.
# Tratamiento de datos
# ==============================================================================
import pandas as pd
import numpy as np
from sklearn.datasets import load_diabetes
# Gráficos
# ==============================================================================
import matplotlib.pyplot as plt
from matplotlib import style
import seaborn as sns
# Preprocesado y análisis
# ==============================================================================
import statsmodels.api as sm
import pingouin as pg
from scipy import stats
from scipy.stats import pearsonr
# Configuración matplotlib
# ==============================================================================
plt.style.use('ggplot')
# Configuración warnings
# ==============================================================================
import warnings
warnings.filterwarnings('ignore')
url = ('https://raw.githubusercontent.com/JoaquinAmatRodrigo/' +
'Estadistica-machine-learning-python/master/data/Howell1.csv')
datos = pd.read_csv(url)
# Se utilizan únicamente información de individuos mayores de 18 años.
datos = datos[datos.age > 18]
datos.info()
En primer lugar se representan las dos variables mediante un diagrama de dispersión (scatterplot) para intuir si existe relación lineal o monotónica. Si no la hay, no tiene sentido calcular este tipo de correlaciones.
# Gráfico
# ==============================================================================
fig, ax = plt.subplots(1, 1, figsize=(6,4))
ax.scatter(x=datos.height, y=datos.weight, alpha= 0.8)
ax.set_xlabel('Altura')
ax.set_ylabel('Peso');
El diagrama de dispersión parece indicar una relación lineal positiva entre ambas variables.
Para poder elegir el coeficiente de correlación adecuado, se tiene que analizar el tipo de variables y la distribución que presentan. En este caso, ambas variables son cuantitativas continuas y pueden ordenarse para convertirlas en un ranking, por lo que, a priori, los tres coeficientes podrían aplicarse. La elección se hará en función de la distribución que presenten las observaciones: normalidad, homocedasticidad y presencia de outliers.
# Gráfico distribución variables
# ==============================================================================
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
axs[0].hist(x=datos.height, bins=20, color="#3182bd", alpha=0.5)
axs[0].plot(datos.height, np.full_like(datos.height, -0.01), '|k', markeredgewidth=1)
axs[0].set_title('Distribución altura (height)')
axs[0].set_xlabel('height')
axs[0].set_ylabel('counts')
axs[1].hist(x=datos.weight, bins=20, color="#3182bd", alpha=0.5)
axs[1].plot(datos.weight, np.full_like(datos.weight, -0.01), '|k', markeredgewidth=1)
axs[1].set_title('Distribución peso (weight)')
axs[1].set_xlabel('weight')
axs[1].set_ylabel('counts')
plt.tight_layout();
# Gráfico Q-Q
# ==============================================================================
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
sm.qqplot(
datos.height,
fit = True,
line = 'q',
alpha = 0.4,
lw = 2,
ax = axs[0]
)
axs[0].set_title('Gráfico Q-Q height', fontsize = 10, fontweight = "bold")
axs[0].tick_params(labelsize = 7)
sm.qqplot(
datos.height,
fit = True,
line = 'q',
alpha = 0.4,
lw = 2,
ax = axs[1]
)
axs[1].set_title('Gráfico Q-Q height', fontsize = 10, fontweight = "bold")
axs[1].tick_params(labelsize = 7)
Además del estudio gráfico, se recurre a dos test estadísticos que contrasten la normalidad de los datos: Shapiro-Wilk test y D'Agostino's K-squared test. Este último es el que incluye el summary de statsmodels bajo el nombre de Omnibus.
En ambos test, la hipótesis nula considera que los datos siguen una distribución normal, por lo tanto, si el p-value no es inferior al nivel de referencia alpha seleccionado, no hay evidencias para descartar que los datos se distribuyen de forma normal.
# Normalidad de los residuos Shapiro-Wilk test
# ==============================================================================
shapiro_test = stats.shapiro(datos.height)
print(f"Variable height: {shapiro_test}")
shapiro_test = stats.shapiro(datos.weight)
print(f"Variable weight: {shapiro_test}")
# Normalidad de los residuos D'Agostino's K-squared test
# ==============================================================================
k2, p_value = stats.normaltest(datos.height)
print(f"Variable height: Estadítico = {k2}, p-value = {p_value}")
k2, p_value = stats.normaltest(datos.weight)
print(f"Variable weight: Estadítico = {k2}, p-value = {p_value}")
El análisis gráfico y los test estadísticos muestran evidencias de que no se puede asumir normalidad en ninguna de las dos variables. Siendo estrictos, este hecho excluye la posibilidad de utilizar el coeficiente de Pearson, dejando como alternativas el de Spearman o Kendall. Sin embargo, dado que la distribución no se aleja mucho de la normalidad y de que el coeficiente de Pearson tiene cierta robustez, a fines prácticos sí que se podría utilizar siempre y cuando se tenga en cuenta este hecho y se comunique en los resultados. Otra posibilidad es tratar de transformar las variables para mejorar su distribución, por ejemplo, aplicando el logaritmo.
# Transformación logarítmica de los datos
# ==============================================================================
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6, 4))
sm.qqplot(
np.log(datos.height),
fit = True,
line = 'q',
alpha = 0.4,
lw = 2,
ax = ax
)
ax.set_title('Gráfico Q-Q log(height)', fontsize = 13)
ax.tick_params(labelsize = 7)
shapiro_test = stats.shapiro(np.log(datos.height))
print(f"Variable height: {shapiro_test}")
La trasformación logarítmica de la variable altura (height) consigue una distribución más próxima a la normal.
La homocedasticidad implica que la varianza se mantiene constante. Puede analizarse de forma gráfica representando las observaciones en un diagrama de dispersión y viendo si mantiene una homogeneidad en su dispersión a lo largo del eje X. Una forma cónica es un claro indicativo de falta de homocedasticidad. Dos test estadísticos utilizados para contrastar la homocedasticidad son: test de Goldfeld-Quandt y el de Breusch-Pagan.
Tal como muestra el diagrama de dispersión generado al inicio del ejercicio, no se aprecia ningún patrón cónico y la dispersión es constante.
Debido a la falta de normalidad, los resultados generados por Pearson no son del todo precisos. Sin embargo, dado que la desviación de la normalidad es leve y no se aprecian outliers, con fines ilustrativos, se procede a calcular los tres tipos de coeficientes.
De nuevo recordar que, cuando alguna de las condiciones asumidas por un modelo o test estadístico no se cumplen, no significa que obligatoriamente se tenga que descartar, pero hay que ser consciente de las implicaciones que tiene y reportarlo siempre en los resultados.
Pandas
Pandas permite calcular la correlación de dos Series (columnas de un DataFrame). El cálculo se hace por pares, eliminando automáticamente aquellos con valores NA/null. Una limitación de Pandas es que no calcula la significancia estadística.
# Cálculo de correlación con Pandas
# ==============================================================================
print('Correlación Pearson: ', datos['weight'].corr(datos['height'], method='pearson'))
print('Correlación spearman: ', datos['weight'].corr(datos['height'], method='spearman'))
print('Correlación kendall: ', datos['weight'].corr(datos['height'], method='kendall'))
Scypy.stats
La implementación de Scypy.stats sí permite calcular la significancia estadística además del coeficiente de correlación. La función stats.pearsonr()
, devuelve un error si alguna de las observaciones contienen valores NA/null. Las funciones stats.spearmanr()
y stats.kendalltau()
sí permiten excluirlos de forma automática si se indica nan_policy='omit'
.
# Cálculo de correlación y significancia con Scipy
# ==============================================================================
r, p = stats.pearsonr(datos['weight'], datos['height'])
print(f"Correlación Pearson: r={r}, p-value={p}")
r, p = stats.spearmanr(datos['weight'], datos['height'])
print(f"Correlación Spearman: r={r}, p-value={p}")
r, p = stats.kendalltau(datos['weight'], datos['height'])
print(f"Correlación Pearson: r={r}, p-value={p}")
Pingouin
La librería Pingouin tiene una de las implementaciones más completas. Con la función corr()
se obtiene, además del coeficiente de correlación, su significancia, intervalo de confianza y poder estadístico entre otros.
# Cálculo de correlación, significancia e intervalos con pingouin
# ==============================================================================
display(pg.corr(datos['weight'], datos['height'], method='pearson'))
display(pg.corr(datos['weight'], datos['height'], method='spearman'))
display(pg.corr(datos['weight'], datos['height'], method='kendall'))
Los test estadísticos muestran una correlación lineal entre moderada y alta, con claras evidencias estadísticas de que la relación observada no se debe al azar ($pvalue \approx 0$).
Un equipo de investigadores quiere estudiar si existe correlación en la presencia de dos sustancias (A y B) en el agua de los ríos. Para ello han realizado una serie de mediciones en las que se cuantifica la concentración de las dos sustancias en 10 muestras independientes de agua. Se sospecha que el instrumento de lectura sufre alguna avería que provoca que algunas lecturas se disparen, por esta razón se quiere emplear un método de correlación robusto. El objetivo de este ejemplo es ilustrar el método de Jackknife, por lo que se asume que se cumplen las condiciones para la correlación de Pearson.
# Datos simulados de dos variables A y B
a = np.array([12,9,6,7,2,5,4,0,1,8])
b = np.array([3,5,1,9,5,3,7,2,10,5])
# Se introduce un outlier
a[5] = 20
b[5] = 16
# Gráfico
# ==============================================================================
fig, ax = plt.subplots(1, 1, figsize=(6,4))
ax.plot(a, label='A')
ax.plot(b, label='B')
ax.set_xlabel('ID muestra')
ax.set_ylabel('Concentración')
ax.set_title('Concentración sustancias A y B en las muestras')
ax.legend();
# Correlación con outlier
r, p = stats.pearsonr(a, b)
print(f"Correlación Pearson con outlier: r={r}, p-value={p}")
# Correlación sin outlier
r, p = stats.pearsonr(np.delete(a, 5), np.delete(b, 5))
print(f"Correlación Pearson sin outlier: r={r}, p-value={p}")
Se confirma que, La observación número 5, tiene una gran influencia en el resultado de la correlación, siendo de 0.52 si está presente y de -0.18 si se excluye.
# Función Jackknife correlation
# ==============================================================================
def correlacion_jackknife(x, y):
'''
Esta función aplica el método de Jackknife para el cálculo del coeficiente
de correlación de Pearson.
Parameters
----------
x : 1D np.ndarray, pd.Series
Variable X.
y : 1D np.ndarray, pd.Series
Variable y.
Returns
-------
correlaciones: 1D np.ndarray
Valor de correlación para cada iteración de Jackknife
'''
n = len(x)
valores_jackknife = np.full(shape=n, fill_value=np.nan, dtype=float)
for i in range(n):
# Loop para excluir cada observación y calcular la correlación
r = stats.pearsonr(np.delete(x, i), np.delete(y, i))[0]
valores_jackknife[i] = r
promedio_jackknife = np.nanmean(valores_jackknife)
standar_error = np.sqrt(((n - 1) / n) * \
np.nansum((valores_jackknife - promedio_jackknife) ** 2))
bias = (n - 1) * (promedio_jackknife - stats.pearsonr(x, y)[0])
resultados = {
'valores_jackknife' : valores_jackknife,
'promedio' : promedio_jackknife,
'se' : standar_error,
'bias' : bias
}
return resultados
correlacion = correlacion_jackknife(x=a, y=b)
print(f"Correlación jackknife: {correlacion['promedio']}")
print(f"Error estándar: {correlacion['se']}")
print(f"Error bias: {correlacion['bias']}")
print(f"Valores_jackknife: {correlacion['valores_jackknife']}")
Para identificar si existe algún valor muy influyente, se puede graficar el cambio que produce en el coeficiente de regresión la exclusión de cada observación.
variacion_corr = correlacion['valores_jackknife'] - stats.pearsonr(a, b)[0]
fig, ax = plt.subplots(1, 1, figsize=(6,4))
ax.plot(variacion_corr)
ax.set_xlabel('ID muestra')
ax.set_ylabel('Variación correlación');
El método Jackknife correlation solo ha sido capaz de amortiguar una pequeña parte de la influencia del outlier, sin embargo, sí ha permitido identificar qué observación está afectando en mayor medida.
Cuando se dispone de múltiples variables numéricas, por ejemplo en problemas de modelado estadístico y machine learning, es conveniente estudiar el grado de correlación entre las variables disponibles.
Una forma de hacerlo es mediante matrices de correlación, en las que se muestra el coeficiente de correlación para cada par de variables.
# Datos
# ==============================================================================
url = ('https://raw.githubusercontent.com/JoaquinAmatRodrigo/' +
'Estadistica-machine-learning-python/master/data/SaratogaHouses.csv')
datos = pd.read_csv(url, sep=",")
# Se renombran las columnas para que sean más descriptivas
datos.columns = ["precio", "metros_totales", "antiguedad", "precio_terreno",
"metros_habitables", "universitarios", "dormitorios",
"chimenea", "banyos", "habitaciones", "calefaccion",
"consumo_calefacion", "desague", "vistas_lago",
"nueva_construccion", "aire_acondicionado"]
# Variables numéricas
datos = datos.select_dtypes(include=['float64', 'int'])
# Matriz de correlación
# ==============================================================================
corr_matrix = datos.corr(method='pearson')
corr_matrix
Las matrices de correlación tienen el inconveniente de tener un tamaño notable cuando se dispone de muchas variables. Para facilitar la identificación de pares de variables con correlaciones altas, es conveniente convertirlas en formato de tabla larga (tidy).
def tidy_corr_matrix(corr_mat):
'''
Función para convertir una matriz de correlación de pandas en formato tidy.
'''
corr_mat = corr_mat.stack().reset_index()
corr_mat.columns = ['variable_1','variable_2','r']
corr_mat = corr_mat.loc[corr_mat['variable_1'] != corr_mat['variable_2'], :]
corr_mat['abs_r'] = np.abs(corr_mat['r'])
corr_mat = corr_mat.sort_values('abs_r', ascending=False)
return(corr_mat)
tidy_corr_matrix(corr_matrix).head(10)
# Heatmap matriz de correlaciones
# ==============================================================================
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(5, 5))
sns.heatmap(
corr_matrix,
annot = True,
cbar = False,
annot_kws = {"size": 8},
vmin = -1,
vmax = 1,
center = 0,
cmap = sns.diverging_palette(20, 220, n=200),
square = True,
ax = ax
)
ax.set_xticklabels(
ax.get_xticklabels(),
rotation = 45,
horizontalalignment = 'right',
)
ax.tick_params(labelsize = 10)
Se quiere estudiar la relación entre las variables precio y peso de los automóviles. Se sospecha que esta relación podría estar influenciada por la variable potencia del motor, ya que a mayor peso del vehículo se requiere mayor potencia y, a su vez, motores más potentes son más caros.
Para este ejemplo se utiliza el set de datos Cars93
disponible en el paquete de R MASS
.
url = ('https://raw.githubusercontent.com/JoaquinAmatRodrigo/' +
'Estadistica-machine-learning-python/master/data/Cars93.csv')
datos = pd.read_csv(url)
datos['log_Price'] = np.log(datos.Price)
# Gráfico
# ==============================================================================
fig, ax = plt.subplots(1, 1, figsize=(6,4))
ax.scatter(x=datos.Weight, y=datos.log_Price, alpha= 0.8)
ax.set_xlabel('Peso')
ax.set_ylabel('Log(Precio)');
El gráfico muestra una clara relación lineal entre el peso de un coche y el logaritmo de su precio.
# Cálculo de correlación lineal
# ==============================================================================
pg.corr(x=datos['Weight'], y=datos['log_Price'], method='pearson')
# Cálculo de correlación lineal parcial
# ==============================================================================
pg.partial_corr(data=datos, x='Weight', y='log_Price', covar='Horsepower', method='pearson')
La correlación entre el peso y el logaritmo del precio es alta (r=0.764) y significativa ($pvalue \approx 0$). Sin embargo, cuando se estudia su relación bloqueando la variable potencia de motor, a pesar de que la relación sigue siendo significativa, pasa a ser baja (r=0.4047).
Se puede afirmar que, la relación lineal existente entre el peso y el logaritmo del precio, está influenciada por el efecto de la variable potencia de motor.
from sinfo import sinfo
sinfo()
Linear Models with R by Julian J.Faraway
OpenIntro Statistics: Fourth Edition by David Diez, Mine Çetinkaya-Rundel, Christopher Barr
Introduction to Machine Learning with Python: A Guide for Data Scientists
Points of Significance: Association, correlation and causation. Naomi Altman & Martin Krzywinski Nature Methods
¿Cómo citar este documento?
Correlacion lineal con Python por Joaquín Amat Rodrigo, disponible con licencia CC BY-NC-SA 4.0 en https://www.cienciadedatos.net/documentos/pystats05-correlacion-lineal-python.html
¿Te ha gustado el artículo? Tu ayuda es importante
Mantener un sitio web tiene unos costes elevados, tu contribución me ayudará a seguir generando contenido divulgativo gratuito. ¡Muchísimas gracias! 😊
Este contenido, creado por Joaquín Amat Rodrigo, tiene licencia Attribution-NonCommercial-ShareAlike 4.0 International.
Se permite:
Compartir: copiar y redistribuir el material en cualquier medio o formato.
Adaptar: remezclar, transformar y crear a partir del material.
Bajo los siguientes términos:
Atribución: Debes otorgar el crédito adecuado, proporcionar un enlace a la licencia e indicar si se realizaron cambios. Puedes hacerlo de cualquier manera razonable, pero no de una forma que sugiera que el licenciante te respalda o respalda tu uso.
NoComercial: No puedes utilizar el material para fines comerciales.
CompartirIgual: Si remezclas, transformas o creas a partir del material, debes distribuir tus contribuciones bajo la misma licencia que el original.