Tema 05 - Análisis Exploratorio de Datos (AED)

Técnicas para ‘Big Data’ en Economía - Curso 2024/25
Universidad de Alicante

Pedro Albarrán

Dpto. de Fundamentos del Análisis Económico. Universidad de Alicante

De los datos en bruto a la información

  • AED es una fase inicial importante, con dos objetivos:

    • Conocer nuestros datos e identificar problemas \(\Longrightarrow\) Preprocesamiento

      • qué variables, tipo de información, calidad (información faltante, inconsistencias, problemas en combinación de datos.)
    • Análisis descriptivo: identificar patrones y encontrar escenarios de análisis

  • NO hay una “receta”: el proceso es diferente con distintos datos o con los mismos datos para diferentes objetivos

  • Es un proceso iterativo para descubrir información

Primera aproximación a los datos

  • Contexto: conocimiento previo de nuestros datos, aquí o aquí

    • fuente (de dónde han salido), cómo están almacenados (.csv, .xlsx, …)

    • “diccionario”: información de cada variable (descripción, unidades, etc.)

  • Cargar los datos
Bank <- read_csv2("data/BankMarketing.csv")
Boston <- read_csv("data/BostonHousing.csv")
  • Reconocimiento inicial de las características de los datos: número de observaciones y de variables, tipo de cada variable, etc.
glimpse(Bank)  # str(Bank)
View(Bank)     # head(Bank)
  • NO TODO lo que hagamos se incluirá en un documento para comunicar

Primera aproximación a los datos (cont.)

  • Limpiar y procesar los datos para asegurar que son ordenados:

    • ¿Tienen las variables la información y el tipo adecuado? P.e.: job en Bank. Convertimos datos a factores, numéricas, etc.

    • Eliminar filas vacías, observaciones duplicadas

    • Renombrar variables (para mayor claridad), generar nuevas

    • Detectar inconsistencias en texto, fechas, unidades, etc.

    • ¿Mantenemos solo algunas variables u observaciones?
  • Caso destacado: identificar cuántos NAs en cada variable

Bank %>%  is.na() %>% summary()
Bank %>% summary()
load("data/earn.RData")
earn %>% is.na() %>% summary()
  • NO ES UNA RECETA: más adelante podemos volver atrás, para rehacer o tomar decisiones (qué hacer con NAs al modelizar)

Análisis de Variación (“univariante”)

  • La variación es la tendencia de los valores de una variable a cambiar entre medidas (p.e., educación de dos personas o ventas de dos empresas)

  • Las técnicas para analizar el patrón de variación, es decir, la distribución de valores, dependen del tipo de variable

  • Variables Categóricas (previamente convertidas a factores):

    • Conteos, Porcentajes, Moda
      • con summary(), table(), mode() o summarize(), count()
    • Visualización: Gráficos de Barras (también, quizás, circulares)
  • Variables Numéricas:

    • Estadísticas Descriptivas: Mínimo, Máximo, Media, Mediana, Moda
      • con summary() o summarize() con funciones para estadísticos
    • Dispersión: Rango, Varianza, Desviación Estándar, Cuartiles.
    • Visualización: Histogramas, Densidades, Boxplots.

Visualizando distribuciones

  • Variables Categóricas: gráficos de barras para conteos o porcentajes
g0 <- ggplot(data = Bank) 
g0 + geom_bar(aes(x = job)) + 
        theme(axis.text.x = element_text(angle = 90))
g0 + geom_bar( aes(x = "", fill = education))
Bank %>% count(education) %>% mutate(prop = n / sum(n)) %>% 
  ggplot() + geom_bar(aes(x = education, y = prop), stat = "identity")

Bank %>% ggplot(aes(x = education)) +
  geom_bar(aes(y = ..prop.., group = 1))
  • Para variables continuas, usar un histograma o densidad (o ambos)
g0 + geom_histogram(mapping = aes(x = age), binwidth = 5)
g0 + geom_density(mapping = aes(x = balance)) + scale_x_log10()
Boston %>%  ggplot(aes(x=medv)) + 
  geom_histogram(aes(y=..density..)) + geom_density() 
  • Consideramos varios anchos del intervalo: pueden revelar diferentes patrones
