YMAL

title: “Reporte de Análisis Ecommerce USA” author: “Claudia Pizarro” date: “2026-09-28” output: flexdashboard::flex_dashboard: orientation: rows vertical_layout: fill css: Mi_Diseño.css logo: “logo.png” —

Page 3: Estadísticas Descriptivas

Tabla de Estadísticas

datatable(
  tabla_resumen,
  options = list(
    scrollX = TRUE,
    pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_resumen),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Comentarios:

Al observar cada una de las variables no son simétricas ya que la moda media y mediana son diferentes. La variable que se comporta de manera mas simétrica es TimeonWebSite. En general no hay una variable que se exceda en los valores de kurtosis, se alejan levemente del cero, ya sea positivo o negativo.La variabilidad de los datos es bastante razonable, ninguna tiene un comportamiento a tipico o con variacion muy elevada.


Page 4: Histogramas Faceteados

p <- ggplot(num_long, aes(x = valor)) +
  geom_histogram(
    bins = 50,
    fill = "#2C3E50",
    color = "white",
    alpha = 0.7
  ) +
  facet_wrap(
    ~ variable,
    scales = "free",
    ncol = 3
  ) +
  theme_bw(base_size = 12) +
  theme(
    strip.background = element_rect(fill = "#0B1A33"),
    strip.text = element_text(color = "white", face = "bold", size = 12),
    axis.text.x = element_text(size = 7),
    axis.text.y = element_text(size = 7),
    axis.title.x = element_text(size = 7),
     axis.title.y = element_text(size = 7),
  ) +
  labs(
    title = "Histogramas Faceteados de Variables Numéricas",
    x = "Valor",
    y = "Frecuencia"
  )

ggplotly(p)

Comentarios:

Al visualizar la grafica, podemos confirmar lo dicho anteriormente, no son simetricas, la amplitud de los rango en los cuales se mueve cada variable no es muy elevada, esto demuestra que la variación no es muy grande.


Page 5: Rangos de Avg.SessionLength

Tabla

datatable(tabla_rangos, options = list(scrollX = TRUE,pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_rangos),
    `font-size` = '10px',
    `text-align` = 'center')

Gráficos

ggplot(tabla_rangos, aes(x = Avg.SessionLength_Group, y = n_Obs)) +
  geom_col(fill = "#2C3E50") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 8),   
    axis.text.y = element_text(size = 8),
     axis.title.x = element_text(size = 7),
     axis.title.y = element_text(size = 7),
    plot.title = element_text(size = 12, face = "bold")
  ) +
  labs(
    x = "Avg.SessionLength_Group",
    y = "n_Obs",
    title = "Distribución por Rangos de Session Length"
  )->grafico_barras

ggplotly(grafico_barras)
ggplotly(
  ggplot(datos, aes(x = Avg.SessionLength_Group, y = YearlyAmountSpent)) +
    geom_boxplot(fill = "#2C3E50", alpha = 0.5)+
    theme_minimal() +
    theme(
      axis.text.x = element_text(size = 8),
      axis.text.y = element_text(size = 8),
      axis.title.x = element_text(size = 7),
       axis.title.y = element_text(size = 7),
      plot.title = element_text(size = 12, face = "bold")
    ) +
    labs(
      x = "Avg.Session Length_Group",
      y = "Yearly Amount Spent",
      title = "Box-Plot por Rangos de Session Length"
    )
)

Comentarios:

Podemos observar que la mayor proproción se da entre los rangos [32 al 34), aca se concentra el 70% de las observaciones.Podríamos decir que esxiste una relación directa entre Session Length y Yearly Amount Spent, ya que para cada rango que incrementa su valor también lo hace la media y la mediana de Yearly Amount Spent. La variación dentro de cada rango no es elevada, y la variación entre rango tampoco lo es, si existe mayor similitud en variabilidad para el rango 1 y 2 [29 - 32) - [32 - 33) y similaridad entre el rango 3 y 4 [33 - 34) y [34 - 36.2). En la gráfica Box-Plot se puede visualizar de manera rápida la relación positiva que existe entre ambas variables, aun cuando una de ellas sea categórica (ya que se transformo así).También podemos observar que ambos extremos son los que presentan más outliers, provocando en el primer tramo se desplace a valores menores y bajando el promedio, y en caso contrario en el útimo tramo, se da el efecto contrario, sus outliers estan en la parte superior desplazando la caja hacia arriba. Por qué se menciona esto, ya que el promedio se ve afectado rápidamente por estos valores outliers.


Page 6: Correlaciones

ggplotly(
  ggcorrplot(
    cor_mat,
    lab = TRUE,         
    lab_size = 3,        
    colors = c("#6D9EC1", "white", "#E46726")  
  )
)

