Eres un consultor de datos contratado por plazaVea, una de las principales cadenas de retail en Perú. La gerencia comercial desea identificar las dimensiones subyacentes que influyen en la satisfacción del cliente en sus tiendas. Para ello, se ha recolectado una base de datos con las valoraciones de 200 clientes en diferentes aspectos del servicio.
Se trabajó una encuesta de satisfacción con 8 variables (escala Likert del 1 al 5, donde 1 = “Muy insatisfecho” y 5 = “Muy satisfecho”):
Variable | Descripción | Ejemplo de Interpretación |
---|---|---|
X1 | Amabilidad del personal | Grado en que los clientes perciben trato cordial y servicial. |
X2 | Rapidez en el checkout | Tiempo de espera en cajas al realizar el pago. |
X3 | Disponibilidad de productos | Existencia de productos en stock y variedad. |
X4 | Limpieza de la tienda | Higiene y orden en pasillos, baños y áreas comunes. |
X5 | Promociones atractivas | Descuentos y ofertas percibidas como relevantes. |
X6 | Organización de pasillos | Facilidad para encontrar productos. |
X7 | Calidad de productos frescos | Frescura de frutas, verduras y productos perecibles. |
X8 | Señalización interna | Claridad de rótulos para ubicarse en la tienda. |
Objetivos:
Validar la adecuación del análisis factorial mediante:
Prueba de Esfericidad de Bartlett (para determinar si las variables están correlacionadas).
Medida de Adecuación Muestral (MSA) y Kaiser-Meyer-Olkin (KMO) global/por ítem.
Determinar el número óptimo de factores.
Realizar el análisis factorial (rotación Varimax si es necesario) e interpretar los factores.
Carga de base de datos
datos=read.csv("datos_plazavea.csv")
head(datos)
## X1 X2 X3 X4 X5 X6 X7 X8
## 1 3 2 5 2 3 1 5 3
## 2 2 1 3 1 3 1 4 1
## 3 3 2 4 2 2 1 4 1
## 4 4 2 2 2 1 3 3 2
## 5 4 1 4 3 2 3 5 3
## 6 1 2 4 2 2 1 4 1
library(psych)
## Warning: package 'psych' was built under R version 4.4.2
# Matriz de correlaciones
corr_matrix <- cor(datos)
# **Prueba de Esfericidad de Bartlett**
# H0: La matriz de correlaciones es una matriz identidad (no hay correlaciones significativas).
# H1: La matriz de correlaciones no es una matriz identidad (existen correlaciones significativas).
bartlett_test <- cortest.bartlett(corr_matrix, n = 200)
print(bartlett_test)
## $chisq
## [1] 558.8146
##
## $p.value
## [1] 4.812488e-100
##
## $df
## [1] 28
# Decisión: Si p-value < 0.05, se rechaza H0 (válido para AF).
Interpretación:
Hipótesis nula (H₀): La matriz de correlaciones es una matriz identidad (no hay correlaciones significativas entre las variables).
Hipótesis alternativa (H₁): Existen correlaciones significativas entre al menos algunas variables.
Conclusión:
El valor p es extremadamente pequeño (< 0.001), por lo que rechazamos H₀.
Esto indica que existen correlaciones significativas entre las variables, lo que justifica el uso de análisis factorial exploratorio (AFE).
El alto valor de chi-cuadrado (558.81) refuerza que las correlaciones observadas no son aleatorias.
# **Medidas KMO y MSA (por ítem y global)**
kmo_result <- KMO(datos)
print(kmo_result)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = datos)
## Overall MSA = 0.76
## MSA for each item =
## X1 X2 X3 X4 X5 X6 X7 X8
## 0.80 0.83 0.62 0.81 0.81 0.84 0.60 0.83
# KMO global > 0.7 y MSA por ítem > 0.5 son aceptables.
Interpretación:
a) KMO Global (Overall MSA = 0.76):
Regla de decisión:
KMO ≥ 0.90: Excelente
0.80 ≤ KMO < 0.90: Bueno
0.70 ≤ KMO < 0.80: Aceptable
KMO < 0.50: Inaceptable
Conclusión:
print(kmo_result$MSAi)
## X1 X2 X3 X4 X5 X6 X7 X8
## 0.7952999 0.8290970 0.6156901 0.8103216 0.8053635 0.8448909 0.5950774 0.8321623
b) MSA por Ítem:
Valores críticos:
MSA ≥ 0.80: Adecuación excelente para ese ítem.
0.70 ≤ MSA < 0.80: Adecuación buena.
MSA < 0.50: Problemas serios (considerar eliminar el ítem).
Análisis por variable:
X3 (0.62) y X7 (0.60): Están por debajo de 0.70, lo que sugiere que estas variables podrían no ajustarse bien al modelo factorial.
Acción recomendada:
Verificar si estas variables tienen correlaciones bajas con las demás (ej. en la matriz de correlaciones).
Considerar eliminarlas si no cargan significativamente en ningún factor.
Resto de variables (X1, X2, X4, X5, X6, X8): MSA > 0.80, lo que indica que son altamente adecuadas para el AFE.
Prueba | Resultado | Interpretación | Decisión |
---|---|---|---|
Bartlett | χ² = 558.81, p ≈ 0 | Correlaciones significativas entre variables. | Proceder con AFE. |
KMO Global | 0.76 | Adecuación muestral aceptable (no óptima). | Válido, pero con precaución. |
MSA por Ítem | X3 = 0.62, X7 = 0.60 | Problemas potenciales con estas variables. | Evaluar eliminación o revisar correlaciones. |
# Scree Plot
scree(datos, factors = FALSE, main = "Scree Plot para Selección de Factores")
# Autovalores
fa.parallel(datos, fa = "fa", main = "Parallel Analysis")
## Parallel analysis suggests that the number of factors = 2 and the number of components = NA
Se recomienda trabajar 2 Factores.
modelo_fa <- fa(datos, nfactors = 2, rotate = "none")
print(modelo_fa$loadings, cutoff = 0.4)
##
## Loadings:
## MR1 MR2
## X1 0.827
## X2 0.742
## X3 0.807
## X4 0.757
## X5 0.571
## X6 0.621
## X7 0.877
## X8 0.490
##
## MR1 MR2
## SS loadings 2.474 1.774
## Proportion Var 0.309 0.222
## Cumulative Var 0.309 0.531
La tabla muestra cómo cada variable se relaciona con los dos factores extraídos (MR1 y MR2). Las cargas factoriales indican la correlación entre la variable y el factor (valores entre -1 y 1).
Cargas > 0.4 se consideran significativas (generalmente se omiten valores menores para simplificar la interpretación).
Variables agrupadas por factor:
Factor MR1 (Servicio) | Factor MR2 (Productos) |
---|---|
X1 (0.827) | X3 (0.807) |
X2 (0.742) | X5 (0.571) |
X4 (0.757) | X7 (0.877) |
X6 (0.621) | |
X8 (0.490) |
Interpretación:
Factor MR1: Agrupa variables relacionadas con servicio al cliente:
X1
(Amabilidad del personal),
X2
(Rapidez en checkout),
X4
(Limpieza),
X6
(Organización de pasillos), y
débilmente X8
(Señalización).
Nota: X8
tiene una carga
de 0.490, lo que sugiere una relación moderada con este factor.
Factor MR2: Agrupa variables vinculadas a productos y ofertas:
X3
(Disponibilidad de productos),
X7
(Calidad de productos frescos), y
moderadamente X5
(Promociones
atractivas).Métrica | MR1 | MR2 | Total |
---|---|---|---|
SS Loadings | 2.474 | 1.774 | 4.248 |
Proportion Var | 30.9% | 22.2% | 53.1% |
Cumulative Var | 30.9% | 53.1% |
Explicación:
SS Loadings (Suma de cuadrados de las cargas):
Proportion Var (Varianza explicada por factor):
Cumulative Var (Varianza acumulada):
Conclusión:
El modelo explica más del 50% de la varianza, lo que es aceptable en ciencias sociales (usualmente se busca > 60%).
El Factor MR1 (Servicio) es más importante que el Factor MR2 (Productos) en términos de varianza explicada.
Variables problemáticas:
X5
(Promociones atractivas) tiene
una carga moderada (0.571) en MR2. Podría considerarse:
Eliminarla si no es teóricamente relevante.
Explorar si tiene cross-loadings (cargas similares en ambos factores).
X8
(Señalización) tiene la carga
más baja (0.490) en MR1. Validar si su aporte es teóricamente
consistente.
Mejoras posibles:
Añadir más variables para aumentar la varianza explicada (idealmente > 60%).
Repetir el AFE eliminando
X5
o X8
y
comparar resultados.
Nombres de factores sugeridos:
MR1: “Calidad de Servicio en Tienda”.
MR2: “Disponibilidad y Calidad de Productos”.
# Diagrama de cargas factoriales
fa.diagram(modelo_fa, main = "Cargas Factoriales")
Gráfico complementario
library(psych)
library(semPlot)
# Generar el modelo factorial
modelo_fa <- fa(datos, nfactors = 2, rotate = "none")
# Personalización avanzada con semPlot
semPaths(modelo_fa$loadings,
what = "std",
layout = "circle",
edge.label.cex = 1.2,
node.width = 1.5,
nCharNodes = 0,
sizeMan = 8,
sizeLat = 10,
edge.color = "darkblue",
shapeMan = "rectangle",
shapeLat = "ellipse",
residuals = FALSE,
optimizeLatRes = TRUE,
exoVar = FALSE,
title = TRUE,
main = "Análisis Factorial: Plaza Vea (Cargas Estandarizadas)",
mar = c(3,3,3,3))
# Añadir leyenda personalizada
legend("bottomright",
legend = c("Factor Servicio (MR1)", "Factor Productos (MR2)"),
col = c("darkgreen", "purple"),
lty = 1,
bty = "n",
cex = 0.8)
# Destacar cargas importantes
text(x = 0.7, y = 0.9, labels = "Cargas > 0.5", col = "red", cex = 0.8)
Calculamos scores para cada observación:
# Calcular puntuaciones factoriales
scores <- factor.scores(datos, modelo_fa, method = "Bartlett")
datos$Score_Servicio <- scores$scores[,1] # MR1
datos$Score_Productos <- scores$scores[,2] # MR2
# Resumen estadístico
summary(datos[, c("Score_Servicio", "Score_Productos")])
## Score_Servicio Score_Productos
## Min. :-2.30942 Min. :-2.9024
## 1st Qu.:-0.65628 1st Qu.:-0.7324
## Median :-0.08259 Median : 0.1687
## Mean : 0.00000 Mean : 0.0000
## 3rd Qu.: 0.71042 3rd Qu.: 0.8794
## Max. : 2.86325 Max. : 1.7737
Uso: Estos scores permiten:
Clasificar clientes por perfil (ej. “Satisfecho con servicio pero no con productos”).
Correlacionar con otras variables (ej. Fidelidad, gasto promedio).
El método Bartlett (también llamado “mínimos cuadrados ponderados”) es una de las técnicas más comunes para estimar puntuaciones factoriales en el análisis factorial, y su elección se basa en las siguientes razones técnicas:
Método | Ventajas | Limitaciones |
---|---|---|
Bartlett | Óptimo para estimar factores comunes | Sensible a desviaciones de normalidad |
Regresión | Minimiza error de predicción | Asume homocedasticidad (igual varianza de errores) |
Anderson-Rubin | Scores ortogonales (no correlacionados) | Complejidad computacional |
Elección típica:
Bartlett es preferido en investigación académica y cuando se buscan scores precisos para análisis posteriores (ej. regresiones).
Regresión es más usado en aplicaciones predictivas.
Los resultados muestran la distribución de los scores estandarizados para cada factor identificado en el análisis factorial. Aquí la explicación clave:
Puntajes estandarizados: Ambos factores tienen media = 0 y desviación estándar ≈ 1 (propio de la estandarización).
Rango de variación:
Score_Servicio
: [-2.31,
2.86]
Score_Productos
: [-2.90,
1.77]
Estadístico | Score_Servicio | Score_Productos | Interpretación |
---|---|---|---|
Mínimo | -2.31 | -2.90 | Clientes extremadamente insatisfechos en esa dimensión. |
1er Cuartil (Q1) | -0.66 | -0.73 | 25% de clientes están por debajo del promedio en ambas dimensiones. |
Mediana | -0.08 (cerca de la media) | 0.17 (lig. arriba media) | El cliente típico: servicio ≈ promedio, productos levemente mejores. |
3er Cuartil (Q3) | 0.71 | 0.88 | 25% superior tiene satisfacción claramente arriba del promedio en ambos. |
Máximo | 2.86 | 1.77 | Clientes muy satisfechos (especialmente con servicio). |
Asimetría en Productos:
El rango negativo (-2.90) es más extremo que el positivo (1.77), sugiriendo que la insatisfacción con productos es más intensa que la satisfacción.
Posible causa: Problemas específicos (ej. stock o calidad de productos frescos).
Servicio más Balanceado:
Rango simétrico entre negativo y positivo, pero con máximo más alto (2.86 vs 1.77).
Implicación: Buen servicio impacta más positivamente que mal servicio impacta negativamente.
Comparación Directa:
Score_Productos
(0.88) >
Score_Servicio
(0.71): Los clientes más
satisfechos valoran especialmente los productos.Segmentación de clientes mediante clustering jerárquico:
# Estandarizar scores
scores_std <- scale(datos[, c("Score_Servicio", "Score_Productos")])
# Clustering
distancia <- dist(scores_std, method = "euclidean")
cluster <- hclust(distancia, method = "ward.D2")
plot(cluster, main = "Segmentación de Clientes por Factores")
rect.hclust(cluster, k = 3, border = "red") # 3 grupos
grupos <- cutree(cluster, k = 3) # Cortar el dendrograma en 3 grupos
datos$Cluster <- as.factor(grupos) # Añadir la asignación de clúster al dataframe
library(dplyr)
# Resumen de scores factoriales por clúster
resumen_clusters <- datos %>%
group_by(Cluster) %>%
summarise(
n = n(), # Tamaño de cada clúster
Servicio_Media = mean(Score_Servicio),
Productos_Media = mean(Score_Productos)
)
print(resumen_clusters)
## # A tibble: 3 × 4
## Cluster n Servicio_Media Productos_Media
## <fct> <int> <dbl> <dbl>
## 1 1 54 -0.780 1.01
## 2 2 76 -0.505 -0.696
## 3 3 70 1.15 -0.0244
Basado en los resultados proporcionados, aquí está el análisis detallado de cada clúster:
Tamaño: 54 clientes (27% del total).
Perfil:
Servicio_Media: -0.78 (Por debajo del promedio).
Productos_Media: +1.01 (Muy por encima del promedio).
Interpretación:
Son clientes que aman los productos de Plaza Vea (alta disponibilidad, calidad, promociones), pero están insatisfechos con el servicio (amabilidad, rapidez, limpieza).
Recomendaciones:
Investigar causas específicas de insatisfacción con el servicio (ej. encuestas cualitativas).
Capacitación urgente en atención al cliente en tiendas donde se concentra este grupo.
Tamaño: 76 clientes (38% del total).
Perfil:
Servicio_Media: -0.51 (Bajo promedio).
Productos_Media: -0.70 (Muy bajo promedio).
Interpretación:
Clientes insatisfechos en ambas dimensiones. Podrían ser los más propensos a cambiar de retailer.
Posibles causas:
Mala experiencia generalizada (ej. stock inconsistente + servicio lento).
Comparación negativa con competidores.
Recomendaciones:
Acciones correctivas agresivas: revisar procesos de reposición, entrenamiento de personal.
Programas de recuperación (ej. descuentos personalizados).
Tamaño: 70 clientes (35% del total).
Perfil:
Servicio_Media: +1.15 (Muy por encima del promedio).
Productos_Media: -0.02 (Neutral, ligeramente bajo).
Interpretación:
Clientes que valoran el servicio (rapidez, trato amable, limpieza), pero perciben los productos como “normales” (ni buenos ni malos).
Oportunidad:
Potencial para aumentar lealtad si se mejora la percepción de productos (ej. muestras gratis de productos frescos).
Ideal para programas de recomendación (son promotores naturales del servicio).
Clúster | Servicio | Productos | Riesgo | Potencial |
---|---|---|---|---|
1 (Productos) | ❌ Bajo | ✅ Alto | Abandono por mal servicio | Fidelizar con mejoras en servicio |
2 (Insatisfechos) | ❌ Bajo | ❌ Bajo | Alto riesgo de churn | Prioridad máxima de mejora |
3 (Servicio) | ✅ Alto | ⏺ Neutral | Bajo riesgo | Convertirlos en embajadores |
library(ggplot2)
ggplot(datos, aes(x = Score_Servicio, y = Score_Productos, color = Cluster)) +
geom_point(alpha = 0.6) +
labs(title = "Distribución de Clústeres en Espacio Factorial",
x = "Score Servicio", y = "Score Productos") +
theme_minimal()
Los clústeres revelan que Plaza Vea tiene:
Una base leal satisfecha con el servicio (Clúster 3) que puede aprovecharse para aumentar ventas.
Un grupo crítico (Clúster 2) que requiere intervención inmediata.
Una oportunidad para alinear servicio con productos (Clúster 1).