g0 + geom_histogram(mapping = aes(x = age), binwidth = 1)
g0 + geom_histogram(mapping = aes(x = age), binwidth = 10)

Visualizando distribuciones (cont.)

  • Los gráficos de caja también aportan información para distribuciones continuas
ggplot(Boston) + geom_boxplot(mapping = aes(y = medv))

Aspectos a prestar atención

  • Detectar inconsistencias en la distribución de valores o en las categorías: p.e., “unknown” en job de Bank

  • Valores frecuentes, concentración en valores concretos (p.e., ceros, números “redondos”, etc.): ¿por qué se producen? ¿son “esperables”?

  • ¿Tienen sentido las categorías de las variables cualitativas?
    • agrupar valores con pocas observaciones
    • crear categorías más “finas”o más agregadas (ej. de países a continentes)
  • ¿Sería preferible discretizar alguna variable continua? Ej., grupos de edad

  • Variables con alta dispersión o distribución asimétrica (logs?)

  • Variables con información redundante, homogeneizar valores, normalidad(?)
  • Valores inusuales (“atípicos” o “outliers”): no encajan en el patrón general

    • ¿cambian los resultados del análisis sin ellos? ¿Qué los ha causado?

Otras herramientas para AED

  • Para una primera aproximación automática , pero NO todas para incluir en un informe final: con las bibliotecas skimr (o modelsummary) y DataExplorer
library(skimr)
skim(Bank)        # ¿para incluir en un informe?
modelsummary::datasummary_skim(Bank)
library(DataExplorer)
plot_bar(Bank)        # para TODAS las variables categóricas
plot_histogram(Bank)  # para TODAS las variables numéricas
  • El paquete janitor contiene herramientas para limpieza de datos

  • La biblioteca dlookr ofrece heramientas para diagnóstico y exploración de datos (entre otras), devolviendo data frame (para usar con kable())

library(dlookr)     # en MacOS, puede pedir instalar XQuartz
Bank %>% diagnose()
Bank %>% describe() %>%
  select(described_variables, skewness, mean, p25, p50, p75) %>% 
  filter(!is.na(skewness)) %>% arrange(desc(abs(skewness)))
Bank %>% group_by(education) %>% 
  describe(age, balance, campaign, pdays) 

Bank %>% mutate(across(where(is.character), ~parse_factor(.x))) %>% 
  eda_web_report()

Análisis de Covariación (“multivariante”)

  • La variación describe el comportamiento dentro de una variable

  • La covariación describe relaciones entre variables: tendencia a que sus valores cambien juntos

  • Útil para formular modelos, que explican patrones complejos de los datos

    • ¿qué explica la relación sugerida por el patrón de covariación?

    • ¿cómo de fuerte es la relación?

    • ¿otras variables pueden afectar a la relación? ¿varían por subgrupos?

  • Covariación implica que los valores de una variable se pueden predecir a partir de otra

    • ¿es la covariación una relación causal?

Una variable continua y una categórica

  • ¿Es diferente la distribución de Y (continua) por categorías de X? Si \(\small{\Pr(Y|X=x_1) = \Pr(Y|X=x_0) = \Pr(Y)} \Rightarrow\) Y NO depende de X

1.- mediante el histograma o densidad (en el mismo gráfico o diferentes)

ggplot(Bank) + geom_density(aes(x = balance, color = default)) + 
  scale_x_log10()
ggplot(Bank) + geom_density(aes(x = balance)) + facet_wrap(~default) + 
  scale_x_log10()
ggplot(Bank) + geom_density(aes(x = balance, color = education)) + 
  scale_x_log10()
ggplot(Boston) + geom_density(aes(x=lstat, color=as.factor(chas))) 

2.- mediante gráficos de caja: menos información pero más fácil de comparar

ggplot(Boston) + geom_boxplot(aes(x=medv, y=as.factor(chas)))
ggplot(Bank) + geom_boxplot(aes(x=duration, y=as.factor(y)))
  • Si un grupo es mucho más pequeño, es difícil ver las diferencias

  • Se pueden necesitar reordenar las categorías de un factor, rotar los ejes, etc.

