---
title: "Medidas de heterogeneidad en Big Mart Sales"
pagetitle: "Medidas de heterogeneidad en Big Mart Sales"
open-graph:
description: "Aplica entropía y comparación entre grupos al dataset BigMart Sales para ver si las ventas cambian según categoría de producto o tipo de outlet."
twitter-card:
description: "Aplica entropía y comparación entre grupos al dataset BigMart Sales para ver si las ventas cambian según categoría de producto o tipo de outlet."
description: "Aplica entropía y comparación entre grupos al dataset BigMart Sales para ver si las ventas cambian según categoría de producto o tipo de outlet."
author: "Diego Villalba"
date: today
lang: es
number-sections: true
format:
html:
toc: true
toc-depth: 3
code-fold: true
code-tools: true
code-summary: "Mostrar código"
page-layout: full
pdf:
toc: true
jupyter: python3
bibliography: [referencias_eda.bib, ../../references.bib]
---
<!-- TODO: MENCIONAR QUE PARA UNA MEJRO COMPARACIÓN EN MEDIDAS DE HETEOOGENEIDAD ES NECESARIO COLOCAR LOS VALORES MAXIMOS A UNA COSTADO. -->
## Introducción
::: {.callout-tip appearance="minimal"}
Este caso aplica la diversidad categórica y la comparación entre grupos desarrolladas en [Medidas de heterogeneidad](2-6-heterogeneidad.qmd).
:::
Después de estudiar la localización, la variabilidad y la forma de las distribuciones, el análisis exploratorio de datos debe avanzar hacia una pregunta más estructural: **¿el comportamiento observado es homogéneo en toda la población o cambia de manera importante entre grupos?**. Esta cuestión introduce el concepto de **heterogeneidad**, una dimensión central del EDA cuando el dataset contiene segmentaciones naturales, como categorías de producto, tipos de tienda, tamaños de outlet o ubicaciones geográficas.
En términos estadísticos, la heterogeneidad alude a la existencia de diferencias sistemáticas entre subpoblaciones. Tales diferencias pueden expresarse en el centro de la distribución, en su dispersión, en su forma o incluso en la presencia diferencial de valores extremos. En un problema de negocio como BigMart, detectar heterogeneidad es indispensable, pues permite identificar si ciertos tipos de tiendas venden consistentemente más, si algunas categorías presentan patrones de ventas más variables, o si la estructura comercial cambia según el entorno del outlet.
En este capítulo se trabaja la heterogeneidad como una extensión natural del análisis univariado. La idea principal es que una variable numérica no debe interpretarse de manera aislada, sino también en relación con variables categóricas relevantes.
::: {.callout-note appearance="minimal"}
**Definición operativa.** La heterogeneidad aparece cuando la distribución de ventas cambia entre subgrupos o cuando la composición categórica presenta diversidad relevante [@shannon1948mathematical; @simpson1949measurement].
:::
## Preparación del entorno
Trabajaremos con el siguiente [dataset BigMart](../../data/bigmart_sales.csv), usando Python, pandas, NumPy y Plotly.
```{python}
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
DATA_PATH = "../../data/bigmart_sales.csv"
df = pd.read_csv(DATA_PATH)
df.head()
```
Conviene verificar las variables categóricas y numéricas del conjunto de datos.
```{python}
df.info()
```
```{python}
num_cols = df.select_dtypes(include=np.number).columns.tolist()
cat_cols = df.select_dtypes(exclude=np.number).columns.tolist()
num_cols, cat_cols
```
## Fundamentos teóricos
La heterogeneidad puede analizarse desde varias perspectivas. Si $Y$ es una variable numérica de interés y $G$ una variable categórica que define grupos, pueden estudiarse diferencias en:
### Centro por grupo
Se comparan medidas como:
$$
\bar{y}_g = \frac{1}{n_g}\sum_{i \in g} y_i,
$$
así como la mediana y otros cuantiles dentro de cada grupo $g$.
### Dispersión por grupo
La variabilidad interna de cada subpoblación puede resumirse mediante la desviación estándar, el rango intercuartílico o el coeficiente de variación. Dos grupos pueden tener medias semejantes y, sin embargo, diferir de forma sustancial en estabilidad o consistencia.
### Forma por grupo
La heterogeneidad también puede aparecer en la asimetría o en la presencia de colas pesadas. Algunos grupos pueden concentrarse en rangos estrechos y otros exhibir ventas con distribución muy extendida.
### Participación relativa de cada grupo
Finalmente, también es útil estudiar cuánto contribuye cada grupo al total de observaciones o al total de ventas. Esta dimensión conecta la heterogeneidad con el estudio posterior de la concentración.
## Variable objetivo y grupos de interés
En este capítulo tomaremos nuevamente como variable principal a $\texttt{Item\_Outlet\_Sales}$. Como ejes de segmentación se consideran, al menos, las siguientes variables categóricas:
- $\texttt{Outlet\_Type}$,
- $\texttt{Outlet\_Size}$,
- $\texttt{Outlet\_Location\_Type}$,
- $\texttt{Item\_Type}$.
Antes de comparar grupos, es útil revisar su tamaño.
```{python}
for col in ["Outlet_Type", "Outlet_Size", "Outlet_Location_Type", "Item_Type"]:
print(f"\n{col}")
print(df[col].value_counts(dropna=False))
```
Este paso es importante porque la interpretación de diferencias entre grupos debe considerar el tamaño muestral. Un grupo muy pequeño puede mostrar estadísticas inestables o aparentes extremos debidos a pocos casos.
## Heterogeneidad por tipo de outlet
Comenzamos con una variable de alto interés de negocio: $\texttt{Outlet\_Type}$.
```{python}
outlet_type_summary = (
df.groupby("Outlet_Type")["Item_Outlet_Sales"]
.agg(["count", "mean", "median", "std", "min", "max"])
.sort_values("mean", ascending=False)
)
outlet_type_summary
```
```{python}
fig = px.box(
df,
x="Outlet_Type",
y="Item_Outlet_Sales",
color="Outlet_Type",
title="Distribución de ventas por tipo de outlet"
)
fig.update_layout(showlegend=False)
fig.show()
```
```{python}
fig = px.bar(
outlet_type_summary.reset_index(),
x="Outlet_Type",
y="mean",
error_y="std",
title="Media y desviación estándar de ventas por tipo de outlet",
text_auto=True
)
fig.show()
```
A partir de este análisis se observa una **heterogeneidad clara por tipo de outlet**, lo que indica que `Outlet_Type` sí está asociado con diferencias relevantes en el nivel de ventas.
En primer lugar, `Supermarket Type3` destaca como el segmento con **mayor nivel de ventas**, tanto en la **media** (**3694.039**) como en la **mediana** (**3364.953**). Además, su boxplot se ubica claramente por encima del resto, lo que sugiere un desempeño consistentemente superior.
En segundo lugar, `Supermarket Type1` y `Supermarket Type2` presentan niveles de ventas **intermedios**, aunque `Supermarket Type1` muestra valores centrales algo mayores (**media = 2316.181**, **mediana = 1990.742**) que `Supermarket Type2` (**media = 1995.499**, **mediana = 1655.179**). Esto sugiere que, aunque ambos formatos son comparables, no tienen exactamente el mismo comportamiento comercial.
Por otro lado, `Grocery Store` aparece como el grupo con **menor nivel de ventas**, con una **media de 339.829** y una **mediana de 256.999**, muy por debajo de los supermercados. Esto revela una diferencia estructural importante entre este tipo de outlet y los demás.
En términos de **variabilidad**, `Supermarket Type3` también presenta la mayor dispersión (**std = 2127.760**), lo que indica que no solo vende más, sino que sus ventas son más heterogéneas. `Supermarket Type1` y `Supermarket Type2` también muestran dispersión considerable, mientras que `Grocery Store` tiene una variabilidad mucho menor en términos absolutos (**std = 260.852**), coherente con su escala de ventas más baja.
Los boxplots también muestran la presencia de **valores atípicos** en todos los grupos, especialmente en los supermercados. Esto sugiere que dentro de cada tipo de outlet existen productos o combinaciones producto-tienda con desempeños excepcionalmente altos.
En conjunto, este resultado tiene varias implicaciones para el EDA:
- `Outlet_Type` debe considerarse una **variable clave de segmentación**;
- no conviene analizar `Item_Outlet_Sales` como si proviniera de una sola población homogénea;
- es recomendable profundizar con comparaciones entre grupos, distribuciones segmentadas y medidas robustas;
- en etapas posteriores, `Outlet_Type` probablemente será una variable explicativa importante en cualquier análisis predictivo o inferencial.
En síntesis, el análisis muestra que el tipo de outlet introduce diferencias sustanciales tanto en el **nivel** como en la **dispersión** de las ventas, por lo que esta variable merece un lugar central dentro del EDA.
## Heterogeneidad por tamaño del outlet
El tamaño del outlet puede influir tanto en el volumen típico de ventas como en la dispersión observada.
```{python}
outlet_size_summary = (
df.groupby("Outlet_Size")["Item_Outlet_Sales"]
.agg(["count", "mean", "median", "std"])
.sort_values("mean", ascending=False)
)
outlet_size_summary
```
```{python}
fig = px.violin(
df,
x="Outlet_Size",
y="Item_Outlet_Sales",
color="Outlet_Size",
box=True,
points=False,
title="Ventas por tamaño de outlet"
)
fig.update_layout(showlegend=False)
fig.show()
```
Los violin plots son especialmente útiles aquí porque combinan información sobre dispersión y forma dentro de cada grupo. Si dos grupos tienen medianas parecidas pero densidades internas distintas, la heterogeneidad va más allá del simple promedio.
Este análisis también muestra **heterogeneidad por tamaño del outlet**, aunque con diferencias menos extremas que las observadas por `Outlet_Type`. Aun así, `Outlet_Size` aporta información relevante para el EDA porque parece asociarse tanto con el nivel típico de ventas como con su dispersión.
En primer lugar, los outlets de tamaño `Medium` presentan el mayor nivel de ventas, con una **media de 2681.604** y una **mediana de 2251.070**. Les siguen los outlets `High`, con **media = 2298.995** y **mediana = 2050.664`, mientras que los outlets `Small` muestran los valores más bajos (**media = 1912.149**, **mediana = 1544.656**). Esto sugiere que el tamaño del outlet sí introduce diferencias sistemáticas en el comportamiento comercial.
En términos de dispersión, `Medium` también presenta la mayor variabilidad (**std = 1855.211**), seguido por `Small` (**std = 1582.370**) y `High` (**std = 1533.532**). Los violin plots refuerzan esta idea al mostrar que no solo cambian los niveles centrales, sino también la forma interna de la distribución en cada grupo.
Para el EDA, esto tiene varias consecuencias:
- `Outlet_Size` debe considerarse una **variable relevante de segmentación**, ya que las ventas no parecen distribuirse igual entre tamaños de tienda;
- no basta con comparar solo promedios: la forma de los violines sugiere diferencias en **concentración, dispersión y densidad interna** entre grupos;
- conviene cruzar `Outlet_Size` con otras variables categóricas, especialmente `Outlet_Type`, para ver si parte de esta heterogeneidad se explica por la combinación entre ambas;
- en análisis posteriores, `Outlet_Size` puede funcionar como una **variable explicativa útil**, aunque probablemente con menor poder discriminante que `Outlet_Type`;
- dado que esta variable tenía valores faltantes en etapas previas, su papel analítico resulta todavía más importante, porque ayuda a decidir si conviene imputarla y preservarla en lugar de descartarla.
En síntesis, el tamaño del outlet no solo afecta el nivel típico de ventas, sino también la estructura de su distribución. Por ello, en el EDA conviene tratarlo como un factor de heterogeneidad relevante y no como una simple característica secundaria del establecimiento.
## Heterogeneidad por ubicación del outlet
Otra dimensión natural del análisis es $\texttt{Outlet\_Location\_Type}$, que puede reflejar diferencias territoriales o de mercado.
```{python}
location_summary = (
df.groupby("Outlet_Location_Type")["Item_Outlet_Sales"]
.agg(["count", "mean", "median", "std"])
.sort_values("mean", ascending=False)
)
location_summary
```
```{python}
fig = px.box(
df,
x="Outlet_Location_Type",
y="Item_Outlet_Sales",
color="Outlet_Location_Type",
title="Ventas por tipo de localización del outlet"
)
fig.update_layout(showlegend=False)
fig.show()
```
El análisis por `Outlet_Location_Type` revela también **heterogeneidad territorial en las ventas**, aunque con diferencias más moderadas que las observadas por tipo de outlet.
En términos de nivel central, `Tier 2` presenta el mayor promedio (**mean = 2323.991**, **median = 2004.058**), seguido muy de cerca por `Tier 3` (**mean = 2279.628**, **median = 1812.308**). En contraste, `Tier 1` muestra los valores más bajos (**mean = 1876.909**, **median = 1487.397**), lo que sugiere que las ventas tienden a ser menores en este tipo de localización.
En cuanto a la dispersión, `Tier 3` presenta la mayor variabilidad (**std = 1912.451**), lo que indica una mayor heterogeneidad en el desempeño de ventas dentro de este grupo. Los boxplots también muestran la presencia de **valores extremos** en todas las ubicaciones, especialmente en `Tier 3`.
Para el EDA, esto sugiere que:
- `Outlet_Location_Type` introduce **diferencias territoriales en el nivel de ventas**;
- `Tier 2` y `Tier 3` tienen comportamientos relativamente similares en el centro de la distribución, aunque `Tier 3` muestra mayor dispersión;
- `Tier 1` parece corresponder a ubicaciones con **menor desempeño promedio**;
- conviene explorar **interacciones entre ubicación, tipo y tamaño del outlet**, ya que parte de la heterogeneidad observada podría explicarse por la combinación de estas variables.
En síntesis, la localización del outlet añade otra dimensión de segmentación en el EDA y refuerza la idea de que las ventas no provienen de una población homogénea, sino de **subgrupos con comportamientos distintos**.
## Heterogeneidad por tipo de producto
La variable $\texttt{Item\_Type}$ suele contener más niveles que las anteriores, por lo que conviene resumir y ordenar cuidadosamente la información.
```{python}
item_type_summary = (
df.groupby("Item_Type")["Item_Outlet_Sales"]
.agg(["count", "mean", "median", "std"])
.sort_values("mean", ascending=False)
)
item_type_summary.head(10)
```
```{python}
fig = px.bar(
item_type_summary.reset_index(),
x="mean",
y=item_type_summary.reset_index()["Item_Type"],
orientation="h",
title="Media de ventas por tipo de producto",
labels={"mean": "Media de ventas", "y": "Tipo de producto"}
)
fig.show()
```
```{python}
top_item_types = item_type_summary.head(8).index.tolist()
fig = px.box(
df[df["Item_Type"].isin(top_item_types)],
x="Item_Type",
y="Item_Outlet_Sales",
color="Item_Type",
title="Distribución de ventas en los tipos de producto con mayor media"
)
fig.update_layout(showlegend=False)
fig.show()
```
El análisis por `Item_Type` muestra que también existe **heterogeneidad por categoría de producto**, aunque menos marcada que la observada por `Outlet_Type`. Aun así, las diferencias son suficientes para justificar una exploración segmentada.
En términos de promedio, las categorías con mayores ventas son `Starchy Foods` (**mean = 2374.333**), `Seafood` (**mean = 2326.066**) y `Fruits and Vegetables` (**mean = 2289.010**). Sin embargo, estas dos primeras tienen tamaños muestrales mucho menores (**148** y **64** observaciones, respectivamente), por lo que sus medias deben interpretarse con más cautela.
Entre las categorías con mayor presencia en el dataset, `Fruits and Vegetables` (**1232** casos), `Snack Foods` (**1200**) y `Household` (**910**) combinan **niveles altos de ventas** con una base de observaciones más sólida, lo que las vuelve especialmente relevantes para el EDA.
Los boxplots sugieren además que estas categorías no solo difieren en el nivel central, sino también en su **dispersión** y en la presencia de **valores extremos**. Por ejemplo, `Household`, `Fruits and Vegetables` y `Snack Foods` muestran colas superiores amplias y varios valores altos, lo que sugiere comportamientos heterogéneos dentro de cada tipo de producto.
Para el EDA, esto tiene varias implicaciones:
- `Item_Type` debe considerarse una **variable de segmentación importante**;
- conviene distinguir entre categorías con **muchas observaciones** y categorías con **poca representación**, para no sobredimensionar diferencias basadas en muestras pequeñas;
- resulta útil cruzar `Item_Type` con variables como `Outlet_Type` u `Outlet_Size`, ya que parte de la heterogeneidad podría depender de la interacción entre producto y tienda;
- en etapas posteriores, `Item_Type` puede aportar valor explicativo, pero probablemente con efecto desigual según la categoría.
En síntesis, el tipo de producto introduce diferencias reales en las ventas, pero su interpretación debe combinar **nivel de ventas**, **dispersión** y **tamaño muestral** para evitar conclusiones apresuradas.
## Tablas comparativas con múltiples indicadores
Una forma útil de sistematizar la heterogeneidad es construir tablas resumen que integren varias medidas por grupo.
```{python}
def group_profile(df, group_col, target="Item_Outlet_Sales"):
out = (
df.groupby(group_col)[target]
.agg(
n="count",
media="mean",
mediana="median",
desviacion="std",
q1=lambda x: x.quantile(0.25),
q3=lambda x: x.quantile(0.75)
)
.reset_index()
)
out["iqr"] = out["q3"] - out["q1"]
out["cv"] = out["desviacion"] / out["media"]
return out.sort_values("media", ascending=False)
profile_outlet_type = group_profile(df, "Outlet_Type")
profile_outlet_type
```
```{python}
profile_location = group_profile(df, "Outlet_Location_Type")
profile_location
```
Estas tablas permiten pasar de una observación visual a una descripción más precisa: no solo se identifican grupos “más altos” o “más bajos”, sino también grupos más o menos variables y con distinta estabilidad relativa.
## Heterogeneidad cruzada
En muchos problemas reales, la segmentación relevante no depende de una sola variable categórica. Una comparación cruzada, por ejemplo entre tipo de outlet y localización, ayuda a identificar patrones más finos.
```{python}
pivot_mean = pd.pivot_table(
df,
values="Item_Outlet_Sales",
index="Outlet_Type",
columns="Outlet_Location_Type",
aggfunc="mean"
)
pivot_mean
```
```{python}
fig = px.imshow(
pivot_mean,
text_auto=True,
aspect="auto",
title="Media de ventas: tipo de outlet vs localización"
)
fig.show()
```
La heterogeneidad cruzada muestra que una sola variable categórica no siempre basta para describir el comportamiento de las ventas. En este caso, la combinación entre `Outlet_Type` y `Outlet_Location_Type` permite detectar patrones más específicos que no se observan con la misma claridad al analizar cada variable por separado.
El resultado más visible es que `Supermarket Type3` en `Tier 3` presenta la media de ventas más alta (**3694.039**), mientras que `Grocery Store` mantiene niveles muy bajos tanto en `Tier 1` (**340.330**) como en `Tier 3` (**339.352**). Por su parte, `Supermarket Type1` muestra un comportamiento bastante estable entre ubicaciones, con medias de **2313.099** en `Tier 1`, **2323.991** en `Tier 2` y **2298.995** en `Tier 3`.
Para el EDA, esto tiene varias implicaciones:
- la variación en ventas no depende solo del tipo de outlet ni solo de la ubicación, sino de su **combinación**;
- `Supermarket Type1` parece ser un formato relativamente estable entre territorios, mientras que otros tipos están mucho más concentrados en ciertas ubicaciones;
- existen combinaciones ausentes (`NaN`), lo que indica que no todos los formatos de outlet están presentes en todas las localizaciones, y eso también forma parte de la estructura real del negocio;
- conviene seguir explorando **interacciones** entre variables categóricas, porque parte de la heterogeneidad puede estar oculta cuando se estudian los factores por separado;
- en etapas posteriores, estas combinaciones pueden ser útiles para construir variables explicativas más informativas que cada factor individual por sí solo.
En síntesis, este análisis refuerza una idea central del EDA: las ventas no provienen de grupos simples, sino de **segmentos combinados** donde el contexto del outlet importa tanto como su categoría individual.
## Entropía de Shannon como medida de heterogeneidad
Hasta ahora, la heterogeneidad se ha estudiado comparando promedios, medianas, dispersiones y distribuciones entre grupos. Sin embargo, también es útil contar con una medida **global** que resuma qué tan **diversificada** o **concentrada** está una variable categórica. Para ello puede utilizarse la **entropía de Shannon**.
Si una categoría concentra casi toda la masa de observaciones o de ventas, la entropía será baja. En cambio, si la distribución está más repartida entre varios grupos, la entropía será mayor. En este sentido, la entropía ofrece una medida sintética de diversidad.
En términos generales, para una variable categórica con proporciones $p_1, p_2, \dots, p_k$, la entropía se define como
$$
H = - \sum_{i=1}^{k} p_i \log(p_i)
$$
donde valores más altos indican mayor heterogeneidad. Como el valor máximo depende del número de categorías, también conviene trabajar con una **entropía normalizada**:
$$
H_{\text{norm}} = \frac{H}{\log(k)}
$$
De esta forma, el resultado queda entre 0 y 1:
- valores cercanos a **0** indican **alta concentración**;
- valores cercanos a **1** indican **alta diversidad**.
### Entropía de ventas por variable categórica
En esta sección calcularemos la entropía sobre la **distribución de ventas** agregadas por categoría, para responder preguntas como: ¿las ventas están repartidas entre muchos grupos o dependen de unos pocos?
```{python}
import numpy as np
import pandas as pd
vars_cat_heterogeneidad = [
"Outlet_Type",
"Outlet_Size",
"Outlet_Location_Type",
"Item_Type"
]
def shannon_entropy_from_sales(df, cat_var, sales_var="Item_Outlet_Sales"):
sales_by_group = df.groupby(cat_var)[sales_var].sum().dropna()
p = sales_by_group / sales_by_group.sum()
h = -(p * np.log(p)).sum()
h_norm = h / np.log(len(p)) if len(p) > 1 else np.nan
return pd.Series({
"n_categorias": len(p),
"entropia": h,
"entropia_normalizada": h_norm
})
entropy_table = pd.DataFrame({
var: shannon_entropy_from_sales(df, var)
for var in vars_cat_heterogeneidad
}).T.reset_index(names="variable")
entropy_table.sort_values("entropia_normalizada", ascending=False).round(4)
```
La interpretación debe hacerse con cuidado. Una entropía alta no significa necesariamente “mejor”, sino simplemente que las ventas están más repartidas entre las categorías de esa variable. Una entropía baja, en cambio, sugiere que el negocio está más concentrado en unos pocos segmentos.
```{python}
import plotly.express as px
entropy_plot = entropy_table.sort_values("entropia_normalizada", ascending=True)
fig = px.bar(
entropy_plot,
x="entropia_normalizada",
y="variable",
orientation="h",
text="entropia_normalizada",
title="Entropía normalizada de Shannon por variable categórica",
labels={
"entropia_normalizada": "Entropía normalizada",
"variable": "Variable categórica"
},
range_x=[0, 1]
)
fig.update_traces(texttemplate="%{text:.3f}", textposition="outside")
fig.update_layout(height=450, width=900)
fig.show()
```
Si se desea profundizar en una variable concreta, también puede visualizarse directamente la distribución de las ventas agregadas por categoría. Por ejemplo, para Item_Type:
```{python}
sales_item_type = (
df.groupby("Item_Type")["Item_Outlet_Sales"]
.sum()
.sort_values(ascending=False)
.reset_index()
)
sales_item_type["proporcion"] = (
sales_item_type["Item_Outlet_Sales"] /
sales_item_type["Item_Outlet_Sales"].sum()
)
fig = px.bar(
sales_item_type,
x="Item_Type",
y="proporcion",
text="proporcion",
title="Proporción de ventas por tipo de producto",
labels={
"Item_Type": "Tipo de producto",
"proporcion": "Proporción de ventas"
}
)
fig.update_traces(texttemplate="%{text:.3f}", textposition="outside")
fig.update_layout(xaxis_tickangle=45, height=500, width=950)
fig.show()
```
Los resultados de entropía sugieren que no todas las variables categóricas aportan el mismo tipo de segmentación para el EDA. En particular, `Outlet_Location_Type` presenta la **mayor entropía normalizada** (**0.9792**), seguido por `Item_Type` (**0.9078**) y `Outlet_Size` (**0.8990**). Esto indica que, en estas variables, las ventas están **bastante repartidas** entre sus categorías y no dependen fuertemente de un solo grupo.
En cambio, `Outlet_Type` muestra una entropía normalizada claramente menor (**0.6298**), lo que sugiere una **mayor concentración** de las ventas en unos pocos tipos de outlet. Esto es coherente con los análisis previos, donde se observó que ciertos formatos, especialmente `Supermarket Type3` y `Supermarket Type1`, concentran gran parte del volumen de ventas.
Para el EDA, esto tiene varias implicaciones:
- `Outlet_Type` aparece como una variable especialmente útil para detectar **concentración comercial**, ya que distingue grupos con pesos muy desiguales en el negocio;
- `Outlet_Location_Type`, `Outlet_Size` e `Item_Type` reflejan una estructura más **diversificada**, por lo que su utilidad analítica está menos en la concentración y más en comparar patrones internos entre categorías;
- una entropía alta no elimina la heterogeneidad, sino que indica que el negocio está más repartido entre grupos, por lo que conviene profundizar con medidas de nivel, dispersión y forma dentro de cada categoría;
- el gráfico de proporciones por `Item_Type` muestra que, aunque la distribución es bastante diversa, algunas categorías como `Fruits and Vegetables` (**0.152**) y `Snack Foods` (**0.147**) tienen un peso algo mayor que otras, por lo que pueden merecer atención especial en análisis posteriores.
En síntesis, la entropía complementa el EDA porque ayuda a distinguir entre variables que describen un negocio **más concentrado** y variables que describen un negocio **más distribuido**. En este caso, `Outlet_Type` parece ser la variable más útil para estudiar concentración, mientras que `Item_Type`, `Outlet_Size` y `Outlet_Location_Type` son más útiles para explorar diversidad y segmentación interna.
::: {.callout-important appearance="minimal"}
La entropía anterior describe diversidad de participaciones. El coeficiente de Gini basado en la curva de Lorenz responde específicamente a desigualdad y se desarrolla, con su fórmula corregida, en [Medidas de concentración en Big Mart Sales](2-7-concentracion_bigmart.qmd).
:::
## Mini-dashboard de heterogeneidad
A continuación se construye un dashboard compacto que integra varias vistas segmentadas.
```{python}
from plotly.subplots import make_subplots
fig = make_subplots(
rows=2,
cols=2,
subplot_titles=(
"Media por tipo de outlet",
"Media por tamaño de outlet",
"Media por localización",
"Top 8 tipos de producto"
)
)
summary1 = group_profile(df, "Outlet_Type")
summary2 = group_profile(df.dropna(subset=["Outlet_Size"]), "Outlet_Size")
summary3 = group_profile(df, "Outlet_Location_Type")
summary4 = group_profile(df, "Item_Type").head(8)
fig.add_trace(
go.Bar(x=summary1["Outlet_Type"], y=summary1["media"], name="Outlet Type"),
row=1, col=1
)
fig.add_trace(
go.Bar(x=summary2["Outlet_Size"], y=summary2["media"], name="Outlet Size"),
row=1, col=2
)
fig.add_trace(
go.Bar(x=summary3["Outlet_Location_Type"], y=summary3["media"], name="Location"),
row=2, col=1
)
fig.add_trace(
go.Bar(x=summary4["Item_Type"], y=summary4["media"], name="Item Type"),
row=2, col=2
)
fig.update_layout(
title="Dashboard básico de heterogeneidad en BigMart",
height=750,
showlegend=False
)
fig.show()
```
## Conclusiones del capítulo
En este capítulo se mostró que la heterogeneidad constituye una dimensión esencial del análisis exploratorio de datos. Comparar grupos permite ampliar la descripción estadística de una variable y pasar de una lectura global a una interpretación segmentada y contextual.
En el dataset de BigMart, la heterogeneidad se manifiesta en diferencias entre tipos de outlet, tamaños, localizaciones y categorías de producto. Estas comparaciones enriquecen el EDA porque permiten distinguir subestructuras internas del fenómeno, identificar patrones consistentes y detectar segmentos con comportamientos contrastantes.
Este capítulo prepara de manera natural el siguiente paso del proyecto: el estudio de la **concentración**, donde se analizará si una fracción reducida de grupos, productos o outlets explica una proporción sustancial del total de ventas.