- Cargué y revisé la estructura de una tabla de 15.000 filas y 12 columnas.
- Corregí el tipo de edad y documenté el significado de cada variable.
- Exploré distribuciones, outliers, indicadores binarios, dispositivos y regiones.
- Construí matrices Pearson y Spearman y un PairGrid con color por región.
- Visualicé los pares visitas–ingreso anual y compras–ingreso anual.
- Calculé punto-biserial y V de Cramér para tipos de variables distintos.
- Traducí los resultados en hallazgos no causales, limitaciones y próximos pasos.
NovaRetail+:
explorando drivers de comportamiento
Analicé 15.000 registros de clientes para identificar qué comportamientos se asocian con el ingreso anual generado. Compras, visitas, publicidad y premium se contrastan con evidencia visual y numérica, sin confundir correlación con causalidad.
Resumen del proyecto
Una base completa de 15.000 registros, cuatro métodos de asociación y una pregunta central: qué comportamientos se relacionan con el ingreso generado para NovaRetail+.
Mi aporte fue organizar la exploración del comportamiento del cliente en una secuencia reproducible: entender la calidad del dataset, elegir un coeficiente según el tipo de variable y contrastar las cifras con gráficos.
Diferencié el ingreso estimado del cliente del ingreso que genera para la empresa. También separé el tamaño de una asociación de su posible relevancia comercial.
| Campo | Tipo / función | Significado |
|---|---|---|
id_cliente | Identificador | Código del cliente; no se usa para correlacionar. |
edad | Numérica · entero | Edad en años; se convirtió de float64 a int64. |
nivel_ingreso | Numérica | Ingreso anual estimado del cliente, distinto del revenue que genera. |
visitas_mes | Numérica · conteo | Visitas durante el mes a la app o al sitio web. |
compras_mes | Numérica · conteo | Compras realizadas durante el mes. |
gasto_publicidad_dirigida | Numérica | Gasto en anuncios asignado al usuario. |
satisfaccion | Numérica · escala | Calificación del cliente de 1 a 5. |
miembro_premium | Binaria | 1 = premium; 0 = no premium. |
abandono | Binaria | 1 = abandonó la plataforma; 0 = no. |
tipo_dispositivo | Categórica | Móvil, escritorio o tablet. |
region | Categórica | Norte, oeste, sur o este. |
ingreso_anual | Numérica · objetivo | Ingreso anual generado por el cliente para NovaRetail+. |
Ver resumen estadístico completo de las variables numéricas
| Variable | Media | Mediana | Mínimo | Máximo | Q1 / Q3 |
|---|---|---|---|---|---|
| Edad | 38,26 | 38,00 | 18,00 | 75,00 | 30,00 / 46,00 |
| Ingreso estimado del cliente | 30.019,70 | 30.023,74 | 8.000,00 | 74.790,84 | 23.127,10 / 36.768,44 |
| Visitas del mes | 10,03 | 10,00 | 1,00 | 25,00 | 8,00 / 12,00 |
| Compras del mes | 1,21 | 1,00 | 0,00 | 8,00 | 0,00 / 2,00 |
| Gasto publicitario dirigido | 20,15 | 19,73 | 0,00 | 75,51 | 12,31 / 27,29 |
| Satisfacción | 3,60 | 3,60 | 1,00 | 5,00 | 3,10 / 4,10 |
| Ingreso anual para la empresa | 36,59 | 30,70 | 0,00 | 244,69 | 0,00 / 58,22 |
Valores de describe() y medianas guardados en la celda 19. Las unidades monetarias de ingreso_anual no se especifican de forma explícita en el diccionario; se conservan sus valores sin atribuirles una moneda. No se calcula una tasa de conversión con la razón entre medias de compras y visitas.
Proceso analítico, sección a sección
Las seis secciones del notebook se mantienen en el orden original. Cada bloque explica lo realizado, las cifras relevantes y el código disponible para revisarlo.
Sección 1. Cargar y explorar el dataset
Importé Pandas, NumPy, Seaborn y Matplotlib. Cargué novaretail_comportamiento_clientes_2024.csv con pd.read_csv() y revisé la estructura mediante info() y las primeras cinco filas con head(5).
Las doce columnas muestran 15.000 valores no nulos. El índice va de 0 a 14.999: el total es 15.000 filas, no 14.999. El análisis utiliza todo el conjunto disponible.
Ver código y salidas guardadas de esta sección
Celda 7 · código original
# Importar librerías
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
Sin salida textual adicional guardada. Las figuras y matrices se incluyen en la galería.
Celda 9 · código original
# Cargar el dataset y explorar datos
# df = pd.read_csv("https://drive.google.com/uc?export=download&id=1-eHDkD0ZapRUKZ2zoWojNzT-Ufy_nqX9") (CODIGO AUXILIAR WEB DIRECTO)
df = pd.read_csv("/datasets/novaretail_comportamiento_clientes_2024.csv")
df.info()<class 'pandas.core.frame.DataFrame'> RangeIndex: 15000 entries, 0 to 14999 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id_cliente 15000 non-null object 1 edad 15000 non-null float64 2 nivel_ingreso 15000 non-null float64 3 visitas_mes 15000 non-null int64 4 compras_mes 15000 non-null int64 5 gasto_publicidad_dirigida 15000 non-null float64 6 satisfaccion 15000 non-null float64 7 miembro_premium 15000 non-null int64 8 abandono 15000 non-null int64 9 tipo_dispositivo 15000 non-null object 10 region 15000 non-null object 11 ingreso_anual 15000 non-null float64 dtypes: float64(5), int64(4), object(3) memory usage: 1.4+ MB
Celda 11 · código original
# mostrar las primeras 5 filas
df.head(5)| id_cliente | edad | nivel_ingreso | visitas_mes | compras_mes | gasto_publicidad_dirigida | satisfaccion | miembro_premium | abandono | tipo_dispositivo | region | ingreso_anual | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | CL-100000 | 44.0 | 28565.77 | 9 | 1 | 31.36 | 3.9 | 0 | 0 | móvil | norte | 23.22 |
| 1 | CL-100001 | 36.0 | 29673.44 | 11 | 3 | 24.66 | 3.7 | 0 | 0 | tablet | sur | 93.47 |
| 2 | CL-100002 | 46.0 | 30642.95 | 9 | 0 | 0.00 | 2.9 | 0 | 0 | móvil | este | 0.00 |
| 3 | CL-100003 | 56.0 | 39468.61 | 8 | 0 | 6.81 | 3.1 | 0 | 0 | móvil | este | 0.00 |
| 4 | CL-100004 | 35.0 | 22527.83 | 9 | 2 | 26.49 | 2.3 | 0 | 0 | móvil | sur | 33.76 |
Sección 2. Preparar datos y documentar supuestos
Convertí edad de float64 a int64 y verifiqué el cambio. Separé las variables por tipo: siete numéricas, dos binarias y dos categóricas. Dejé id_cliente como identificador, fuera de los cálculos de asociación.
Calculé describe(), medianas y frecuencias. Definí funciones para generar histogramas y boxplots por variable, y countplots de dispositivos y regiones. No imputé nulos ni eliminé filas: las salidas no muestran valores faltantes.
Validé edades de 18 a 75 años, satisfacción entre 1 y 5, y variables binarias codificadas como 0/1. Se conservan valores cero plausibles en compras, publicidad e ingreso anual.
| Tipo | Método utilizado | Lectura |
|---|---|---|
| Numérica–numérica | Pearson / Spearman | Relación lineal / monótona |
| Binaria–numérica | Punto-biserial | Asociación del indicador con una variable numérica |
| Categórica–categórica | V de Cramér | Intensidad de asociación, sin signo |
Ver código y salidas guardadas de esta sección
Celda 16 · código original
# Corregir el tipo de dato
df['edad'] = df['edad'].astype('int64')
Sin salida textual adicional guardada. Las figuras y matrices se incluyen en la galería.
Celda 17 · código original
# verificar cambios
df.info()<class 'pandas.core.frame.DataFrame'> RangeIndex: 15000 entries, 0 to 14999 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id_cliente 15000 non-null object 1 edad 15000 non-null int64 2 nivel_ingreso 15000 non-null float64 3 visitas_mes 15000 non-null int64 4 compras_mes 15000 non-null int64 5 gasto_publicidad_dirigida 15000 non-null float64 6 satisfaccion 15000 non-null float64 7 miembro_premium 15000 non-null int64 8 abandono 15000 non-null int64 9 tipo_dispositivo 15000 non-null object 10 region 15000 non-null object 11 ingreso_anual 15000 non-null float64 dtypes: float64(4), int64(5), object(3) memory usage: 1.4+ MB
Celda 19 · código original
# Estadísticas descriptivas de variables numéricas
variables_numericas = ['edad', 'nivel_ingreso', 'visitas_mes', 'compras_mes', 'gasto_publicidad_dirigida', 'satisfaccion', 'ingreso_anual']
variables_binarias = ['miembro_premium', 'abandono']
variables_categoricas = ['tipo_dispositivo', 'region']
print(df[variables_numericas].describe())
print()
print('Medianas de cada columna')
print(df[variables_numericas].median())
def distribuciones(df, columnas):
for col in columnas:
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
sns.histplot(data=df, x=col, bins=20, hue='tipo_dispositivo', kde=True, ax=axes[0])
axes[0].axvline(x=df[col].mean(), color='red', linestyle='--', label='Media')
axes[0].set_title(f"Distribución de los valores en {col}")
axes[0].set_xlabel(f"Rango de {col}")
axes[0].set_ylabel("Repeticiones")
sns.boxplot(df[col], ax=axes[1])
axes[1].set_title(f"Distribución de outliers en {col}")
axes[1].set_xlabel(f"Rango de {col}")
axes[1].set_ylabel("Repeticiones")
return plt.show()
distribuciones(df, variables_numericas)
edad nivel_ingreso visitas_mes compras_mes \
count 15000.000000 15000.000000 15000.000000 15000.000000
mean 38.262400 30019.704782 10.029000 1.206467
std 11.492378 9833.166305 3.158189 1.105284
min 18.000000 8000.000000 1.000000 0.000000
25% 30.000000 23127.097500 8.000000 0.000000
50% 38.000000 30023.745000 10.000000 1.000000
75% 46.000000 36768.440000 12.000000 2.000000
max 75.000000 74790.840000 25.000000 8.000000
gasto_publicidad_dirigida satisfaccion ingreso_anual
count 15000.000000 15000.000000 15000.000000
mean 20.149301 3.603693 36.594180
std 10.880724 0.685300 34.484888
min 0.000000 1.000000 0.000000
25% 12.310000 3.100000 0.000000
50% 19.730000 3.600000 30.705000
75% 27.292500 4.100000 58.220000
max 75.510000 5.000000 244.690000
Medianas de cada columna
edad 38.000
nivel_ingreso 30023.745
visitas_mes 10.000
compras_mes 1.000
gasto_publicidad_dirigida 19.730
satisfaccion 3.600
ingreso_anual 30.705
dtype: float64
Celda 22 · código original
# Verificar que cada columna tenga únicamente dos valores posibles
print(df[variables_binarias].describe())
print()
print(df[variables_binarias].value_counts(normalize=True))
print()
print(df[variables_binarias].nunique())
miembro_premium abandono
count 15000.000000 15000.000000
mean 0.139267 0.150733
std 0.346236 0.357801
min 0.000000 0.000000
25% 0.000000 0.000000
50% 0.000000 0.000000
75% 0.000000 0.000000
max 1.000000 1.000000
miembro_premium abandono
0 0 0.716067
1 0.144667
1 0 0.133200
1 0.006067
dtype: float64
miembro_premium 2
abandono 2
dtype: int64
Celda 25 · código original
# Verificar el número de valores únicos por variable categórica
print(df[variables_categoricas].describe())
print()
print(df[variables_categoricas].nunique())tipo_dispositivo region count 15000 15000 unique 3 4 top móvil norte freq 9818 4395 tipo_dispositivo 3 region 4 dtype: int64
Celda 26 · código original
# Explorar variables categóricas y cómo se distribuyen
print(df[variables_categoricas].value_counts()) # frecuencia absoluta
print('____________________________')
print(df[variables_categoricas].value_counts(normalize=True)) # frecuencia relativa (porcentaje)
def graficar_cat(df, columnas):
for col in columnas:
otra_col = [c for c in columnas if c != col][0]
plt.figure()
sns.countplot(data=df, x=col, hue=otra_col)
return plt.show()
graficar_cat(df, variables_categoricas)tipo_dispositivo region
móvil norte 2843
oeste 2489
sur 2483
este 2003
escritorio norte 1125
oeste 935
sur 894
este 766
tablet norte 427
oeste 386
sur 349
este 300
dtype: int64
____________________________
tipo_dispositivo region
móvil norte 0.189533
oeste 0.165933
sur 0.165533
este 0.133533
escritorio norte 0.075000
oeste 0.062333
sur 0.059600
este 0.051067
tablet norte 0.028467
oeste 0.025733
sur 0.023267
este 0.020000
dtype: float64
Sección 3. Visualizar las relaciones
Construí matrices con corr(method="pearson") y corr(method="spearman"), presentadas con Styler.background_gradient(cmap="coolwarm"). Estas son tablas HTML coloreadas originales, no imágenes estáticas.
Generé un PairGrid de siete variables, puntos diferenciados por región y líneas de regresión global fuera de la diagonal. Después destaqué dos scatterplots: visitas del mes frente al ingreso anual y compras del mes frente al ingreso anual.
El primer par presenta una relación positiva limitada y mayor dispersión; el segundo muestra una asociación muy fuerte. Las líneas son descriptivas: no representan un modelo predictivo validado ni un efecto causal.
La relación publicidad–visitas aparece en ambas matrices y en el PairGrid. No existe un scatterplot independiente guardado para ese par en la versión adjunta.
Ver código y salidas guardadas de esta sección
Celda 32 · código original
# Visualizar la matriz de correlación para identificar relaciones
def corr_numerica(df, columnas, metodo="pearson"):
matriz = df[columnas].corr(method=metodo)
return matriz.style.background_gradient(cmap="coolwarm")
# CODIGO MANUAL
#corr = df[variables_numericas].corr(method='pearson')
# corr.style.background_gradient(cmap="coolwarm") CODIGO AUXILIAR SIN IMAGEN
#plt.figure(figsize=(10,6))
#sns.heatmap(corr, annot=True, cmap="coolwarm", center=0)
#plt.title("Correlation Heatmap — NovaRetail+")
#plt.show()
#Codigo con Imagen
#def corr_numerica_imagen(df, columnas, metodo="pearson"):
# matriz = df[columnas].corr(method=metodo)
# plt.figure(figsize=(10,6))
# sns.heatmap(matriz, annot=True, cmap="coolwarm", center=0)
# plt.title(f"Correlation Heatmap Variables Numericas")
# return plt.show()
#corr_numerica_imagen(df, variables_numericas, metodo="pearson")Sin salida textual adicional guardada. Las figuras y matrices se incluyen en la galería.
Celda 33 · código original
corr_numerica(df, variables_numericas, metodo="pearson")<pandas.io.formats.style.Styler at 0x7ff69ccafe20>
Celda 34 · código original
corr_numerica(df, variables_numericas, metodo="spearman")<pandas.io.formats.style.Styler at 0x7ff6b29b5940>
Celda 38 · código original
#sns.pairplot(df, vars=variables_numericas, hue='region', kind='scatter') CODIGO DEL BOOTCAMP
# Paso 1: Crear el PairGrid (CODIGO DADO POR IA)
pg = sns.PairGrid(df, vars=variables_numericas, hue='region')
# Paso 2: Dibujar los puntos con color por región
pg.map_offdiag(sns.scatterplot)
# Paso 3: Recorrer cada subgráfico y agregar regresión global
for i, var_y in enumerate(variables_numericas):
for j, var_x in enumerate(variables_numericas):
if i != j: # solo fuera de la diagonal
sns.regplot(data=df, x=var_x, y=var_y,
scatter=False, ax=pg.axes[i][j],
color='black', line_kws={'linewidth': 1.5})
pg.add_legend()
plt.show()Sin salida textual adicional guardada. Las figuras y matrices se incluyen en la galería.
Celda 40 · código original
# Visualizar pares de variables con relaciones moderadas o fuertes
# Crear scatterplot
sns.scatterplot(data=df,x="visitas_mes", y="ingreso_anual", hue='region')
# Crear línea de tendencia
sns.regplot(data=df, x='visitas_mes', y='ingreso_anual',
scatter=False, color='black')<AxesSubplot:xlabel='visitas_mes', ylabel='ingreso_anual'>
Celda 41 · código original
# Crear scatterplot
sns.scatterplot(data=df,x="compras_mes", y="ingreso_anual", hue='region')
# Crear línea de tendencia
sns.regplot(data=df, x='compras_mes', y='ingreso_anual',
scatter=False, color='black')<AxesSubplot:xlabel='compras_mes', ylabel='ingreso_anual'>
Sección 4. Calcular coeficientes y evidencia numérica
Respaldé los patrones visuales con coeficientes adecuados para cada tipo de variable. Reporté Pearson y Spearman para los dos pares principales, y revisé los restantes pares en las matrices.
| Par de variables | Pearson | Spearman | Lectura descriptiva |
|---|---|---|---|
| Compras → ingreso anual | 0,967 | 0,967 | Muy fuerte, positiva |
| Visitas → ingreso anual | 0,337 | 0,321 | Positiva, limitada |
| Publicidad → visitas | 0,579 | 0,559 | Moderada, positiva |
| Publicidad → ingreso anual | 0,197 | 0,185 | Débil, positiva |
| Ingreso estimado → ingreso anual | 0,017 | 0,025 | Cercana a cero |
| Satisfacción → ingreso anual | 0,056 | 0,061 | Muy pequeña |
Con scipy.stats.pointbiserialr evalué las variables binarias frente a variables numéricas. Premium–ingreso anual dio 0,0931; abandono–ingreso anual, −0,0028. Con pd.crosstab() y chi2_contingency() calculé V de Cramér para dispositivo–región: 0,012378.
El código generaliza el punto-biserial a las columnas numéricas, pero la salida guardada solo contiene seis por indicador: no aparece nivel_ingreso. No inventé ese resultado faltante.
Ver código y salidas guardadas de esta sección
Celda 46 · código original
# Calcular correlación entre variables relevantes
corr_pearson = df['visitas_mes'].corr(df['ingreso_anual'], method='pearson')
corr_spearman = df['visitas_mes'].corr(df['ingreso_anual'], method='spearman')
print(f"Correlacion entre: visitas_mes y ingreso_anual")
print(f"Pearson: {corr_pearson:.3f}") #La correlación Pearson evalúa relación lineal
print(f"Spearman: {corr_spearman:.3f}") #La correlación Spearman evalúa consistencia (monotonía)
Correlacion entre: visitas_mes y ingreso_anual Pearson: 0.337 Spearman: 0.321
Celda 47 · código original
# Calcular correlación entre variables relevantes
corr_pearson = df['compras_mes'].corr(df['ingreso_anual'], method='pearson')
corr_spearman = df['compras_mes'].corr(df['ingreso_anual'], method='spearman')
print(f"Correlacion entre: compras_mes y ingreso_anual")
print(f"Pearson: {corr_pearson:.3f}")
print(f"Spearman: {corr_spearman:.3f}")
Correlacion entre: compras_mes y ingreso_anual Pearson: 0.967 Spearman: 0.967
Celda 50 · código original
# Calcular correlacion Punto-biserial: estado suscripcion ingresos mensuales
# Punto-biserial compara dos grupos (premium / no premium)
# contra una variable numérica.
#El coeficiente indica si existe diferencia entre ambos grupos,
#no causalidad
from scipy.stats import pointbiserialr
# Codificar suscripción (CODIGO EN CASO DE QUE APLIQUE. EN ESTE CASO EL DATASET YA ESTABA CONFIGURADO)
#df["estado_suscripcion_bin"] = df["estado_suscripcion"].replace({
# "Yes": 1,
# "No": 0
#})
def corr_point_biserial(df, col_binarias, col_numericas):
for col_b in col_binarias:
print(f"\nCorrelacion de la variable binaria {col_b}")
for col_n in col_numericas:
coef, p_value = pointbiserialr(df[col_b],df[col_n])
print(f"\ncon la variable {col_n}")
print(f"Point-Biserial: {coef:.4f}")
print(f"p-value: {p_value:.4f}")
print('_________________________________________________________________________')
corr_point_biserial(df, variables_binarias, variables_numericas)Correlacion de la variable binaria miembro_premium con la variable edad Point-Biserial: 0.0046 p-value: 0.5728 con la variable visitas_mes Point-Biserial: -0.0127 p-value: 0.1211 con la variable compras_mes Point-Biserial: 0.0034 p-value: 0.6744 con la variable gasto_publicidad_dirigida Point-Biserial: 0.0027 p-value: 0.7390 con la variable satisfaccion Point-Biserial: 0.0257 p-value: 0.0016 con la variable ingreso_anual Point-Biserial: 0.0931 p-value: 0.0000 _________________________________________________________________________ Correlacion de la variable binaria abandono con la variable edad Point-Biserial: -0.0115 p-value: 0.1590 con la variable visitas_mes Point-Biserial: -0.0089 p-value: 0.2734 con la variable compras_mes Point-Biserial: 0.0083 p-value: 0.3099 con la variable gasto_publicidad_dirigida Point-Biserial: -0.0046 p-value: 0.5744 con la variable satisfaccion Point-Biserial: -0.0238 p-value: 0.0035 con la variable ingreso_anual Point-Biserial: -0.0028 p-value: 0.7295 _________________________________________________________________________
Celda 53 · código original
# Función mejorada y generalizable para calcular V de Cramér
from scipy.stats import chi2_contingency
def cramer_v(df, col_cat):
for i, col_1 in enumerate(col_cat):
for col_2 in col_cat[i+1:]:
print(f"\nCorrelacion de la variable categorica {col_1}")
# tabla de contingencia
tabla = pd.crosstab(df[col_1], df[col_2])
# calcular chi-cuadrado
chi2, p_value, dof, expected = chi2_contingency(tabla)
# calcular coeficiente V de Cramér
n = tabla.values.sum()
v = np.sqrt(chi2 / (n * (min(tabla.shape) -1)))
print(f"\ncon la variable {col_2}:")
print(v)
print('_________________________________')
Sin salida textual adicional guardada. Las figuras y matrices se incluyen en la galería.
Celda 54 · código original
# Aplicar V de Cramér en variables relevantes
cramer_v(df, variables_categoricas)
Correlacion de la variable categorica tipo_dispositivo con la variable region: 0.012378338407739397 _________________________________
Sección 5. Interpretar resultados para el negocio
Documenté tres hallazgos siguiendo la estructura del notebook: evidencia visual, evidencia numérica, interpretación no causal, qué no puede afirmarse e implicación de negocio.
- Las visitas del mes se asocian con el ingreso anual, pero de forma limitada: Pearson 0,337 y Spearman 0,321.
- El gasto publicitario se asocia moderadamente con las visitas: Pearson 0,579 y Spearman 0,559.
- La condición premium tiene una asociación positiva pequeña con el ingreso anual: punto-biserial 0,0931.
La página también destaca el par compras–ingreso anual, porque es el vínculo más fuerte de las matrices y de los gráficos clave: Pearson 0,967 y Spearman 0,967. Ese destacado sintetiza resultados existentes; no añade un análisis nuevo.
Sección 6. Reconocer limitaciones y próximos pasos
Reconocí variables no controladas —campañas, antigüedad y promociones— y la posibilidad de efectos distintos por segmento. Propuse profundizar por dispositivo, región, premium, abandono y nivel de ingreso estimado.
Planteé comparar asociaciones globales con asociaciones por grupo para detectar cambios compatibles con una paradoja de Simpson. No afirmé que esa paradoja esté demostrada.
Como siguiente fase, propuse analizar el embudo visitas → compras → ingreso y diseñar pruebas A/B sobre publicidad dirigida. El notebook no ejecuta esos experimentos ni calcula su impacto causal.
El proyecto se documentó en la versión revisada del notebook y en GitHub. Esta web organiza el material para portafolio, conserva las figuras y permite descargar el archivo adjunto.
Ver código y salidas guardadas de esta sección
Celda 63 · código original
"Link del repositorio: https://github.com/andaba2101/NovaRetail_Correlational_analysis.git"'Link del repositorio: https://github.com/andaba2101/NovaRetail_Correlational_analysis.git'
Hallazgos y evidencia de negocio
Los tres hallazgos escritos en el notebook se conservan, junto con el destacado de compras–ingreso anual obtenido de sus matrices y scatterplots. Cada recomendación queda separada del resultado observado.
Destacado adicional · resultados existentes en celdas 33, 34, 41 y 47
Pearson = 0,967149; Spearman = 0,967482. Matrices y scatterplot de compras_mes frente a ingreso_anual.
Ambos coeficientes muestran una asociación positiva muy fuerte: quienes registran más compras tienden a generar más ingreso en este dataset.
Que haya un efecto causal estimado, una mejora de revenue del 96,7 % o un modelo predictivo ya validado.
Investigar frecuencia de compra, valor por pedido y consistencia temporal del ingreso anual antes de usar compras_mes para predecir resultados.
Hallazgo 1 original · celda 57
Pearson = 0,337147; Spearman = 0,320954. Scatterplot por región y matrices.
Las visitas se mueven positivamente con el ingreso anual, aunque con bastante dispersión. Es un vínculo menor que el observado con compras.
Que aumentar las visitas por sí solo garantice más ingresos o que exista una tasa de conversión del 10 % calculada en el proyecto.
Explorar el embudo visitas → compras → ingreso y posibles fricciones. Las hipótesis de precio, oferta o segmento requieren datos y pruebas adicionales.
Hallazgo 2 original · celda 58; complemento de las matrices
Publicidad–visitas: Pearson = 0,578947; Spearman = 0,559267. Publicidad–ingreso anual: Pearson = 0,197483; Spearman = 0,184999.
La asociación con visitas es moderada; con ingreso anual es menor. El patrón descriptivo no cuantifica retorno ni eficiencia de campañas.
Que aumentar gasto cause más visitas, que exista saturación a un gasto concreto o que la publicidad sea rentable o no rentable.
Diseñar pruebas A/B sobre publicidad y analizar ingresos, costos y atribución con ventanas temporales comparables antes de reasignar presupuesto.
Hallazgo 3 original · celda 59; salida numérica en celda 50
Punto-biserial = 0,0931 para miembro_premium–ingreso_anual. El p-value se imprime como 0,0000 por redondeo.
La asociación es positiva y pequeña. La condición premium no basta para describir diferencias importantes de ingreso entre clientes.
Que no exista ninguna relación, que premium explique por sí solo el revenue o que el coeficiente demuestre un efecto causal de la suscripción.
Combinar premium con métricas de comportamiento y comparar segmentos; no utilizar la membresía como criterio único de valor.
Base: 15.000 registros. Totales agregados de las frecuencias dispositivo–región guardadas.
Base: 15.000 registros. Son etiquetas regionales del dataset; no se identifican países.
Ver todas las asociaciones punto-biseriales guardadas
| Variable binaria | Variable numérica | Coeficiente | p guardado |
|---|---|---|---|
miembro_premium | edad | 0,0046 | 0,5728 |
miembro_premium | visitas_mes | -0,0127 | 0,1211 |
miembro_premium | compras_mes | 0,0034 | 0,6744 |
miembro_premium | gasto_publicidad_dirigida | 0,0027 | 0,7390 |
miembro_premium | satisfaccion | 0,0257 | 0,0016 |
miembro_premium | ingreso_anual | 0,0931 | 0,0000 * |
abandono | edad | -0,0115 | 0,1590 |
abandono | visitas_mes | -0,0089 | 0,2734 |
abandono | compras_mes | 0,0083 | 0,3099 |
abandono | gasto_publicidad_dirigida | -0,0046 | 0,5744 |
abandono | satisfaccion | -0,0238 | 0,0035 |
abandono | ingreso_anual | -0,0028 | 0,7295 |
* p se imprime con cuatro decimales en el notebook; 0,0000 representa redondeo. Se reproducen las doce asociaciones disponibles sin completar nivel_ingreso.
La asociación global entre dispositivo y región es muy pequeña. El predominio móvil existe en los conteos, pero esa distribución no demuestra diferencias de ingreso, conversión o rentabilidad por dispositivo.
Método del notebook: tabla de contingencia, chi-cuadrado y V = √(χ² / [n × (min(filas, columnas) − 1)]).
Rigor metodológico, limitaciones y alcance
- Correlación no implica causalidad: el dataset no controla campañas, promociones, antigüedad ni otros posibles factores de confusión.
- visitas_mes y compras_mes son variables mensuales; ingreso_anual es anual según el diccionario. Falta documentar las ventanas exactas y cómo se construyó el ingreso para interpretar esa relación temporal.
- La ausencia de nulos y rangos plausibles no garantiza ausencia de duplicados, errores de medición o sesgos. No aparece una auditoría explícita de duplicados en el código adjunto.
- El Q1 de ingreso_anual es cero: permite destacar al menos un 25 % de registros con ingreso cero, pero no un porcentaje exacto de clientes sin ingreso.
- La razón entre medias de compras y visitas no equivale a conversión de visitantes únicos. El notebook no calcula una tasa de conversión de clientes.
- El valor 0,0000 de p es una salida redondeada, no un p-value exactamente cero. Una asociación pequeña debe distinguirse de su significación estadística.
- Una correlación alta entre compras y la variable objetivo ingreso no demuestra multicolinealidad entre predictores. Antes de modelar conviene revisar variables explicativas, redundancia y posible relación mecánica en la definición de ingreso.
- El análisis no calcula ROAS, ROI, efectos marginales ni retornos causales de publicidad. Tampoco demuestra que las personas mayores compren menos o que la marca no sea de lujo.
- La proporción del indicador abandono es descriptiva de la muestra; no define por sí sola una tasa de abandono mensual ni un horizonte de retención.
- El código numérico incluye nivel_ingreso, pero la salida guardada de punto-biserial no muestra esa variable. La web conserva las doce asociaciones disponibles, sin reconstruir las faltantes.
- No se reejecutó el análisis sobre el CSV fuente. La presentación utiliza el notebook adjunto, sus salidas guardadas y cálculos de porcentajes sobre frecuencias ya disponibles.
Seguimiento de la revisión del proyecto
La versión adjunta incluye comentarios de la Iteración 1 del revisor Israel: validación positiva de carga/exploración y observaciones sobre la tipificación y los pares clave. El código actual incorpora edad como entero y los scatterplots de visitas–ingreso y compras–ingreso. No se presenta esta versión como “aprobada” ni se atribuye una calificación que no está documentada.
Comentario original del revisor · celda 12
Comentario del revisor. (Iteración 1) Excelente trabajo. La carga y exploración inicial cumplen con lo solicitado. Se importan las librerías, se carga el dataset, se revisan los tipos y valores nulos y se muestran las primeras filas antes de continuar con el análisis.
Comentario original del revisor · celda 29
Comentario del revisor. (Iteración 1) Buen trabajo. La conversión de `edad`, la clasificación de variables y la exploración de variables numéricas, binarias y categóricas están correctamente realizadas. Ajusta únicamente el supuesto que afirma que los datos ya estaban correctamente tipificados, porque `edad` requirió una conversión. GRACIAS POR EL APORTE, YA SE CORRIÓ. TMBIÉN SE AGREGÓ EL NIVEL DE INGRESO DEL CLIENTE QUE SE HABIA OMITIDO
Comentario original del revisor · celda 43
Comentario del revisor. (Iteración 1) Revisa esta sección. Los pares principales solicitados son `compras_mes` vs `ingreso_anual` y `visitas_mes` vs `ingreso_anual`. Actualmente se grafica `visitas_mes` vs `gasto_publicidad_dirigida` en lugar del segundo par principal. Incluye el scatterplot de visitas e ingreso anual y deja publicidad dirigida solo como análisis complementario. GRACIAS POR EL APORTE PERO CONSIDERO QUE DEBIÓ HABERSE PUESTO DE MANERA MÁS EXPLICITA EL DESVÍO DEL OBJETIVO PRINCIPAL. SESIÓN 1:1 FUE NECESARIA PARA RESOLVER ESTA INQUIETUD, POR MUY REDUNDANTE QUE PUEDA PARECER
Próximos pasos planteados
Propuestas del notebook, todavía no ejecutadas como análisis o experimentos adicionales.
Repetir los cálculos por dispositivo, región, premium, abandono y rangos de ingreso estimado. Comparar la dirección y magnitud dentro de cada grupo.
Definir visitas, compradores únicos y compras en una misma ventana. Identificar fricciones y estudiar a los clientes con ingreso cero.
Diseñar pruebas A/B sobre publicidad dirigida para evaluar efectos sobre compras e ingreso, en lugar de atribuir causalidad a correlaciones.
Todas las visualizaciones del proyecto
12 figuras originales y 2 matrices coloreadas: siete figuras de distribución, con histograma y boxplot; dos countplots; un PairGrid; dos scatterplots clave; y las matrices Pearson y Spearman.
Las imágenes y las matrices conservan los colores y las salidas del notebook. Pulsa las figuras para ampliarlas; en el PairGrid puedes activar zoom al 200 % y desplazarte. El fondo blanco preserva la legibilidad en ambos modos.
Edad: distribución y outliers
Histograma con 20 intervalos, comparación por dispositivo y línea de la media; junto a él, boxplot de edad. La media es 38,26 y los cuartiles son 30 y 46.
La forma de la distribución no demuestra que las personas mayores compren menos.
Ingreso estimado del cliente
Distribución y boxplot de nivel_ingreso. La media es 30.019,70 y el rango va de 8.000 a 74.790,84. Esta variable describe el ingreso estimado del cliente.
No confundir nivel_ingreso con ingreso_anual: el segundo mide el ingreso generado para NovaRetail+.
Visitas durante el mes
El histograma y el boxplot muestran visitas_mes: media 10,03, mínimo 1, Q1 = 8 y Q3 = 12. Hay clientes más activos que el centro de la distribución.
Son visitas por cliente, no el número de clientes únicos que convierten.
Compras durante el mes
La media es 1,21; Q1 = 0 y Q3 = 2. Los ceros representan clientes con visitas, pero sin compras registradas en el mes.
Dividir la media de compras entre la media de visitas no calcula una tasa de conversión de clientes.
Gasto publicitario dirigido
La media es 20,15, con Q1 = 12,31 y Q3 = 27,2925. La figura permite revisar asignaciones elevadas de gasto publicitario a usuarios.
Esta distribución no demuestra saturación publicitaria, rentabilidad ni causalidad.
Satisfacción del cliente
Histograma y boxplot de satisfaccion. La media es 3,60; Q1 = 3,1 y Q3 = 4,1. Las calificaciones bajas son un grupo para investigar.
No se calculó un índice NPS ni se demostró que satisfacción determine las compras.
Ingreso anual para NovaRetail+
Distribución y boxplot de ingreso_anual. La media es 36,59 y la mediana 30,705. Con mínimo y Q1 iguales a cero, al menos el 25 % de los registros no genera ingreso en este campo.
Es un límite inferior basado en cuartiles; el notebook no reporta el porcentaje exacto de clientes con ingreso cero.
Dispositivo utilizado, por región
Countplot original de tipo_dispositivo, con color por region. El total agregado es móvil: 9.818; escritorio: 3.720; tablet: 1.462.
Que móvil sea mayoritario no prueba que tenga mayor conversión o rentabilidad.
Región del cliente, por dispositivo
Countplot original de region, con color por tipo_dispositivo. Norte reúne 4.395 registros; oeste 3.810; sur 3.726 y este 3.069.
Las categorías son regiones del dataset, no países o ciudades identificados.
Matriz Pearson · siete variables numéricas
| edad | nivel_ingreso | visitas_mes | compras_mes | gasto_publicidad_dirigida | satisfaccion | ingreso_anual | |
|---|---|---|---|---|---|---|---|
| edad | 1.000000 | -0.009003 | 0.004998 | 0.014971 | 0.000062 | -0.006963 | 0.017496 |
| nivel_ingreso | -0.009003 | 1.000000 | 0.001060 | 0.007309 | 0.016834 | 0.002301 | 0.017446 |
| visitas_mes | 0.004998 | 0.001060 | 1.000000 | 0.353844 | 0.578947 | -0.003179 | 0.337147 |
| compras_mes | 0.014971 | 0.007309 | 0.353844 | 1.000000 | 0.207528 | -0.003542 | 0.967149 |
| gasto_publicidad_dirigida | 0.000062 | 0.016834 | 0.578947 | 0.207528 | 1.000000 | -0.013175 | 0.197483 |
| satisfaccion | -0.006963 | 0.002301 | -0.003179 | -0.003542 | -0.013175 | 1.000000 | 0.056171 |
| ingreso_anual | 0.017496 | 0.017446 | 0.337147 | 0.967149 | 0.197483 | 0.056171 | 1.000000 |
Matriz HTML original con los 49 coeficientes y colores guardados. En móvil, desplaza la tabla horizontalmente para recorrer las siete columnas.
Colores conservados de Styler.background_gradient(cmap="coolwarm"): el gradiente original se aplica por columna, no con una escala global común. Para comparar pares, utiliza los valores numéricos.
Matriz Spearman · siete variables numéricas
| edad | nivel_ingreso | visitas_mes | compras_mes | gasto_publicidad_dirigida | satisfaccion | ingreso_anual | |
|---|---|---|---|---|---|---|---|
| edad | 1.000000 | -0.007775 | 0.005205 | 0.015630 | 0.002869 | -0.007590 | 0.016097 |
| nivel_ingreso | -0.007775 | 1.000000 | 0.001420 | 0.009004 | 0.015393 | 0.005243 | 0.025017 |
| visitas_mes | 0.005205 | 0.001420 | 1.000000 | 0.332943 | 0.559267 | -0.001305 | 0.320954 |
| compras_mes | 0.015630 | 0.009004 | 0.332943 | 1.000000 | 0.192511 | -0.002006 | 0.967482 |
| gasto_publicidad_dirigida | 0.002869 | 0.015393 | 0.559267 | 0.192511 | 1.000000 | -0.012612 | 0.184999 |
| satisfaccion | -0.007590 | 0.005243 | -0.001305 | -0.002006 | -0.012612 | 1.000000 | 0.060834 |
| ingreso_anual | 0.016097 | 0.025017 | 0.320954 | 0.967482 | 0.184999 | 0.060834 | 1.000000 |
Matriz HTML original con los 49 coeficientes y colores guardados. En móvil, desplaza la tabla horizontalmente para recorrer las siete columnas.
Colores conservados de Styler.background_gradient(cmap="coolwarm"): el gradiente original se aplica por columna, no con una escala global común. Para comparar pares, utiliza los valores numéricos.
PairGrid: mapa general de relaciones
Vista conjunta de las siete variables numéricas. Los puntos se diferencian por región y las líneas negras resumen la tendencia global fuera de la diagonal.
La diagonal no tiene distribuciones dibujadas. Amplía y activa el zoom para leer los pares; el tamaño de puntos refleja superposición, no conteos exactos.
Visitas del mes frente a ingreso anual
Scatterplot original por región y línea de regresión global. La relación es positiva, pero tiene dispersión considerable: más visitas no se traducen de forma automática en más ingreso.
No se validó un modelo predictivo ni se controlaron campañas, antigüedad u otras variables.
Compras del mes frente a ingreso anual
La asociación positiva es muy fuerte en ambos métodos. El ingreso anual aumenta en conjunto con la cantidad de compras, en el patrón observado del dataset.
Un coeficiente de 0,967 no significa 96,7 % de aumento de ingresos ni prueba una relación causal.
Notebook y repositorio del proyecto
El análisis original se conserva en el notebook revisado del Sprint 8. Esta presentación reúne sus resultados y facilita la revisión del código, las cifras y las visualizaciones.
El botón abre exactamente la versión revisada que compartiste, dentro de NovaRetail_Correlational_analysis. El notebook incluye código, gráficos, matrices y comentarios de revisión.
Abrir notebook revisadoIncluí una copia íntegra del notebook adjunto dentro de esta página. La descarga incluida funciona desde el navegador sin depender de Google Drive.