Categoría: EDA

  • Exploración de Datos con Estadística Descriptiva y Visualización

    ¿Qué cubre el análisis de datos exploratorios avanzados?

    • Calcular la varianza de una variable.
    • Evaluar la distribución de los datos.
    • Informar sobre cuartiles, cuantiles y rango intercuartil.
    • Explorar datos categóricos.
    • Transformar los datos para satisfacer tus necesidades.

    Varianza

    Calcular la media, mediana y moda es un buen comienzo para comprender la forma general de un conjunto de datos. Pero esas tres estadísticas solo cuentan parte de la historia.

    Considera los dos conjuntos siguientes:

    dataset_one = [-4, -2, 0, 2, 4]
    dataset_two = [-400, -200, 0, 200, 400]

    Ambos tienen la misma media y mediana (0), pero claramente no representan la misma dispersión. Ahí entra en juego la varianza, que describe qué tan dispersos están los datos.

    Distancia desde la media

    Intuitivamente, queremos que la varianza sea mayor cuando los datos están más dispersos y menor cuando están más concentrados. Una primera idea sería usar el rango, pero solo considera los extremos.

    En cambio, podemos medir cuánto se aleja cada punto de la media:

    $$\text{diferencia} = X – \mu$$

    Donde \( X \) es un punto de datos y \( \mu \) la media.

    Promedio de las distancias

    Podemos combinar las diferencias en una sola medida tomando su promedio. Sin embargo, si los valores por encima y por debajo de la media se cancelan (por ejemplo, [-5, 5]), el promedio sería 0, aunque los datos estén claramente dispersos.

    Cuadrar las diferencias

    Para evitar la cancelación, elevamos al cuadrado las diferencias:

    $$\text{diferencia} = (X – \mu)^2$$

    De este modo, los valores negativos desaparecen y las grandes desviaciones pesan más.

    La varianza \( \sigma^2 \) se define entonces como:

    $$\sigma^2 = \frac{\sum_{i=1}^n (x_i – \mu)^2}{n}$$

    Varianza en Python

    import numpy as np
    
    dataset = [3, 5, -2, 49, 10]
    variance = np.var(dataset)
    print(f"Varianza: {variance:.2f}")

    Salida:

    Varianza: 328.56

    La varianza no se interpreta directamente, sin tener en cuenta la escala de los datos. Esta crece con la magnitud de los valores porque está en unidades al cuadrado. Por eso, comparar una varianza de 328.56 en dos contextos distintos (media = 13 o media = 1200) no tiene sentido absoluto. En el primer caso, las desviaciones son grandes respecto a la media y en el segundo, son minúsculas.

    Entonces:

    La varianza no es una medida relativa, y solo tiene valor comparativo si las variables están en la misma escala.

    Desviación estándar

    La varianza tiene un inconveniente: sus unidades están al cuadrado como ya vimos anteriormente. Por eso usamos la desviación estándar, que devuelve las unidades originales:

    $$\sigma = \sqrt{\sigma^2}$$

    Desviación estándar con NumPy

    import numpy as np
    
    dataset = [4, 8, 15, 16, 23, 42]
    standard_deviation = np.std(dataset)
    print(f"Desviación estándar: {standard_deviation:.2f}")

    Salida:

    Desviación estándar: 12.32

    Interpretación práctica

    La desviación estándar permite interpretar cuán inusual es un valor.  Al encontrar el número de desviaciones estándar que un punto de datos está alejado de la media, podemos comenzar a investigar qué tan inusual es realmente ese punto de datos. 

    • ~68% de los datos están dentro de de la media.
    • ~95% dentro de .
    • ~99.7% dentro de .

    Si un punto se encuentra a más de tres desviaciones estándar, es un valor atípico.

    Describiendo un histograma

    Media y Mediana

    Ambas indican el centro de los datos. En distribuciones simétricas, suelen coincidir.

    Dispersión (Spread)

    Se describe con los valores mínimo y máximo, tomados con la media y la mediana, comienzan a indicar la forma del conjunto de datos subyacente.

    Sesgo (Skewness)

    • Simétrico: la media ≈ mediana.
    • Sesgo a la derecha: cola larga hacia la derecha, media > mediana.
    • Sesgo a la izquierda: cola larga hacia la izquierda, media < mediana.

    Modalidad

    La modalidad describe el número de picos en un conjunto de datos. 

    • Unimodal: un solo pico.
    • Bimodal o multimodal: varios picos.
    • Uniforme: sin agrupaciones claras.

    Valores atípicos (Outliers)

    Son puntos lejanos al resto del conjunto de datos. Conviene investigarlos: pueden ser errores o indicios interesantes.

    Cuartiles

    Dividen los datos en cuatro partes iguales:

    • Q1: 25% inferior
    • Q2: 50% (la mediana)
    • Q3: 75% superior

    Ejemplo:

    import numpy as np
    
    dataset = [-108, 4, 8, 15, 16, 23, 42]
    
    q1 = np.quantile(dataset, 0.25)
    q2 = np.quantile(dataset, 0.50)
    q3 = np.quantile(dataset, 0.75)
    
    print(q1, q2, q3)

    Salida:

    4.0 15.0 23.0

    Cuantiles

    Los cuantiles dividen los datos en grupos de igual tamaño.
    Por ejemplo:

    • Deciles: 10 grupos
    • Percentiles: 100 grupos
    import numpy as np
    
    dataset = [5, 10, -20, 42, -9, 10]
    quantiles = np.quantile(dataset, [0.2, 0.4, 0.6, 0.8])
    print(quantiles)

    Salida:

    [-11.8  -3.6   9.2  23.6]

    Rango intercuartil (IQR)

    El rango intercuartil mide la amplitud del 50% central de los datos, entre el tercer cuartil (Q3) y el primer cuartil (Q1).

    $$IQR = Q3 – Q1$$

    Es más robusto ante valores atípicos que el rango total.

    from scipy.stats import iqr
    
    dataset = [4, 10, 38, 85, 193]
    interquartile_range = iqr(dataset)
    print(f"IQR: {interquartile_range}")
    IQR: 75.0

    Diagramas de caja (Boxplots)

    Los diagramas de caja son una de las formas más comunes de visualizar un conjunto de datos. Al igual que los histogramas , los diagramas de caja dan una idea de la tendencia central y la dispersión de los datos.

    Los boxplots resumen visualmente la distribución:

  • Estadísticas Resumidas

    En el análisis de datos, especialmente cuando trabajamos con conjuntos de datos tabulares, es común que lo primero que queramos hacer sea “entender el terreno”: obtener una visión rápida de los patrones, la distribución y las características principales de las variables.
    A este proceso lo llamamos estadísticas resumidas (summary statistics), y constituye uno de los pilares del análisis exploratorio de datos (EDA, Exploratory Data Analysis).

    Estas estadísticas nos permiten responder preguntas básicas como:

    • ¿Qué tan centrados o dispersos están los datos?
    • ¿Existen valores extremos o atípicos?
    • ¿Cómo se distribuyen los valores?
    • ¿Qué categorías son más frecuentes?

    Estas herramientas —medias, dispersiones, cuartiles, gráficos y agrupaciones— nos permiten:

    • Preparar los datos para análisis más complejos.
    • Detectar errores o valores extremos.
    • Comprender patrones iniciales.

    Análisis Univariado: Explorando una Variable a la Vez

    El análisis univariado se enfoca en describir y entender una sola variable por vez. Es la forma más directa de comenzar el EDA y nos permite observar tendencias, detectar anomalías y entender el comportamiento general de los datos.

    Podemos dividirlo en dos grandes tipos:

    • Variables cuantitativas (numéricas)
    • Variables categóricas (de tipo texto o etiquetas)

    Veamos cómo se resumen y visualizan cada una.

    Variables Cuantitativas

    Medidas de Tendencia Central

    Las medidas de tendencia central buscan representar el valor “típico” o central de un conjunto de datos.

    • Media (promedio): la suma de todos los valores dividida por el número de observaciones. Es útil, pero sensible a valores atípicos.
    • Mediana: el valor que divide al conjunto en dos partes iguales. Menos afectada por outliers, representa mejor distribuciones sesgadas.
    • Moda: el valor más frecuente. Muy útil en datos categóricos o multimodales.
    • Media recortada: elimina un porcentaje de los valores más altos y bajos antes de calcular la media.
    df['column'].mean() # media
    df['column'].median() # mediana
    df['column'].mode() # Moda
    
    # Media recortada:
    from scipy.stats import trim_mean 
    trim_mean(df.column, proportiontocut=0.1)

    Medidas de Dispersión

    Describen cuánto varían los valores respecto al centro.

    • Rango: diferencia entre el valor máximo y el mínimo.
    • Varianza: mide la variabilidad cuadrática respecto a la media.
    • Desviación estándar: raíz cuadrada de la varianza; indica cuánto se alejan los datos, en promedio, de la media.
    • Desviación media absoluta (MAD): promedio de las diferencias absolutas respecto a la media.
    df['column'].max() - df['column'].min()  # rango
    df['column'].var()  # Varianza
    df['column'].std()  # Desviacion estandar
    (df.column - df.column.mean()).abs().mean()  # Desviación media absoluta

    Asimetría (Skewness) y Curtosis

    Estas métricas describen la forma de la distribución:

    • Asimetría (Skewness): indica si los datos están sesgados a la izquierda o derecha.
      • Sesgo positivo → cola larga a la derecha
      • Sesgo negativo → cola larga a la izquierda
    • Curtosis (Kurtosis): mide el peso de las colas de la distribución (presencia de valores extremos). df['column'].kurt()
      • Leptocúrtica: colas gruesas (muchos outliers)
      • Platicúrtica: colas delgadas
      • Mesocúrtica: similar a la normal
    df['column'].skew()  # Asimetría 
    df['column'].kurt()  # Curtosis

    Percentiles y Cuartiles

    Los percentiles indican el porcentaje de observaciones por debajo de un valor dado.
    Por ejemplo, el percentil 80 = 130 significa que el 80% de los valores son menores que 130.

    np.percentile(df['column'], 80)

    Los cuartiles dividen los datos en cuatro partes iguales:

    • Q1 (25%), Q2 (50% = mediana), Q3 (75%)

    El rango intercuartílico (IQR) se calcula como:

    IQR = Q3 - Q1

    y representa la dispersión central, resistente a outliers.

    Visualización: Histogramas y Boxplots

    Visualizar los datos es esencial para complementar las estadísticas numéricas.

    • Histograma: muestra la frecuencia de valores en intervalos (bins).
    sns.histplot(df['column'])
    • Boxplot (diagrama de caja): representa la mediana, los cuartiles y los valores atípicos.
    sns.boxplot(df['column'])

    Estos gráficos ayudan a detectar sesgos, simetrías y valores extremos de un vistazo.


    Variables Categóricas

    Cuando analizamos variables no numéricas (como “país”, “color” o “tipo de producto”), las estadísticas cambian.

    Frecuencias y Proporciones

    La herramienta básica es el conteo de valores:

    df['column'].value_counts()

    Y para ver proporciones:

    df['column'].value_counts(normalize=True)

    Estas proporciones nos ayudan a entender la distribución de categorías, especialmente cuando hay clases dominantes o poco representadas.

    Visualización

    • Gráficos de barras: ideales para mostrar frecuencias.
    sns.countplot(x='column', data=df)
    • Gráficos circulares (pie charts): útiles para proporciones, aunque menos precisos.

    Agrupación y Agregación de Datos

    En análisis exploratorios más profundos, necesitamos obtener estadísticas por grupo.
    Por ejemplo: ¿Cuál es el precio promedio por tipo de carrocería?

    La función groupby() de pandas permite dividir, aplicar y combinar fácilmente:

    df.groupby('body-style')['price'].mean()

    También podemos aplicar múltiples funciones de agregación:

    df.groupby(['body-style', 'drive-wheels']).agg({
        'height': 'min',
        'length': 'max',
        'price': 'mean'
    })

    Y definir agregaciones personalizadas con agg():

    df.agg({'length':['sum','min'], 'width':['max','min']})

    Este enfoque es esencial para crear tablas resumen, indicadores por categoría y comparativas entre grupos.

    Variables Categóricas Ordinales

    Algunas categorías tienen un orden lógico (por ejemplo: “bajo”, “medio”, “alto”).
    En estos casos, podemos convertirlas en variables de tipo category ordenadas para analizarlas numéricamente:

    order = ['Preschool', 'Primary', 'Secondary', 'College', 'Graduate']
    df['education'] = pd.Categorical(df['education'], categories=order, ordered=True)

    Esto permite calcular la mediana de la categoría:

    median_index = np.median(df['education'].cat.codes)
    order[int(median_index)]

    Importante:

    Aunque podemos asignar números, no debemos calcular medias si las distancias entre categorías no son uniformes.