Objetivo 3.4 IPV

Carga de las librerías

library(readxl)
library(ggplot2)
library(dplyr) 
library(caret)
library(readr)
library(lightgbm)
library(scales)
library(grid)
library(gridExtra)

Carga de los datos y el modelo

datos_ipv <- suppressMessages(read_xlsx("IPV_ComunidadValenciana.xlsx"))
datos_2025 <- readRDS("datos_limpios.rds")
modelo_rf = readRDS("modelo_rf.rds")
datos_2025 <- datos_2025 %>% filter(district != "Alboraya Centro")
datos_2025 <- datos_2025 %>% filter(district != "La Patacona")
# Selecciona y renombra las variables requeridas
datos_predecir <- datos_2025 %>%
    transmute(
        FLOORCLEAN = floor,
        PRICE = price,
        CONSTRUCTEDAREA = as.numeric(size),
        ROOMNUMBER = rooms,
        BATHNUMBER = bathrooms,
        DISTRITO = district,
        DISTANCE_TO_CITY_CENTER = distance,
        status = status,
        HASLIFT = as.factor(hasLift),
        UNITPRICE = priceByArea,
        DISTANCE_TO_METRO = distancia_min_estacion_m,
    )

datos_predecir$status[is.na(datos_predecir$status)] <- "good"
datos_predecir$status <- ifelse(datos_predecir$status == "newdevelopment", "Nueva", ifelse(datos_predecir$status == "renew", "Restaurar", "BuenEstado"))
datos_predecir$status <- as.factor(datos_predecir$status)
datos_predecir$HASLIFT = as.factor(datos_predecir$HASLIFT)
# Crear el transformador de variables dummy INCLUYENDO todas las variables
dummies <- dummyVars(PRICE ~ ., data = datos_predecir)
# Aplica el transformador a los datos
datos_dummies <- predict(dummies, newdata = datos_predecir)
# Elimina las columnas hasLift.1 y hasLift.0 si existen
cols_to_remove <- grep("^HASLIFT\\.", colnames(datos_dummies), value = TRUE)
datos_predecir2 <- datos_dummies[, !(colnames(datos_dummies) %in% cols_to_remove)]
datos_predecir2 <- as.data.frame(datos_predecir2) # Convertir a data.frame para evitar el warning
# Añade la columna PRICE desde datos_predecir original
datos_predecir2$PRICE <- datos_predecir$PRICE
datos_predecir2$HASLIFT <- as.numeric(as.character(datos_predecir$HASLIFT))
datos_predecir2$HASLIFT[is.na(datos_predecir2$HASLIFT)] <- 0 #los chalets tienen valor NA en HASLIFT
# Renombrar columnas de distritos para que tengan puntos en vez de espacios y apóstrofes
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOCamins al Grau"] <- "DISTRITOCamins.al.Grau"
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOCiutat Vella"] <- "DISTRITOCiutat.Vella"
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOEl Pla del Real"] <- "DISTRITOEl.Pla.del.Real"
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOL'Eixample"] <- "DISTRITOL.Eixample"
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOL'Olivereta"] <- "DISTRITOL.Olivereta"
colnames(datos_predecir2)[16] <- "DISTRITOLa.Saidia"
colnames(datos_predecir2)[18]  <- "DISTRITOPoblats.Marítims"
colnames(datos_predecir2)[colnames(datos_predecir2) == "DISTRITOQuatre Carreres"] <- "DISTRITOQuatre.Carreres"

En este apartado se pretende analizar hasta qué punto un modelo predictivo entrenado con datos de 2018 es capaz de estimar los precios actuales de la vivienda en Valencia. Para ello, se evaluará el rendimiento del modelo al aplicarlo sobre datos recientes y se comprobará si existe un desfase significativo entre las predicciones y los valores reales. En caso de observarse una diferencia relevante, se propone ajustar las predicciones originales utilizando la evolución del Índice de Precios de la Vivienda (IPV) como factor de corrección, con el objetivo de aproximar las estimaciones del modelo a la realidad actual del mercado.

#> Random Forest - RMSE: 317013.4 
#> MAE: 213572.3 
#> R2: 0.6761979

Las primeras predicciones del modelo, entrenado con datos de 2018, no han reflejado correctamente los precios actuales de la vivienda en Valencia. Además, en el gráfico se puede apreciar como los precios están desfasados. Por ello, se va a realizar un pequeño análisis exploratorio del Índice de Precios de la Vivienda (IPV), con el objetivo de observar cómo han evolucionado los precios desde 2018 hasta 2025. Este análisis permitirá ajustar las predicciones del modelo a la situación actual del mercado, mejorando así su precisión.

Primero observaremos la evolución año a año desde 2007 hasta 2024 para tener una visión global de la situación del mercado inmobiliario.

El gráfico muestra claramente la evolución del Índice de Precios de la Vivienda (IPV) en la Comunidad Valenciana desde 2007 hasta 2024, reflejando las principales tendencias del mercado inmobiliario en este periodo. Se observa una fuerte caída en los precios desde 2008 hasta 2013, consecuencia directa de la crisis financiera y el estallido de la burbuja inmobiliaria, lo que llevó a una importante corrección en el valor de la vivienda. A partir de 2013, el mercado entra en una fase de estabilización, con precios que se mantienen bajos durante algunos años, señalando un periodo de ajuste y menor actividad. Sin embargo, desde 2016 se inicia una recuperación progresiva y sostenida, con incrementos anuales cada vez más pronunciados, especialmente a partir de 2020, cuando el crecimiento se acelera notablemente. Este repunte puede estar relacionado con la recuperación económica tras la pandemia, el aumento de la demanda y la escasez de oferta en el mercado, factores que han impulsado los precios hasta alcanzar en 2024 niveles superiores a los registrados antes de la crisis. En conjunto, el análisis evidencia cómo el mercado de la vivienda en la Comunidad Valenciana ha superado la etapa de ajuste post-crisis y se encuentra actualmente en una fase de expansión, con precios en máximos históricos.

