Cálculo del coeficiente de correlación de Pearson en Python con Numpy

En este artículo, repasaremos la teoría detrás de la correlación de Pearson, así como ejemplos de fuertes correlaciones positivas y negativas, utilizando Python, Numpy y Matplotlib.

Introducción

Este artículo es una introducción al Coeficiente de correlación de Pearson, su cálculo manual y su cálculo a través del módulo numpy de Python.

El coeficiente de correlación de Pearson mide la asociación lineal entre variables. Su valor se puede interpretar así:

  • +1 - Correlación positiva completa
  • +0.8 - Fuerte correlación positiva
  • +0.6 - Correlación positiva moderada
  • 0 - sin correlación alguna
  • -0.6 - Correlación negativa moderada
  • -0.8 - Fuerte correlación negativa
  • -1 - Correlación negativa completa

Ilustraremos cómo varía el coeficiente de correlación con diferentes tipos de asociaciones. En este artículo, también mostraremos que cero correlación no siempre significa cero asociaciones. Las variables relacionadas de forma no lineal pueden tener coeficientes de correlación cercanos a cero.

¿Qué es el coeficiente de correlación de Pearson?

El coeficiente de correlación de Pearson también se conoce como coeficiente de correlación momento-producto de Pearson. Es una medida de la relación lineal entre dos variables aleatorias: X e Y. Matemáticamente, si (σXY) es la covarianza entre X y Y, y (σX) es la desviación estándar de X, entonces el Pearson' El coeficiente de correlación ρ viene dado por:

$$
\rho_{X,Y} = \frac{\sigma_{XY}}{\sigma_X \sigma_Y}
$$

Como la covarianza siempre es menor que el producto de las desviaciones estándar individuales, el valor de ρ varía entre -1 y +1. De lo anterior también podemos ver que la correlación de una variable consigo misma es uno:

$$
\rho_{X,X} = \frac{\sigma_{XX}}{\sigma_X \sigma_X} = 1
$$
Antes de comenzar a escribir código, hagamos un breve ejemplo para ver cómo se calcula este coeficiente.

¿Cómo se calcula el coeficiente de correlación de Pearson?

Supongamos que nos dan algunas observaciones de las variables aleatorias X y Y. Si planea implementar todo desde cero o hacer algunos cálculos manuales, entonces necesita lo siguiente cuando se le den X e Y:

$$\begin{matriz} X & = & \lbrack & {- 2} & {- 1} & 0 & 1 & 2 & \rbrack^{T} \ Y & = & \lbrack & 4 & 1 & 3 & 2 & 0 & \rbrack^{T} \ X^{2} & = & \lbrack & 4 & 1 & 0 & 1 & 4 & \rbrack^{T} \ Y^{2} & = & \lbrack & 16 & 1 & 9 & 4 & 0 & \rbrack^{T} \ {XY} & = & \lbrack & {- 8} & {- 1} & 0 & 2 & 0 & \rbrack^{T} \ \end{matriz}$$

Usemos lo anterior para calcular la correlación. Usaremos la estimación sesgada de la covarianza y las desviaciones estándar. Esto no afectará el valor del coeficiente de correlación que se calcula, ya que el número de observaciones se cancela en el numerador y el denominador:

$$\begin{matriz} \sigma_{XY} & = & {E(XY) - E(X)E(Y)} & {= - 7/5 - (0)(2)} & {= - 7/5} \ \sigma_{X} & = & \sqrt{E(X^{2}) - (E(X))^{2}} & {= \sqrt{10/5 - (0)^{2}}} & {= \raíz cuadrada{2}} \ \sigma_{Y} & = & \sqrt{E(Y^{2}) - (E(Y))^{2}} & {= \sqrt{30/5 - (10/5)^{2} }} & {= \raíz cuadrada{2}} \ \rho_{XY} & = & \frac{\frac{- 7}{5}}{\sqrt{2}\sqrt{2}} & {= - 7/10} & \ \end{matriz}$$