“Correlación” entre una variable continua y una categórica

  • La regresión simple también describe una relación: equivale a calcular la media de la variable continua por grupos definidos por la categórica

\[ E[Y|X]=\beta_0+\beta_1 X \Rightarrow \begin{cases} E[Y|X=0] &=\beta_0 \\ E[Y|X=1]&=\beta_0+\beta_1 \end{cases} \]

summary(lm(data = Bank, balance ~ education))
Bank %>% group_by(education) %>% summarise(media = mean(balance))

Bank %>% group_by(y) %>% summarise(media = mean(duration))
  • ¿Mediante la correlación? NO tiene sentido cuando una variable es categórica
  • Para variables dependientes categóricas veremos una variante de regresión lineal: regresión logística

Dos variables categóricas

  • Tabular o visualizar la frecuencia absoluta (conteo) para cada combinación
table(Bank$job, Bank$education)
Bank %>% count(job, education) %>% 
  pivot_wider(names_from = education, values_from = n)

Bank %>%  ggplot(aes(x=education)) + geom_bar(aes(fill=job)) 
Bank %>%  ggplot(aes(x=education)) + geom_bar(aes(fill=job), position="dodge")
  • O para las frecuencias relativas (proporciones)
table(Bank$job, Bank$education) %>% prop.table(margin = 2)
Bank %>% count(job, education) %>% 
  group_by(education) %>% mutate(prop= n/sum(n)) %>% select(-n) %>% 
  pivot_wider(names_from = education, values_from = prop)  

Bank %>% ggplot(aes(x=education)) + geom_bar(aes(fill=job), position = "fill") 

Bank %>% count(job, education) %>% 
  group_by(education) %>% mutate(prop= n/sum(n)) %>% 
  ggplot() + geom_bar(aes(x=education, y=prop, fill = job), 
                      stat = "identity")

Dos variables continuas

  • La forma obvia de visualizar relaciones entre variables continuas es un gráfico de dispersión; añadir smoothers ayuda a apreciar un patrón en los puntos
ggplot(Boston, aes(y=medv, x=lstat)) + geom_point() + geom_smooth()
ggplot(Boston, aes(y=medv, x=lstat)) + geom_point() + geom_smooth() +
  scale_y_log10()
  • Con la bibliteca GGally obtenemos una primera visión de conjunto
library(GGally)
Boston %>% select(-chas) %>% ggpairs()
  • Otra opción categorizar una variable continua y usar las técnicas anteriores
Bank %>% mutate(agegroup=cut(age, breaks=seq(20, 70, by=10))) %>% 
  ggplot()  + geom_boxplot(aes(x= balance, y =agegroup)) 

Correlación entre variables continuas

  • Podemos calcular modelos de regresión con dos variables continuas
summary(lm(data = Boston, medv ~ lstat) )
  • Y también correlaciones para dos o múltiples variables
cor(Boston$medv, Boston$lstat, use = "complete.obs")

library(dlookr)
Boston %>% correlate()
Boston %>% select(medv, lstat) %>%  correlate() 
Boston %>% group_by(chas) %>%  correlate() 
  • O visualizar las correlaciones
Boston %>% select(-chas) %>% correlate() %>% plot()

library(corrplot)
corrplot(cor(Boston))
corrplot.mixed(cor(Boston))

Más herramientas de AED “automático”

  • Muchas partes del AED son parcialmente “automatizables”: muchos paquetes tratan de facilitar esas partes

  • Radiant puede instalarse o probarse online

    • Sirve tanto para análisis exploratorio, visualización y transformación como para algunas modelizaciones
  • Algunas bibliotecas permiten explorar datos y/o realizar visualizaciones y tableros fácilmente de forma interactiva: GwalkR, explore

  • Informes automatizados con dlookr, DataExplorer, DataMaid, smartEDA
library(dlookr)
Bank %>% mutate(across(where(is.character), ~parse_factor(.x))) %>% 
  eda_web_report(target = "y")
  • Algunos componentes del AED y sobre todo la interpretación del AED son específica de los datos y del objetivo del estudio