Trazado de elipses de confianza con Matplotlib

Beginner

This tutorial is from open-source community. Access the source code

Introducción

Este laboratorio demostrará cómo trazar elipses de confianza de un conjunto de datos bidimensionales utilizando Python Matplotlib. Una elipse de confianza es una representación gráfica de la covarianza de un conjunto de datos, que muestra la incertidumbre de la media estimada y la desviación estándar. Las elipses se trazan utilizando el coeficiente de correlación de Pearson.

Consejos para la MV

Después de que la máquina virtual (VM) haya terminado de iniciar, haga clic en la esquina superior izquierda para cambiar a la pestaña Notebook y acceder a Jupyter Notebook para practicar.

A veces, es posible que deba esperar unos segundos para que Jupyter Notebook termine de cargar. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si encuentra problemas durante el aprendizaje, no dude en preguntar a Labby. Proporcione comentarios después de la sesión y resolveremos rápidamente el problema para usted.

Importar las bibliotecas necesarias

El primer paso es importar las bibliotecas necesarias. Para este laboratorio necesitaremos numpy y matplotlib.pyplot.

import matplotlib.pyplot as plt
import numpy as np

Definir la función confidence_ellipse

A continuación, definimos la función confidence_ellipse que tomará las coordenadas x e y del conjunto de datos, el objeto de ejes en el que se dibujará la elipse y el número de desviaciones estándar. Devuelve un objeto de parche (patch) de Matplotlib que representa la elipse.

def confidence_ellipse(x, y, ax, n_std=3.0, facecolor='none', **kwargs):
    """
    Crea un gráfico de la elipse de confianza de la covarianza de *x* e *y*.

    Parámetros
    ----------
    x, y : array-like, shape (n, )
        Datos de entrada.

    ax : matplotlib.axes.Axes
        El objeto de ejes en el que se dibujará la elipse.

    n_std : float
        El número de desviaciones estándar para determinar los radios de la elipse.

    **kwargs
        Se pasan a `~matplotlib.patches.Ellipse`

    Devuelve
    -------
    matplotlib.patches.Ellipse
    """
    if x.size!= y.size:
        raise ValueError("x y y deben tener el mismo tamaño")

    cov = np.cov(x, y)
    pearson = cov[0, 1]/np.sqrt(cov[0, 0] * cov[1, 1])
    ## Usando un caso especial para obtener los eigenvalores de este
    ## conjunto de datos bidimensional.
    ell_radius_x = np.sqrt(1 + pearson)
    ell_radius_y = np.sqrt(1 - pearson)
    ellipse = Ellipse((0, 0), width=ell_radius_x * 2, height=ell_radius_y * 2,
                      facecolor=facecolor, **kwargs)

    ## Calculando la desviación estándar de x a partir
    ## de la raíz cuadrada de la varianza y multiplicando
    ## por el número dado de desviaciones estándar.
    scale_x = np.sqrt(cov[0, 0]) * n_std
    mean_x = np.mean(x)

    ## calculando la desviación estándar de y...
    scale_y = np.sqrt(cov[1, 1]) * n_std
    mean_y = np.mean(y)

    transf = transforms.Affine2D() \
       .rotate_deg(45) \
       .scale(scale_x, scale_y) \
       .translate(mean_x, mean_y)

    ellipse.set_transform(transf + ax.transData)
    return ax.add_patch(ellipse)

Definir la función get_correlated_dataset

También necesitamos una función para generar un conjunto de datos bidimensional con una media, dimensiones y correlación especificadas.

def get_correlated_dataset(n, dependency, mu, scale):
    """
    Crea un conjunto de datos bidimensional aleatorio con la media bidimensional (mu) y dimensiones (scale) especificadas.
    La correlación se puede controlar mediante el parámetro 'dependency',
    una matriz 2x2.
    """
    latent = np.random.randn(n, 2)
    dependent = latent.dot(dependency)
    scaled = dependent * scale
    scaled_with_offset = scaled + mu
    ## Devuelve x e y del nuevo conjunto de datos correlacionado
    return scaled_with_offset[:, 0], scaled_with_offset[:, 1]