Coeficiente de correlación de Pearson en Python usando Numpy {#coeficiente de correlación de Pearsoninpythonusingnumpy}

El coeficiente de correlación de Pearson se puede calcular en Python usando el método corrcoef() de Numpy.

La entrada para esta función suele ser una matriz, digamos de tamaño mxn, donde:

  • Cada columna representa los valores de una variable aleatoria
  • Cada fila representa una sola muestra de n variables aleatorias
  • n representan el número total de diferentes variables aleatorias
  • m representa el número total de muestras para cada variable

Para n variables aleatorias, devuelve una matriz cuadrada nxn M, con M(i,j) que indica el coeficiente de correlación entre la variable aleatoria i y j. Como el coeficiente de correlación entre una variable y ella misma es 1, todas las entradas diagonales (i,i) son iguales a uno.

En breve:

$$M(i,j) = \left{ \begin{matriz} \rho_{i,j} & {\text{~if~}i \neq j} \ 1 & \text{de lo contrario} \ \end{matriz} \right.$$ Tenga en cuenta que la matriz de correlación es simétrica como la correlación es simétrica, es decir, `M(i,j) = M(j,i)`. Tomemos nuestro ejemplo simple de la sección anterior y veamos cómo usar `corrcoef()` con `numpy`.

Primero, importemos el módulo numpy, junto con el módulo pyplot de Matplotlib. Usaremos Matplotlib para visualizar la correlación más adelante:

1
2
import numpy as np
import matplotlib.pyplot as plt

Usaremos los mismos valores del ejemplo manual anterior. Guardemos eso en x_simple y calculemos la matriz de correlación:

1
2
3
4
5
x_simple = np.array([-2, -1, 0, 1, 2])
y_simple = np.array([4, 1, 3, 2, 0])
my_rho = np.corrcoef(x_simple, y_simple)

print(my_rho)

La siguiente es la matriz de correlación de salida. Nótense los de las diagonales, indicando que el coeficiente de correlación de una variable consigo misma es uno:

1
2
[[ 1.  -0.7]
[-0.7  1. ]]

Ejemplos de correlación positiva y negativa {#ejemplos de correlación positiva y negativa}

Visualicemos los coeficientes de correlación para algunas relaciones. Primero, tendremos una correlación completamente positiva (+1) y completamente negativa (-1) entre dos variables. Luego, generaremos dos variables aleatorias, por lo que el coeficiente de correlación debería ser cercano a cero, a menos que la aleatoriedad accidentalmente tenga alguna correlación, lo cual es muy poco probable.

Usaremos una semilla para que este ejemplo sea repetible cuando llamemos RandomState desde Numpy:

1
2
3
4
5
6
7
seed = 13
rand = np.random.RandomState(seed)

x = rand.uniform(0,1,100)
x = np.vstack((x,x*2+1))
x = np.vstack((x,-x[0,]*2+1))
x = np.vstack((x,rand.normal(1,3,100)))

La primera llamada rand.uniform() genera una distribución uniforme aleatoria:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[7.77702411e-01 2.37541220e-01 8.24278533e-01 9.65749198e-01
 9.72601114e-01 4.53449247e-01 6.09042463e-01 7.75526515e-01
 6.41613345e-01 7.22018230e-01 3.50365241e-02 2.98449471e-01
 5.85124919e-02 8.57060943e-01 3.72854028e-01 6.79847952e-01
 2.56279949e-01 3.47581215e-01 9.41277008e-03 3.58333783e-01
 9.49094182e-01 2.17899009e-01 3.19391366e-01 9.17772386e-01
 3.19036664e-02 6.50845370e-02 6.29828999e-01 8.73813443e-01
 8.71573230e-03 7.46577237e-01 8.12841171e-01 7.57174462e-02
 6.56455335e-01 5.09262200e-01 4.79883391e-01 9.55574145e-01
 1.20335695e-05 2.46978701e-01 7.12232678e-01 3.24582050e-01
 2.76996356e-01 6.95445453e-01 9.18551748e-01 2.44475702e-01
 4.58085817e-01 2.52992683e-01 3.79333291e-01 6.04538829e-01
 7.72378760e-01 6.79174968e-02 6.86085079e-01 5.48260097e-01
 1.37986053e-01 9.87532192e-02 2.45559105e-01 1.51786663e-01
 9.25994479e-01 6.80105016e-01 2.37658922e-01 5.68885253e-01
 5.56632051e-01 7.27372109e-02 8.39708510e-01 4.05319493e-01
 1.44870989e-01 1.90920059e-01 4.90640137e-01 7.12024374e-01
 9.84938458e-01 8.74786502e-01 4.99041684e-01 1.06779994e-01
 9.13212807e-01 3.64915961e-01 2.26587877e-01 8.72431862e-01
 1.36358352e-01 2.36380160e-01 5.95399245e-01 5.63922609e-01
 9.58934732e-01 4.53239333e-01 1.28958075e-01 7.60567677e-01
 2.01634075e-01 1.75729863e-01 4.37118013e-01 3.40260803e-01
 9.67253109e-01 1.43026077e-01 8.44558533e-01 6.69406140e-01
 1.09304908e-01 8.82535400e-02 9.66462041e-01 1.94297485e-01
 8.19000600e-02 2.69384695e-01 6.50130518e-01 5.46777245e-01]

Luego, podemos llamar a vstack() para apilar verticalmente otras matrices. De esta manera, podemos apilar un montón de variables como las de arriba en la misma referencia x y acceder a ellas secuencialmente.

Después de la primera distribución uniforme, hemos apilado algunos conjuntos de variables verticalmente: el segundo tiene una relación positiva completa con el primero, el tercero tiene una correlación negativa completa con el primero y el cuarto es completamente aleatorio. , por lo que debería tener una correlación ~0.

Cuando tenemos una sola referencia x como esta, podemos calcular la correlación para cada uno de los elementos en la pila vertical pasándola sola a np.corrcoef():

1
2
3
4
5
6
7
8
9
rho = np.corrcoef(x)

fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 3))
for i in [0,1,2]:
    ax[i].scatter(x[0,],x[1+i,])
    ax[i].title.set_text('Correlation = ' + "{:.2f}".format(rho[0,i+1]))
    ax[i].set(xlabel='x',ylabel='y')
fig.subplots_adjust(wspace=.4)    
plt.show()

pearson correlation coefficient

Comprensión de los cambios en el coeficiente de correlación de Pearson {#comprensión de los cambios en el coeficiente de correlación de Pearson}

Solo para ver cómo cambia el coeficiente de correlación con un cambio en la relación entre las dos variables, agreguemos algo de ruido aleatorio a la matriz x generada en la sección anterior y volvamos a ejecutar el código.

En este ejemplo, agregaremos lentamente diversos grados de ruido a los gráficos de correlación y calcularemos los coeficientes de correlación en cada paso:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
fig, ax = plt.subplots(nrows=2, ncols=4, figsize=(15, 8))

for noise, i in zip([0.05,0.2,0.8,2],[0,1,2,3]):
    # Add noise
    x_with_noise = x+rand.normal(0,noise,x.shape)
    
    # Compute correlation
    rho_noise = np.corrcoef(x_with_noise)
    
    # Plot column wise. Positive correlation in row 0 and negative in row 1
    ax[0,i].scatter(x_with_noise[0,],x_with_noise[1,],color='magenta')
    ax[1,i].scatter(x_with_noise[0,],x_with_noise[2,],color='green')
    ax[0,i].title.set_text('Correlation = ' + "{:.2f}".format(rho_noise[0,1])
                        + '\n Noise = ' + "{:.2f}".format(noise) )
    ax[1,i].title.set_text('Correlation = ' + "{:.2f}".format(rho_noise[0,2])
                        + '\n Noise = ' + "{:.2f}".format(noise))
    ax[0,i].set(xlabel='x',ylabel='y')    
    ax[1,i].set(xlabel='x',ylabel='y')
    
fig.subplots_adjust(wspace=0.3,hspace=0.4)    
plt.show()

pearson correlation coefficient with noise

Un escollo común: asociaciones sin correlación

Existe una idea errónea común de que la correlación cero implica que no hay asociación. Aclaremos que la correlación mide estrictamente la relación lineal entre dos variables.

Los ejemplos a continuación muestran variables que no están asociadas linealmente entre sí pero tienen una correlación cero.

El último ejemplo de (y=e^x^) tiene un coeficiente de correlación de alrededor de 0,52, que tampoco es un reflejo de la verdadera asociación entre las dos variables:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Create a data matrix
x_nonlinear = np.linspace(-10,10,100)
x_nonlinear = np.vstack((x_nonlinear,x_nonlinear*x_nonlinear))
x_nonlinear = np.vstack((x_nonlinear,-x_nonlinear[0,]**2))
x_nonlinear = np.vstack((x_nonlinear,x_nonlinear[0,]**4))
x_nonlinear = np.vstack((x_nonlinear,np.log(x_nonlinear[0,]**2+1)))
x_nonlinear = np.vstack((x_nonlinear,np.exp(x_nonlinear[0,])))

# Compute the correlation
rho_nonlinear = np.corrcoef(x_nonlinear)

# Plot the data
fig, ax = plt.subplots(nrows=1, ncols=5, figsize=(16, 3))
title = ['$y=x^2$','$y=-x^2$','$y=x^4$','$y=\log(x^2+1)$','$y=\exp(x)$']
for i in [0,1,2,3,4]:
    ax[i].scatter(x_nonlinear[0,],x_nonlinear[1+i,],color='cyan')
    ax[i].title.set_text(title[i] + '\n' + 
                         'Correlation = ' + "{:.2f}".format(rho_nonlinear[0,i+1]))
    ax[i].set(xlabel='x',ylabel='y')
fig.subplots_adjust(wspace=.4)    
plt.show()

pearson correlation coefficient vs variable association

Yendo más lejos: proyecto de extremo a extremo portátil

¿Tu naturaleza inquisitiva te hace querer ir más allá? Recomendamos consultar nuestro Proyecto guiado: ["Predicción práctica del precio de la vivienda: aprendizaje automático en Python"](https://wikihtp.com/courses/hands-on-house- precio-predicción-aprendizaje-máquina-en-python/#cta){target="_blank"}.

[](https://wikihtp.com/ cursos/predicción-de-precio-de-la-casa-práctica-aprendizaje-de-máquina-en-python/#cta)

En este proyecto guiado, aprenderá a crear potentes modelos tradicionales de aprendizaje automático, así como modelos de aprendizaje profundo, utilizar Ensemble Learning y capacitar a los meta-aprendices para predecir los precios de la vivienda a partir de una bolsa de modelos Scikit-Learn y Keras.

Con Keras, la API de aprendizaje profundo creada sobre Tensorflow, experimentaremos con arquitecturas, crearemos un conjunto de modelos apilados y entrenaremos una red neuronal meta-aprendizaje (modelo de nivel 1) para calcular el precio de un casa.

El aprendizaje profundo es sorprendente, pero antes de recurrir a él, se recomienda intentar resolver el problema con técnicas más simples, como los algoritmos de aprendizaje superficial. Nuestro rendimiento de referencia se basará en un algoritmo de Regresión de bosque aleatorio. Además, exploraremos la creación de conjuntos de modelos a través de Scikit-Learn a través de técnicas como embalaje y votación.

Este es un proyecto integral y, como todos los proyectos de aprendizaje automático, comenzaremos con Análisis exploratorio de datos, seguido de Preprocesamiento de datos y, finalmente, Creación de modelos superficiales y Aprendizaje profundo para ajustarse a los datos que hemos explorado y limpiado previamente.

Conclusiones

En este artículo, discutimos el coeficiente de correlación de Pearson. Usamos el método corrcoef() del módulo numpy de Python para calcular su valor.

Si las variables aleatorias tienen asociaciones lineales altas, entonces su coeficiente de correlación está cerca de +1 o -1. Por otro lado, las variables estadísticamente independientes tienen coeficientes de correlación cercanos a cero.

También demostramos que las asociaciones no lineales pueden tener un coeficiente de correlación cero o cercano a cero, lo que implica que las variables que tienen asociaciones altas pueden no tener un valor alto del coeficiente de correlación de Pearson.