Comentarios:

Al observar el comportamiento de las correlaciones, podemos decir que las variables que más se correlacionan con Yearly Amount spent son: Length of Membership - Time on App y Avg. Session Length, con este orden de relevancia. Esto es importante mencionar ya que, en su conjunto estas tres variables podrían explicar el comportamiento de Yearly Amount Spent. Otro punto que podemos observar es que la correlación entre estas tres variables es practicamente cero, lo cual podría dar un indicio de la ausencia de multicolinealidad, que sera probada más adelante.


Page 7: Modelo Lineal Inicial

Coeficientes

datatable(tabla_modelo, options = list(scrollX = TRUE,
    pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_modelo),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Métricas

datatable(metricas, options = list(scrollX = TRUE,
    pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(metricas),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Comentarios:

Se define el modelo inicial con todas las variables, y se estiman sus parámetros beta. para posteriormente realizar una prueba t que nos indica si este parámetro es significativo para el modelo o no.como el p-valor solo sale de la regla en el caso de la variable Time on WebSite, ya que es un p muy elevado esto, nos indica que hay evidencia estadística para decir que este estimador es cero y podemos eliminar la variable del modelo. Tambien tenemos el resumen de las metricas y con ellas podemos decir que el 98.4% de la variabilidad del gasto anual (Yearly Amount Spent) se explica por las variables del modelo. Dado que R2 y R2ajustado, son bastante similares, podemos decir que las variables del modelo aportan información relevante y real al modelo, no hay sobreajuste.El error que se da en el modelo es bastante bajo, ya que al tener 9.92, podemos decir que tiene un error residual bajo, casi 10 dolares, que es un 2% del valor tipico.


Page 8: Modelo Final (Forward Selection)

Selección de Variables

modelo_nulo <- lm(YearlyAmountSpent ~ 1, data = datos)

modelo_completo <- lm(
  YearlyAmountSpent ~ Avg.SessionLength + TimeonApp + LengthofMembership,
  data = datos
)

modelo_forward <- step(
  modelo_nulo,
  scope = list(lower = modelo_nulo, upper = modelo_completo),
  direction = "forward"
)
## Start:  AIC=4374.42
## YearlyAmountSpent ~ 1
## 
##                      Df Sum of Sq     RSS    AIC
## + LengthofMembership  1   2054923 1084203 3844.9
## + TimeonApp           1    782673 2356454 4233.0
## + Avg.SessionLength   1    395805 2743321 4309.0
## <none>                            3139126 4374.4
## 
## Step:  AIC=3844.87
## YearlyAmountSpent ~ LengthofMembership
## 
##                     Df Sum of Sq     RSS    AIC
## + TimeonApp          1    711105  373099 3313.5
## + Avg.SessionLength  1    295668  788535 3687.7
## <none>                           1084203 3844.9
## 
## Step:  AIC=3313.49
## YearlyAmountSpent ~ LengthofMembership + TimeonApp
## 
##                     Df Sum of Sq    RSS    AIC
## + Avg.SessionLength  1    323767  49332 2303.9
## <none>                           373099 3313.5
## 
## Step:  AIC=2303.86
## YearlyAmountSpent ~ LengthofMembership + TimeonApp + Avg.SessionLength
tabla_forward <- modelo_forward$anova %>%
  mutate(across(where(is.numeric), ~ round(., 3)))

Proceso Forward (AIC paso a paso)

datatable(
  tabla_forward,
  options = list(scrollX = TRUE, pageLength = 10),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_forward),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Comentarios:

Se esta utilizando el método Forward para seleccionar las variables definitivas del modelo. Se prueba el ingreso de cada variable al modelo, una a una y se elavúa la métrica AIC mientras mas disminuye significa que esta variable se ajusta bien y mejora el modelo, por lo tanto debe entrar. Viendo el resultado de este proceso podemos decir que, a medida que se van incorporando las variables en el orden Length of Memebership - Time on App - Avg.Session Length la metrica AIC baja cada vez más, por lo tanto estas tres variables si deben estar en el modelo final. Una vez que se determinan las variables a utilizar en el modelo procedemos con el siguiente paso, definir los coeficientes.

Coeficientes

datatable(tabla_modelo_final, options = list(scrollX = TRUE, pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_modelo_final),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Métricas

datatable(metricas_final, options = list(scrollX = TRUE,
    pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(metricas_final),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Comentarios:

Logramos obtener los coeficientes beta para el modelo quedando finalmente la ecuación de la siguiente manera: Yearly Amount Spent= -1035.34 + 61.556(LengthofMemebership) + 38.746(TimeonApp) + 25.721(Avg.SessionLength). Con un R2 y R2ajustado bastante saludable así tambien para ER, se comportan casi igual que el modelo con las 4 variables, solo este ultimo sube levemente.


Page 9: Entrenamiento y Validación

Tabla Comparativa

datatable(tabla_validacion, options = list(scrollX = TRUE, pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_validacion),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Observado vs Predicho (Train)

ggplotly(
  ggplot(entrenamiento, aes(x = YearlyAmountSpent, y = pred_entrenamiento)) +
    geom_point(color = "#2C3E50", alpha = 0.6) +
    geom_line(aes(x = YearlyAmountSpent, y = YearlyAmountSpent),
              color = "tomato", linetype = "dashed")
)

Observado vs Predicho (Test)

ggplotly(
  ggplot(validar, aes(x = YearlyAmountSpent, y = predicciones)) +
    geom_point(color = "#1B4F72", alpha = 0.6) +
    geom_line(aes(x = YearlyAmountSpent, y = YearlyAmountSpent),
              color = "tomato", linetype = "dashed")
)

Comentario:

Se realiza la partición de los datos para entrenamiento y validación y se comparan los resultados. El desempeño del modelo es consistente entre los datos de entrenamiento y los datos de validación. Las métricas RMSE y MAE se mantienen prácticamente iguales en ambos conjuntos de datos, lo que indica que el modelo generaliza bastante bien y no está sobreajustado. Además, los valores de R2 son muy altos, lo que nos dice que el modelo explica casi toda la variabilidad del gasto anual (Yearly Amount Spent). En conjunto, estas métricas muestran que el modelo es estable, preciso y confiable para realizar predicciones.Luego , se realizan las graficas entre el valor observado y el predicho para ambos casos entrenamiento y validación y podemos observar que para ambos caso se comporta muy bien ya que cada punto esta bastante cerca de la linea punteada anaranjada, que es lo que esperamos que ocurra pero no siempre es así, mientras mas cerca esta mejor es su predicción ya que la predicción se acerca mucho al valor observado.


Page 10: Supuestos del Modelo

Homocedasticidad

bptest(modelo_train)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_train
## BP = 8.3493, df = 3, p-value = 0.03932
ggplotly(
  ggplot(data.frame(pred = pred_entrenamiento, resid = residuals(modelo_train)),
         aes(pred, resid)) +
    geom_point()
)

Multicolinealidad

datatable(tabla_vif, options = list(scrollX = TRUE, pageLength = 10
  ),
  rownames = FALSE,
  class = 'compact stripe'
) %>%
  formatStyle(
    names(tabla_vif),
    `font-size` = '10px',
    `text-align` = 'center'
  )

Normalidad

shapiro_test
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo_train)
## W = 0.99806, p-value = 0.9326
ggplot(
  data.frame(resid = residuals(modelo_train)),
  aes(sample = resid)
) +
  stat_qq() +
  stat_qq_line(color = "tomato", linetype = "dashed")

Comentarios

Finalmente debemos hace Pruebas Estadísticas para asegurar que los supuestos se cumplen. Primero, se parte con Homocedasticidad. La Hipótesis nula nos dice que la varianza de los residuos es contante. En este caso la hipotesis nula se rechaza dado que 0.0393 es menor que 0.05. Con esto vemos que existe una leve heterocedasticidad en los residuos, el primer supuesto no se cumple por una pequeña diferencia, esta es leve, lo que podría definirse como un hallazgo pero no algo que limite la capacidad predictora del modelo. Segundo es la Ausencia de Multicolinealidad. Como se vio que esto se mide con el estadistico VIF si es superior a 5 existe multicolinealidad, al ir analizando cada variable vemos que todas estan con valor cercano a 1, siendo esto que ninguna variable comparte variabilidad con otra en el modelo, cada una de ellas aporta información propia a la predición del modelo. Y por ultimo, el Tercer supuesto es la Normalidad de los Residuos y lo probamos con la prueba Shapiro-Wilk, donde H0 es que los residuos se distribuyen normal y se rechaza H0 cuando el p valor es mayor que el estadistico, en este caso 0,05 no es mayor que 0,9326, por lo tanto no se rechaza la Hipotesis, queriendo conformar que los errores si se distribuyen normal. Gráficamente tambien se puede observar ya que cada punto esta muy cerca de la linea anaranjada punteada, solo se da los esperado que en las cosa se alejen levemente, lo cual es totalmente aceptado y normal que ocurra. Con todo lo anterior podemos decir que el modelo –> Yearly Amount Spent= -1035.34 + 61.556(LengthofMemebership) + 38.746(TimeonApp) + 25.721(Avg.SessionLength) es de total confianza para hacer predicciones del gasto anual