Antes de proceder con el análisis de componentes principales (PCA),
es fundamental contar con los conjuntos de datos ya depurados. Para
evitar repetir el proceso de limpieza, hemos guardado las versiones
finales de las bases de datos en archivos .Rds.
Las bases limpias se guardaron utilizando los siguientes comandos:
saveRDS(Valencia_Sale, file = "base_2018_limpia.Rds")
saveRDS(Valencia_Sale_2025, file = "base_2025_limpia.Rds")
Una vez guardadas, podemos cargarlas fácilmente en el entorno mediante:
Valencia_2018 <- readRDS("base_2018_limpia.Rds")
Valencia_2025 <- readRDS("base_2025_limpia.Rds")
Así, podremos proceder con los datos previamente depurados, lo que garantiza mayor coherencia y eficiencia en el análisis.
Además, será necesario cargar ciertas librerías que nos permitirán realizar y visualizar el Análisis de Componentes Principales (PCA). Estas son:
FactoMineR: proporciona funciones para llevar a
cabo el PCA y otros métodos de análisis multivariante. Utilizaremos esta
librería para ejecutar el PCA con la función
PCA().
factoextra: facilita la visualización de los resultados del PCA mediante gráficos intuitivos. Usaremos esta librería para representar la varianza explicada y los individuos/componentes.
ggplot2: nos permitirá personalizar los gráficos
generados (por ejemplo, añadiendo líneas, colores y etiquetas) ya que
factoextra se basa en ggplot2.
knitr: nos permitirá utilizar la función
kable().
Ahora que ya contamos con las bases de datos limpias y las librerías necesarias, el siguiente paso consiste en seleccionar las variables numéricas que se utilizarán en el PCA. Para ello, emplearemos los siguientes códigos:
# Seleccionar solo variables numéricas para PCA
numerical_vars_2018 <- Valencia_2018[, c(
"PRICE", "UNITPRICE", "CONSTRUCTEDAREA", "ROOMNUMBER", "BATHNUMBER",
"CADCONSTRUCTIONYEAR","CADMAXBUILDINGFLOOR", "CADDWELLINGCOUNT",
"CADASTRALQUALITYID", "DISTANCE_TO_CITY_CENTER", "DISTANCE_TO_METRO",
"DISTANCE_TO_BLASCO", "RHabitacion_Banyo"
)]
numerical_vars_2018$geometry <- NULL
numerical_vars_2018[] <- lapply(numerical_vars_2018, as.numeric)
# Seleccionar solo variables numéricas para PCA
numerical_vars_2025 <- Valencia_2025[, c(
"price", "priceByArea", "size", "rooms", "bathrooms",
"numPhotos", "floor", "distance", "distancia_min_estacion_m"
)]
numerical_vars_2025[] <- lapply(numerical_vars_2025, as.numeric)
Ahora que ya lo tenemos todo listo, vamos a empezar escalando las variables que vamos a utilizar. Esto se hace para que cada variable tenga media 0 y desviación estándar 1. De esta forma, variables con unidades grandes como el precio no dominan tanto el análisis. Después, realizaremos un PCA con 10 componentes principales, seleccionando el precio como variable cuantitativa suplementaria. Una vez obtenido el PCA, representaremos qué porcentaje de varianza explica cada componente mediante un scree plot para ver cuantas componentes principales necesitaremos en el análisis:
# Escalar los datos
scaled_data_2018 <- scale(numerical_vars_2018)
# Ejecutar PCA
res.pca_2018 = PCA(scaled_data_2018, scale.unit = TRUE, graph = FALSE, ncp = 10, quanti.sup = "PRICE")
eig.val_2018 <- get_eigenvalue(res.pca_2018)
VPmedio_2018 = 100 * (1/nrow(eig.val_2018))
fviz_eig(res.pca_2018, addlabels = TRUE) +
geom_hline(yintercept=VPmedio_2018, linetype=2, color="red")
kable(eig.val_2018[1:10,])
| eigenvalue | variance.percent | cumulative.variance.percent | |
|---|---|---|---|
| Dim.1 | 3.4023558 | 28.352965 | 28.35296 |
| Dim.2 | 1.9880306 | 16.566922 | 44.91989 |
| Dim.3 | 1.5976210 | 13.313508 | 58.23340 |
| Dim.4 | 1.1643176 | 9.702647 | 67.93604 |
| Dim.5 | 1.0187814 | 8.489845 | 76.42589 |
| Dim.6 | 0.6767069 | 5.639225 | 82.06511 |
| Dim.7 | 0.5811865 | 4.843221 | 86.90833 |
| Dim.8 | 0.4680395 | 3.900329 | 90.80866 |
| Dim.9 | 0.3926027 | 3.271689 | 94.08035 |
| Dim.10 | 0.3289087 | 2.740906 | 96.82126 |
Seleccionamos 5 componentes principales, que explican un 76,4% del total de variabilidad de los datos, porque cumplen tanto con el criterio del codo como con el de superar la “varianza media” explicada por PC:
res.pca_2018 = PCA(scaled_data_2018, scale.unit = TRUE, graph = FALSE, ncp = 5, quanti.sup = "PRICE")
# Escalar los datos
scaled_data_2025 <- scale(numerical_vars_2025)
# Ejecutar PCA
res.pca_2025 = PCA(scaled_data_2025, scale.unit = TRUE, graph = FALSE, ncp = 10, quanti.sup = "price")
eig.val_2025 <- get_eigenvalue(res.pca_2025)
VPmedio_2025 = 100 * (1/nrow(eig.val_2025))
fviz_eig(res.pca_2025, addlabels = TRUE) +
geom_hline(yintercept=VPmedio_2025, linetype=2, color="red")
kable(eig.val_2025[1:8,])
| eigenvalue | variance.percent | cumulative.variance.percent | |
|---|---|---|---|
| Dim.1 | 2.7963332 | 34.954166 | 34.95417 |
| Dim.2 | 1.2671371 | 15.839214 | 50.79338 |
| Dim.3 | 1.2041602 | 15.052003 | 65.84538 |
| Dim.4 | 0.8607514 | 10.759393 | 76.60477 |
| Dim.5 | 0.7023619 | 8.779524 | 85.38430 |
| Dim.6 | 0.5183204 | 6.479005 | 91.86330 |
| Dim.7 | 0.3650732 | 4.563415 | 96.42672 |
| Dim.8 | 0.2858625 | 3.573282 | 100.00000 |
Seleccionamos 3 componentes principales, que explican un 65,8% del total de variabilidad de los datos, porque cumplen tanto con el criterio del codo como con el de superar la “varianza media” explicada por PC:
res.pca_2025 = PCA(scaled_data_2025, scale.unit = TRUE, graph = FALSE, ncp = 3, quanti.sup = "price")
Visualizamos ahora las variables mediante fviz_pca_var()
con el fin de ver qué variables están más correlacionadas y cuales
contribuyen más en cada componente:
fviz_pca_var(res.pca_2018, axes = c(1,2), repel = TRUE, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))
fviz_pca_var(res.pca_2018, axes = c(3,4), repel = TRUE, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))
Entre las variables con mayor contribución a las componentes se encuentran:
CADCONSTRUCTIONYEAR, CADDWELLINGCOUNT y
DISTANCE_TO_CITY_CENTER, que están alineadas con
Dim1 y tienen gran influencia en la varianza
explicada.BATHNUMBER y UNITPRICE también destacan
por su contribución significativa.ROOMNUMBER destaca en esta proyección, con una
alta contribución a Dim3, como lo indica su color rojo
intenso.RHabitacion_Banyo y BATHNUMBER también
presentan una alta contribución, especialmente sobre
Dim4. Ambas variables parecen relacionadas, pues están
relativamente próximas y apuntan en direcciones similares.RHabitacion_Banyo y DISTANCE_TO_METRO
presentan cierta relación positiva en el segundo gráfico.UNITPRICE, CADCONSTRUCTIONYEAR y
CONSTRUCTEDAREA están agrupadas en la parte inferior
izquierda, lo que sugiere afinidad moderada en esta dimensión.Por otro lado, variables como DISTANCE_TO_BLASCO o
RHabitacion_Banyo presentan una contribución menor y están
situadas más cerca del centro del gráfico, lo que indica que están menos
representadas en estas dos dimensiones.
Finalmente, observamos como la variable PRICE está
bastante correlacionada con UNITPRICE,
CONSTRUCTEDYEARy BATHNUMBER.
fviz_pca_var(res.pca_2025, axes = c(1,2), repel = TRUE, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))
fviz_pca_var(res.pca_2025, axes = c(1,3), repel = TRUE, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))
Las variables rooms, size,
bathrooms y floor se agrupan en el cuadrante
superior derecho, mostrando alta correlación entre sí y
una contribución destacada a Dim1.
Estas variables están estrechamente ligadas a las características
físicas de la vivienda.
La variable price, proyectada en azul, está muy
alineada con estas variables, indicando que el precio guarda una fuerte
relación con la cantidad de habitaciones, baños y el tamaño de la
vivienda.
Por otro lado, distance y
distancia_min_estacion_m aparecen apuntando en direcciones
opuestas a las variables anteriores, lo que sugiere una relación
inversa: a mayor distancia al centro o a estaciones, menor
precio y menor tamaño/tipo de vivienda.
La variable priceByArea se aleja claramente del
resto, contribuyendo notablemente a Dim2 y mostrando un
comportamiento distinto al del resto de las variables.
Variables como priceByArea, distance y
rooms presentan las contribuciones más elevadas (en
naranja).
Variables como numPhotos o floor tienen
menor impacto en estas dos dimensiones, pero podrían tener relevancia en
componentes posteriores.
En ambos análisis, las variables relacionadas con las
características físicas de la vivienda, como el número
de habitaciones (ROOMNUMBER / rooms),
superficie (CONSTRUCTEDAREA / size) y número
de baños (BATHNUMBER / bathrooms), aparecen
consistentemente como principales contribuyentes a las primeras
componentes. Esto indica que estos factores han sido
estructuralmente determinantes en la configuración del valor de las
viviendas en ambos periodos.
Además, la variable PRICE, aunque se ha tratado como
suplementaria, mantiene una alineación clara con las variables
estructurales de la vivienda en ambos años. Esto refuerza la
idea de que el precio está más influenciado por aspectos como tamaño,
número de estancias o baños, que por otros factores.
Variables relacionadas con la ubicación o
accesibilidad (como DISTANCE_TO_CITY_CENTER,
DISTANCE_TO_METRO, distance,
distancia_min_estacion_m) muestran una dirección opuesta a
la de las variables estructurales, reflejando su relación
inversa con el precio y tamaño: cuanto mayor la distancia,
menor es el valor o calidad de la vivienda.
Por último, En el PCA de 2025 aparecen nuevas variables como
priceByArea o numPhotos, que no estaban
presentes en 2018. Algunas, como priceByArea, muestran un
comportamiento particular y contribuyen significativamente a componentes
diferentes, lo que podría estar relacionado con cambios en cómo
se percibe el valor por metro cuadrado o con nuevas
formas de marketing digital (por ejemplo, la cantidad de fotos
en un anuncio).