Trazar correlaciones positivas, negativas y débiles

Ahora, podemos utilizar estas funciones para trazar las elipses de confianza de conjuntos de datos con correlaciones positivas, negativas y débiles.

np.random.seed(0)

PARAMETERS = {
    'Positive correlation': [[0.85, 0.35],
                             [0.15, -0.65]],
    'Negative correlation': [[0.9, -0.4],
                             [0.1, -0.6]],
    'Weak correlation': [[1, 0],
                         [0, 1]],
}

mu = 2, 4
scale = 3, 5

fig, axs = plt.subplots(1, 3, figsize=(9, 3))
for ax, (title, dependency) in zip(axs, PARAMETERS.items()):
    x, y = get_correlated_dataset(800, dependency, mu, scale)
    ax.scatter(x, y, s=0.5)

    ax.axvline(c='grey', lw=1)
    ax.axhline(c='grey', lw=1)

    confidence_ellipse(x, y, ax, edgecolor='red')

    ax.scatter(mu[0], mu[1], c='red', s=3)
    ax.set_title(title)

plt.show()

Trazar diferentes números de desviaciones estándar

También podemos trazar las elipses de confianza con diferentes números de desviaciones estándar.

fig, ax_nstd = plt.subplots(figsize=(6, 6))

dependency_nstd = [[0.8, 0.75],
                   [-0.2, 0.35]]
mu = 0, 0
scale = 8, 5

ax_nstd.axvline(c='grey', lw=1)
ax_nstd.axhline(c='grey', lw=1)

x, y = get_correlated_dataset(500, dependency_nstd, mu, scale)
ax_nstd.scatter(x, y, s=0.5)

confidence_ellipse(x, y, ax_nstd, n_std=1,
                   label=r'$1\sigma$', edgecolor='firebrick')
confidence_ellipse(x, y, ax_nstd, n_std=2,
                   label=r'$2\sigma$', edgecolor='fuchsia', linestyle='--')
confidence_ellipse(x, y, ax_nstd, n_std=3,
                   label=r'$3\sigma$', edgecolor='blue', linestyle=':')

ax_nstd.scatter(mu[0], mu[1], c='red', s=3)
ax_nstd.set_title('Different standard deviations')
ax_nstd.legend()
plt.show()

Usando argumentos de palabra clave

Por último, podemos personalizar la apariencia de las elipses utilizando argumentos de palabra clave.

fig, ax_kwargs = plt.subplots(figsize=(6, 6))
dependency_kwargs = [[-0.8, 0.5],
                     [-0.2, 0.5]]
mu = 2, -3
scale = 6, 5

ax_kwargs.axvline(c='grey', lw=1)
ax_kwargs.axhline(c='grey', lw=1)

x, y = get_correlated_dataset(500, dependency_kwargs, mu, scale)
## Traza la elipse con zorder=0 para demostrar
## su transparencia (causada por el uso de alpha).
confidence_ellipse(x, y, ax_kwargs,
                   alpha=0.5, facecolor='pink', edgecolor='purple', zorder=0)

ax_kwargs.scatter(x, y, s=0.5)
ax_kwargs.scatter(mu[0], mu[1], c='red', s=3)
ax_kwargs.set_title('Using keyword arguments')

fig.subplots_adjust(hspace=0.25)
plt.show()

Resumen

En este laboratorio, aprendimos cómo trazar elipses de confianza de un conjunto de datos bidimensional utilizando Python Matplotlib. Definimos las funciones confidence_ellipse y get_correlated_dataset, y las utilizamos para trazar elipses de conjuntos de datos con diferentes correlaciones y números de desviaciones estándar. También mostramos cómo personalizar la apariencia de las elipses utilizando argumentos de palabra clave.