Ahora miraremos la evolución entre 2018(datos con los que se ha entrenado el modelo) y 2024 más detalladamente, por trimestre y mirando las variaciones porcentuales.

A partir del gráfico de la evolución trimestral del Índice de Precios de la Vivienda (IPV) en Valencia entre 2018 y 2024, se observa una tendencia claramente ascendente y sostenida en el valor del IPV. Tras un crecimiento moderado en los primeros años, a partir de 2021 el incremento se vuelve mucho más pronunciado, especialmente en los últimos trimestres, donde el IPV alcanza sus valores máximos históricos.

Esta evolución confirma que el mercado inmobiliario ha experimentado un importante encarecimiento desde 2018, lo que explica por qué un modelo entrenado con datos antiguos subestima sistemáticamente los precios actuales. Por tanto, resulta imprescindible ajustar las predicciones del modelo teniendo en cuenta esta fuerte subida del IPV, ya que refleja el cambio real en el valor de la vivienda durante este periodo. Así, el análisis del IPV justifica y fundamenta la necesidad de corregir las estimaciones del modelo para alinearlas con la situación actual del mercado.

#> IPV 2018T1: 107.643
#> IPV 2024T4: 154.122
#> Diferencia absoluta: 46.479
#> Random Forest - RMSE: 235323.8 
#> MAE: 144676.6 
#> R2: 0.6761979

Tras aplicar la corrección basada en la evolución del IPV, observamos que el MAE del modelo disminuye notablemente hasta situarse en torno a 145.000 €, lo que indica una mejora significativa en la precisión de las predicciones. Además, en el gráfico de dispersión se aprecia claramente cómo el desfase entre los precios reales y los predichos se ha reducido considerablemente, alineando mucho mejor las estimaciones del modelo con los valores actuales del mercado. Esto demuestra la eficacia del ajuste por el IPV para adaptar el modelo a la realidad de 2025.

Por último, se procederá a eliminar los valores anómalos (outliers) del conjunto de datos con el objetivo de analizar cómo mejora el rendimiento del modelo al centrarse únicamente en las viviendas cuyos precios se encuentran dentro de un rango más representativo del mercado. Esta depuración permitirá evaluar la capacidad predictiva del modelo en condiciones más realistas y comprobar si la eliminación de estos casos extremos contribuye a una mayor precisión en las estimaciones.

datos_predecir2_sin_an <- datos_predecir2 %>%
  filter(PRICE <= quantile(PRICE, 0.95))
pred_sin_an_rf <- predict(modelo_rf, datos_predecir2_sin_an)
pred_sin_an_rf = pred_sin_an_rf * diferencia_ipv
rmse_sin_an_rf <- RMSE(pred_sin_an_rf, datos_predecir2_sin_an$PRICE)
mae_sin_an_rf  <- MAE(pred_sin_an_rf, datos_predecir2_sin_an$PRICE)
r2_sin_an_rf   <- R2(pred_sin_an_rf, datos_predecir2_sin_an$PRICE)
cat("Random Forest - RMSE:", rmse_sin_an_rf, "\nMAE:", mae_sin_an_rf, "\nR2:", r2_sin_an_rf, "\n")
#> Random Forest - RMSE: 171059.7 
#> MAE: 120821.3 
#> R2: 0.6195929

Al eliminar los valores anómalos (outliers), el MAE disminuye notablemente, lo que indica que el error medio absoluto entre las predicciones y los precios reales se reduce. Esto es esperable, ya que los outliers suelen ser responsables de errores muy grandes y, al quitarlos, el modelo se evalúa sobre viviendas con precios más representativos y menos extremos.

Sin embargo, el R² también baja. Esto ocurre porque el R² mide la proporción de la varianza explicada por el modelo respecto a la varianza total de los datos. Al eliminar los valores extremos, la variabilidad total del conjunto de datos disminuye, y si el modelo no mejora proporcionalmente su ajuste sobre los datos restantes, el R² puede reducirse. Además, si el modelo estaba ajustando mejor los valores extremos que los intermedios, su capacidad explicativa relativa sobre el nuevo rango de precios puede verse afectada.

A pesar de la mejora tras el ajuste por el IPV, el modelo sigue presentando un error medio elevado. Esto se debe, en parte, a la complejidad inherente del mercado inmobiliario, especialmente cuando se intenta predecir con una diferencia temporal de siete años, periodo en el que han cambiado significativamente la influencia de muchas variables relevantes como se ha visto en el objetivo 3.1. Además, el alto valor absoluto del error está influido por el propio precio medio de la vivienda en Valencia, que ha alcanzado máximos históricos en los últimos años (el precio medio de los datos de 2025 es de 440000€). Por todo ello, aunque la corrección mejora la precisión, sigue siendo necesario interpretar los resultados del modelo con cautela y considerar sus limitaciones en un contexto de mercado tan dinámico y cambiante.

precio_medio <- mean(datos_predecir2$PRICE, na.rm = TRUE)
cat("Precio medio de la muestra:", round(precio_medio, 2), "€\n")
#> Precio medio de la muestra: 442668.8 €