En este informe se analizara la oferta de vivienda usada en Cali publicada en OLX a través de un análisis exploratorio de datos. Olx es una plataforma plataforma de comercio electrónico que permite comprar, vender, o intercambiar bienes y servicios.
El análisis exploratorio de datos (EDA) es un paso clave para comprender la información de venta de vivienda, para identificar patrones y evaluar la distribución de las variables.
PASO 1. Instalar y cargar librerias
# Cargar librerías necesarias
library(readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(knitr) #Facilita la creación de informes con R Markdown, combinando texto, código y resultados.
library(kableExtra) #Para crear tablas con formato más avanzado y estilizado
library(tidyr) #Ayuda a transformar y reorganizar los datos
library(RecordLinkage) #Realiza tareas de emparejamiento de registros,
library(leaflet) #Permite crear mapas interactivos con datos geoespaciale
library(htmltools) #Ayuda a generar y manipular contenido HTML
PASO 2: Filtar o seleccionar la información que necesito
Se filtra la base de datos teniendo en cuenta sólo las viviendas del barrio Valle del Lili.
El código siguiente carga un archivo de Excel con datos de viviendas, les asigna un ID único a cada fila, y luego filtra las propiedades que están en el barrio “Valle del Lili”, permitiendo pequeñas diferencias en la escritura del nombre.
library(readxl)
datos<- read_excel("C:/Users/juane/OneDrive/Desktop/Regresion Lineal/Datos_Vivienda.xlsx",
col_types = c("text", "text", "text",
"numeric", "numeric", "numeric",
"numeric", "numeric", "text", "text",
"numeric", "numeric"))
#Generar una secuencia de números desde 1 hasta el número total de filas y agrega esta secuencia a la tabla como una nueva columna.Cuando trabajas con datos, a veces es necesario tener una manera rápida de identificar o hacer referencia a filas específicas. Si tu tabla no tiene un identificador único (como un id), agregar una secuencia de números te da una forma sencilla de identificar cada fila de manera única.
#1:dim(datos)[1]: Aquí estamos generando una secuencia de números. La función dim(datos) devuelve las dimensiones de tu tabla (datos). El [1] accede al número de filas (la primera dimensión). Así que, 1:dim(datos)[1] crea una secuencia de números que va desde 1 hasta el número total de filas en la tabla datos.
id=1:dim(datos)[1]
datos=data.frame(id,datos) #Este código genera una nueva columna llamada id, que contiene una secuencia de números desde 1 hasta el número de filas de la tabla datos, y luego agrega esta columna id a la tabla original datos.
#Filtro
require(RecordLinkage)
#Busca coincidencias de nombres similares (ej., "Sta Teresita" aún sería válido).
#Encuentra las posiciones de las filas que cumplen ambas condiciones.
# Extrae solo esas filas y las guarda en datos_sub.
pos = which(jarowinkler("valle del lili", datos$Barrio) > 0.98)
datos_sub = datos[pos,]
head(datos_sub)
| id | Zona | piso | Estrato | precio_millon | Area_contruida | parqueaderos | Banos | Habitaciones | Tipo | Barrio | cordenada_longitud | Cordenada_latitud | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 8 | 8 | Zona Sur | 5 | 5 | 310 | 82.5 | 1 | 2 | 3 | Apartamento | valle del lili | -76.46438 | 3.43463 |
| 9 | 9 | Zona Sur | 9 | 4 | 240 | 80.0 | 1 | 2 | 3 | Apartamento | valle del lili | -76.46438 | 3.43463 |
| 12 | 12 | Zona Sur | NA | 5 | 230 | 70.0 | 1 | 2 | 2 | Apartamento | valle del lili | -76.46500 | 3.43600 |
| 13 | 13 | Zona Sur | NA | 5 | 160 | 63.0 | NA | 2 | 2 | Apartamento | valle del lili | -76.46500 | 3.43600 |
| 14 | 14 | Zona Sur | 6 | 5 | 200 | 71.0 | 1 | 2 | 3 | Apartamento | valle del lili | -76.46500 | 3.43600 |
| 15 | 15 | Zona Sur | NA | 5 | 270 | 76.0 | NA | 2 | 3 | Apartamento | valle del lili | -76.46500 | 3.43600 |
Ahora obtenemos los nombres exactos de las variables que tenemos en la base de datos
library(dplyr)
names(datos_sub)
## [1] "id" "Zona" "piso"
## [4] "Estrato" "precio_millon" "Area_contruida"
## [7] "parqueaderos" "Banos" "Habitaciones"
## [10] "Tipo" "Barrio" "cordenada_longitud"
## [13] "Cordenada_latitud"
##Registros totales para las viviendas del barrio "valle del lili"
length(pos)
## [1] 1008
Indicadores de centralidad
## Se calcula el promedio del precio, el área construida, las habitaciones y los baños de las viviendas en venta en el Barrio Valle del Lili y se colocan los datos en una tabla o dataframe
# na.rm: ignora valores faltantes (NA) para evitar errores en el cálculo.
cantidad_ofertas = length(datos_sub$Zona)
promedio_precio = mean(datos_sub$precio_millon, na.rm = TRUE)
promedio_area = mean(datos_sub$Area_contruida, na.rm = TRUE)
promedio_habitaciones = mean(datos_sub$Habitaciones, na.rm = TRUE)
promedio_banos = mean(datos_sub$Banos, na.rm = TRUE)
resultado_prom = data.frame(cantidad_ofertas, promedio_precio, promedio_area, promedio_habitaciones, promedio_banos)
resultado_prom
| cantidad_ofertas | promedio_precio | promedio_area | promedio_habitaciones | promedio_banos |
|---|---|---|---|---|
| 1008 | 243.1716 | 90.07727 | 2.917659 | 2.37996 |
### Indicadores de centralidad y variabilidad para la variable "precio"
promedio_precio=mean(datos_sub$precio_millon,na.rm = TRUE)
mediana_precio=median(datos_sub$precio_millon,na.rm = TRUE)
minimo_precio=min(datos_sub$precio_millon,na.rm = TRUE)
maximo_precio=max(datos_sub$precio_millon,na.rm = TRUE)
desvest_precio=sd(datos_sub$precio_millon,na.rm = TRUE)
indic_precio=data.frame(promedio_precio,mediana_precio,minimo_precio,maximo_precio,desvest_precio)
indic_precio
| promedio_precio | mediana_precio | minimo_precio | maximo_precio | desvest_precio |
|---|---|---|---|---|
| 243.1716 | 235 | 108 | 800 | 85.7378 |
Histograma
Ahora creamos el histograma del precio y área de la vivienda para ver la distribución de los datos:
colnames(datos_sub) # Muestra los nombres de las columnas
## [1] "id" "Zona" "piso"
## [4] "Estrato" "precio_millon" "Area_contruida"
## [7] "parqueaderos" "Banos" "Habitaciones"
## [10] "Tipo" "Barrio" "cordenada_longitud"
## [13] "Cordenada_latitud"
str(datos_sub) # Muestra la estructura del dataframe
## 'data.frame': 1008 obs. of 13 variables:
## $ id : int 8 9 12 13 14 15 16 18 25 26 ...
## $ Zona : chr "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
## $ piso : chr "5" "9" "NA" "NA" ...
## $ Estrato : chr "5" "4" "5" "5" ...
## $ precio_millon : num 310 240 230 160 200 270 170 290 226 280 ...
## $ Area_contruida : num 82.5 80 70 63 71 76 60 91 80 160 ...
## $ parqueaderos : num 1 1 1 NA 1 NA NA 1 1 2 ...
## $ Banos : num 2 2 2 2 2 2 2 3 2 3 ...
## $ Habitaciones : num 3 3 2 2 3 3 3 3 3 4 ...
## $ Tipo : chr "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
## $ Barrio : chr "valle del lili" "valle del lili" "valle del lili" "valle del lili" ...
## $ cordenada_longitud: num -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ Cordenada_latitud : num 3.43 3.43 3.44 3.44 3.44 ...
# Crear y mostrar el histograma interactivo
ggplotly(
ggplot(datos_sub, aes(x = precio_millon)) +
geom_histogram(binwidth = 25, fill = "steelblue", color = "black", alpha = 0.6) +
labs(title = "Figura 1. Histograma del Precio de Viviendas en Valle del Lili",
x = "Precio (Millones COP)",
y = "Frecuencia") +
theme_minimal()
)
Interpretación Figura 1.
La Figura 1 muestra la distribución de los precios de las viviendas en Valle del Lili. Permite identificar patrones, concentración de precios y posibles sesgos en la distribución.
📌 Distribución de Precios:La mayoría de las viviendas tienen precios entre 150 y 300 millones de pesos.Se observa una mayor concentración entre 200 y 275 millones, con los valores más frecuentes en ese rango. Hay viviendas más costosas, superando los 400 millones, pero representan menos del 5% del total de ofertas.
📈 Modos y Agrupaciones:Se identifican dos picos principales: Uno entre 150 y 175 millones (apartamentos de menor metraje o unidades habitacionales compactas). Otro entre 225 y 275 millones, que representa la vivienda familiar estándar típica de la zona. A partir de los 350 millones la cantidad de ofertas decae notoriamente.
📊 Dispersión y Rango de Precios:Los precios van desde 108 millones hasta cerca de 800 millones de pesos. El 50% central de las ofertas se ubica entre 175 y 289 millones, mostrando una oferta relativamente homogénea en el segmento medio.
⚠️ Los inmuebles con precios superiores a 500 millones parecen ser excepciones en el mercado, indicando que corresponden a casas esquineras o propiedades de áreas considerables.
# Crear y mostrar el histograma interactivo
ggplotly(
ggplot(datos_sub, aes(x = Area_contruida)) +
geom_histogram(binwidth = 10, fill = "green", color = "black", alpha = 0.6) +
labs(title = "Figura 2. Histograma del Área Construida (m2) en Valle del Lili",
x = "Área Construida (m²)",
y = "Frecuencia") +
theme_minimal()
)
Interpretación Figura 2.
La Figura 2 muestra la distribución del área construida (en metros cuadrados) de las viviendas ofertadas en Valle del Lili.
📌 Distribución del Área Construida:La gran mayoría de las viviendas tienen áreas comprendidas entre los 55 y 100 m². El valor más frecuente (pico principal) se encuentra alrededor de los 60 a 70 m², con una mediana cercana a los 76 m². Las propiedades con áreas superiores a 200 m² son muy poco frecuentes dentro del sector.
📈 Modos y Agrupaciones:Se observa una marcada concentración unimodal entre 50 y 90 m², lo que refleja la tipología predominante en Valle del Lili: apartamentos familiares compactos y medianos. Existe un segundo grupo residual mucho menos denso entre los 120 y 250 m², asociado a casas o apartamentos dúplex.
📊 Dispersión y Rango de Áreas:Las viviendas más compactas inician alrededor de los 40 m², mientras que el 75% de la oferta no supera los 91 m².La distribución presenta una fuerte asimetría positiva hacia la derecha.
⚠️ Posibles Valores Atípicos:Se identifican algunos registros aislados por encima de los 300 m² (llegando a extremos superiores a 600 y 900 m²), correspondientes a casas campestres, lotes/propiedades especiales o posibles inconsistencias de digitación en la base de datos.
Boxplot
Ahora creamos el boxplot del precio de la vivienda para ver la distribución de los datos:
# Crear y mostrar el boxplot interactivo
ggplotly(
ggplot(datos_sub, aes(y = precio_millon)) +
geom_boxplot(fill = "lightblue", color = "black", outlier.colour = "red", outlier.shape = 16, outlier.size = 3) +
labs(title = "Figura 3. Boxplot del Precio de Viviendas en Valle del Lili",
y = "Precio (Millones COP)") +
theme_minimal()
)
Interpretación Fgura 3-Boxplot
Este boxplot muestra la distribución de los precios de las viviendas en Valle del Lili y permite identificar la dispersión, la mediana y posibles valores atípicos.
📌 Mediana (median: 235 millones):
La línea negra dentro de la caja representa la mediana del precio de las viviendas, que es 235 millones.
Esto significa que el 50% de las viviendas tienen un precio menor o igual a 235 millones, y el otro 50% tiene un precio superior.
📦 Rango Intercuartílico (IQR – Interquartile Range):
Q1 (Primer Cuartil - q1: 175 millones): El 25% de las viviendas tiene un precio inferior a 175 millones. Q3 (Tercer Cuartil - q3: 289 millones): El 75% de las viviendas tiene un precio inferior a 289 millones.
El 50% central de los precios se encuentran entre 175 y 289 millones.
📊 Rango Total (Bigotes del Boxplot):
Mínimo (min: 108 millones): El precio más bajo registrado es 108 millones.
Bigote superior (upper fence: 450 millones): Cualquier valor superior a 450 millones se considera estadísticamente atípico
Máximo (max: 800 millones): El precio más alto registrado alcanza los 800 millones.
⚠️ ¿Hay valores atípicos?
⚠️ ¿Hay valores atípicos?
Sí, se observan múltiples puntos por encima de 450 millones, llegando hasta los 800 millones. Esto indica que existen propiedades de valor significativamente superior al promedio del sector, correspondientes principalmente a casas o apartamentos de mayor tamaño, inmuebles con remodelaciones o viviendas de gama alta.
Ahora creamos el boxplot del área de la vivienda para ver la distribución de los datos:
# Crear y mostrar el boxplot interactivo
ggplotly(
ggplot(datos_sub, aes(y = Area_contruida)) +
geom_boxplot(fill = "green", color = "black", outlier.colour = "red", outlier.shape = 16, outlier.size = 3) +
labs(title = "Figura 4. Boxplot del Área construida de Viviendas en Valle del Lili",
y = "Área (m2)") +
theme_minimal()
)
Interpretación Figura 4
Este boxplot muestra la distribución del área construida de los apartamentos en Santa Teresita, permitiendo analizar la dispersión, la mediana y los valores atípicos.
📌 Mediana (median: 76.00 m²)
La línea negra dentro de la caja representa la mediana del área, que es 76 m².
Esto significa que el 50% de las viviendas tienen un área menor o igual a 76 m², y el otro 50% tiene un área mayor.
📦 Rango Intercuartílico (IQR – Interquartile Range):
Q1 (Primer Cuartil - q1: 62.00 m²): El 25% de las viviendas tienen un área menor a 62 m².
Q3 (Tercer Cuartil - q3: 91.00 m²): El 75% de las viviendas tienen un área menor a 91 m²
El 50% central de las viviendas tienen un área entre 62 y 91 m².
📊 Rango Total (Bigotes del Boxplot):
Mínimo (min: 40 m²): La vivienda más pequeña registrada tiene 40 m².
Máximo (max: 932 m²): El inmueble de mayor tamaño registrado en la base alcanza los 932 m².
Upper fence (upper fence: 130 m²): La mayoría de los apartamentos convencionales se encuentran dentro de este límite.
⚠️ Valores Atípicos (Outliers)
Se observa una fila densa de valores atípicos por encima de los 130 m², con registros notables que superan los 250, 400 y 900 m². Estos corresponden a casas unifamiliares, penthouses de dos niveles o inmuebles especiales que difieren significativamente del metraje típico del sector.
Gráfico de dispersión
Opción 1
g1=ggplot(data = datos_sub,aes(y=precio_millon, x=Area_contruida)) + geom_point() + geom_smooth()
ggplotly(g1)
Opción 2
# Crear gráfico interactivo con correlación
ggplotly(
ggplot(datos_sub, aes(x = Area_contruida, y = precio_millon)) +
geom_point(color = "purple", alpha = 0.8, size = 2) + # Puntos con color y transparencia
geom_smooth(method = "loess", color = "grey", se = TRUE) + # Línea de tendencia lineal
labs(
title = paste("Figura 5. Relación Área vs Precio en Valle del Lili\nCoef. de correlación: ",
round(cor(datos_sub$precio_millon, datos_sub$Area_contruida, use = "complete.obs"), 2)),
x = "Área Construida (m²)",
y = "Precio (Millones COP)",
caption = "Fuente: Datos de Vivienda"
) +
theme_minimal() +
theme(
plot.title = element_text(size = 13, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10)
)
)
Interpretación Figura 5.
Este gráfico muestra la relación entre el precio de las viviendas (en millones de pesos) y el área construida (en m²) en Valle del Lili.
🔹 Tendencia general:
Se observa una relación positiva inicial: a mayor área construida, mayor precio de la vivienda. Sin embargo, la relación no es completamente lineal, ya que presenta alta dispersión y una caída atípica en los metrajes extremos.
🔹 Patrones clave:
Para áreas menores a 100 m², los precios se concentran fuertemente en el rango de 100 a 350 millones. Entre 100 y 250 m², los precios son más dispersos, con algunas propiedades alcanzando entre 400 y 650 millones. *Más de 250 m², la cantidad de datos es escasa y los precios muestran altísima variabilidad (desde menos de 300 hasta 800 millones).
🔹 Curva de tendencia (línea gris):
La línea suavizada sugiere un crecimiento sostenido del precio hasta aproximadamente los 250 m². Hay una caída marcada cuando el área supera los 400 m², debido a unos pocos registros atípicos que arrastran la tendencia hacia abajo, lo que indica que propiedades gigantes en este barrio no escalan en precio de la misma forma.
Coeficiente de correlación
A medida que el área construida aumenta en el rango típico, el precio también tiende a aumentar. Es una relación directamente proporcional: viviendas más grandes suelen costar más. La correlación es de 0.70, lo que indica una asociación fuerte positiva. Aunque hay variabilidad en los precios, en general, el tamaño del inmueble explica una parte importante del precio. Una correlación alta NO significa que el área sea la única causa del precio. Otros factores como número de baños, parqueaderos, tipo de vivienda y acabados también influyen en el precio.
Un coeficiente de 0.70 indica que el tamaño de la vivienda es un buen predictor del precio, pero no es el único factor determinante.
Hallazgos relevantes
Economías de escala: Existe un límite (después de los 200-250 m²) donde aumentar el área no incrementa el precio proporcionalmente en este mercado.
Economías de escala: Existe un límite (después de los 200-250 m²) donde aumentar el área no incrementa el precio proporcionalmente en este mercado.
Tipología de inmueble:Las propiedades más grandes y atípicas probablemente correspondan a casas amplias o lotes, cuyas dinámicas de precio difieren del apartamento estándar del sector.
Oferta y demanda: Los outliers en el extremo derecho podrían indicar propiedades con mucha antigüedad, diferente destinación (comercial) o posibles errores de digitación en el área.
El área construida es un fuerte predictor del precio, pero hay variaciones que podrían explicarse por otros factores estructurales como los parqueaderos, los baños y si la propiedad es casa o apartamento.
# Mapa 1
# Muestra un mapa con puntos morados en las ubicaciones especificadas por las coordenadas de la tabla datos_sub.
# Cada punto tiene una etiqueta con un identificador (id).
# leaflet() → Inicia la creación de un mapa interactivo.
# lng = datos_sub$cordenada_longitud → Usa la columna de longitudes como coordenadas en el eje X.
# lat = datos_sub$Cordenada_latitud → Usa la columna de latitudes como coordenadas en el eje Y.
# radius = 1.0 → Define el tamaño de los marcadores (círculos pequeños).
# label = datos_sub$id → Muestra una etiqueta con el identificador de cada punto cuando el cursor pasa por encima.
leaflet() %>%
addCircleMarkers(
lng = datos_sub$cordenada_longitud,
lat = datos_sub$Cordenada_latitud,
radius = 1.0,
color = "purple",
label = datos_sub$id
) %>%
addTiles()
Interpretación Mapa 1
El mapa representa la ubicación espacial de los inmuebles clasificados bajo el barrio Valle del Lili.
Concentración principal: Se observa una densa aglomeración de puntos en la zona sur de la ciudad, lo cual coincide de manera precisa con la ubicación geográfica real del barrio Valle del Lili.
Valores atípicos espaciales (Outliers): Se evidencia una cantidad considerable de puntos dispersos por el resto de la ciudad (norte, centro, occidente).
Calidad de los datos: Dado que la base fue filtrada estrictamente por el nombre del barrio, esta dispersión expone errores en la digitación de las coordenadas de origen o prácticas de agentes inmobiliarios que utilizan el nombre de “Valle del Lili” para promocionar inmuebles ubicados en otros sectores de Cali.
# Mapa 2
# Etiqueta enriquecida (label) muestra información detallada del punto, incluyendo:
# ID del inmueble, Precio, Área, Barrio y Coordenadas.
# Añade un fondo de mapa base → addTiles()
leaflet() %>%
addCircleMarkers(
lng = datos_sub$cordenada_longitud,
lat = datos_sub$Cordenada_latitud,
radius = 1,
color = "purple",
label = paste0('ID: ', datos_sub$id,
', Precio: ', datos_sub$precio_millon,
', Area: ', datos_sub$Area_contruida,
', Barrio: ', datos_sub$Barrio,
', Lat: ', datos_sub$Cordenada_latitud,
', Long: ', datos_sub$cordenada_longitud)
) %>%
addTiles()
#Estimamos modelo de regresión simple
modsimple=lm(precio_millon~Area_contruida, data=datos_sub)
summary (modsimple)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -751.81 -46.24 1.29 31.91 339.75
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 156.76191 3.38375 46.33 <2e-16 ***
## Area_contruida 0.95928 0.03086 31.09 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 61.26 on 1006 degrees of freedom
## Multiple R-squared: 0.49, Adjusted R-squared: 0.4894
## F-statistic: 966.4 on 1 and 1006 DF, p-value: < 2.2e-16
Interpretación modelo simple:
La ecuación estimada del modelo simple es:
precio_millon = 156.76 + 0.96 * Area_contruida
*Por cada metro cuadrado adicional de área construida, se espera que el precio de la vivienda aumente en promedio 0.96 millones de pesos (960,000 COP)
*Ambos coeficientes son altamente significativos (valores Pr(>|t|) muy pequeños, menores a 0.001), lo que indica que el área construida es un predictor estadísticamente relevante para explicar la variación en el precio de los inmuebles.
R² = 0.49: El modelo explica exactamente el 49% de la variabilidad del precio en este sector. Es un nivel moderado de ajuste
Conclusión:El área construida es un predictor significativo del precio de la vivienda. Aunque el modelo tiene un poder explicativo razonable (R² = 0.49), todavía queda un 51% de variabilidad sin explicar, lo cual sugiere que otros factores también influyen en el precio y deben añadirse en modelos más complejos (regresión múltiple).
# Modelo Simple 2: Precio vs Baños
modsimple2 = lm(precio_millon ~ Banos, data = datos_sub)
summary(modsimple2)
##
## Call:
## lm(formula = precio_millon ~ Banos, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -186.56 -45.78 2.96 34.22 333.44
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 40.254 6.164 6.531 1.04e-10 ***
## Banos 85.261 2.473 34.474 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 58.08 on 1006 degrees of freedom
## Multiple R-squared: 0.5416, Adjusted R-squared: 0.5411
## F-statistic: 1188 on 1 and 1006 DF, p-value: < 2.2e-16
# Modelo Simple 3: Precio vs Habitaciones
modsimple3 = lm(precio_millon ~ Habitaciones, data = datos_sub)
summary(modsimple3)
##
## Call:
## lm(formula = precio_millon ~ Habitaciones, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -214.37 -40.73 -5.73 40.33 387.45
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 12.853 10.539 1.22 0.223
## Habitaciones 78.940 3.532 22.35 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 70.12 on 1006 degrees of freedom
## Multiple R-squared: 0.3318, Adjusted R-squared: 0.3311
## F-statistic: 499.6 on 1 and 1006 DF, p-value: < 2.2e-16
precio_millon=40.25+85.26 * baños
Interpretación de la pendiente: Por cada baño adicional en la vivienda, se espera que el precio promedio aumente en 85.26 millones de pesos.
Significancia estadística: El coeficiente de baños es altamente significativo (\(p < 2 \times 10^{-16}\)), demostrando que la cantidad de baños es un predictor determinante del valor de los inmuebles en Valle del Lili.
Ajuste del modelo (R² = 0.3318): El modelo explica únicamente el 33.18% de la variabilidad del precio, siendo el ajuste más bajo de los tres modelos simples evaluados
Comparación y Selección de Modelos SimplesCapacidad explicativa: El Modelo 2 (Baños) alcanza el mayor poder predictivo individual con un R² = 54.16%, seguido por el Modelo 1 (Área construida) con un R² = 49.00%, mientras que el Modelo 3 (Habitaciones) se ubica rezagado con un R² = 33.180%.
Poder de los predictores: Aunque la cantidad de baños presenta una correlación empírica alta al asociarse a viviendas más amplias o de tipología casa, el área construida sigue siendo la variable física fundamental sobre la cual se valoran los metros cuadrados en el mercado.
Justificación hacia la modelación múltiple: Ningún modelo simple supera el 55% de explicación de la varianza. Esta limitación demuestra que el precio de la vivienda es multivariado y justifica evaluar los supuestos del modelo lineal (análisis de residuos) y combinar estas variables en modelos de regresión múltiple.
# Validación de supuestos del Modelo 1 (Área construida)
par(mfrow = c(2, 2))
plot(modsimple)
par(mfrow = c(1, 1))
Los gráficos diagnósticos confirman que el modelo simple en escala natural no cumple los supuestos clásicos:
Heterocedasticidad y no linealidad: La dispersión de los residuos se amplía a medida que aumenta el precio estimado, mostrando varianza no constante. Falta de normalidad: El gráfico Q-Q evidencia desviaciones severas en los extremos frente a la diagonal teórica.
Puntos influyentes: El registro 6121 supera los límites de la distancia de Cook, actuando como un dato atípico que sesga la pendiente. Para corregir estos problemas, estabilizar la varianza y amortiguar el efecto de los valores atípicos, es metodológicamente pertinente aplicar una transformación logarítmica.
# Modelo con transformación logarítmica
mod_log = lm(log(precio_millon) ~ log(Area_contruida), data = datos_sub)
summary(mod_log)
##
## Call:
## lm(formula = log(precio_millon) ~ log(Area_contruida), data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.48167 -0.13179 0.02407 0.13298 0.56972
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.39082 0.06930 34.50 <2e-16 ***
## log(Area_contruida) 0.69287 0.01569 44.16 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1896 on 1006 degrees of freedom
## Multiple R-squared: 0.6597, Adjusted R-squared: 0.6593
## F-statistic: 1950 on 1 and 1006 DF, p-value: < 2.2e-16
# Diagnóstico de supuestos del modelo transformado
par(mfrow = c(2, 2))
plot(mod_log)
par(mfrow = c(1, 1))
Modelo con transformación logarítmica: Precio vs. ÁreaEcuación estimada: log(precio_millon) = 2.39 + 0.69 * log(Area_contruida)
Interpretación: Por cada aumento del 1% en el área construida, el precio del inmueble se incrementa en promedio un 0.69%. Ajuste: El coeficiente de determinación R² sube del 49% al 66% (R² = 0.6597), mejorando de forma notable la capacidad predictiva.
Validación de supuestos: La transformación estabilizó la varianza de los errores (mitiga la heterocedasticidad), mejoró la simetría y normalidad en el gráfico Q-Q, y neutralizó el efecto palanca del dato atípico (registro 6121). La transformación es completamente pertinente y adecuada.
# 1. Transformación para Baños y gráficos de supuestos
mod_log2 = lm(log(precio_millon) ~ Banos, data = datos_sub)
summary(mod_log2)
##
## Call:
## lm(formula = log(precio_millon) ~ Banos, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.62824 -0.19108 0.04376 0.17438 0.68665
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.73410 0.02545 186.04 <2e-16 ***
## Banos 0.29639 0.01021 29.03 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2398 on 1006 degrees of freedom
## Multiple R-squared: 0.4558, Adjusted R-squared: 0.4553
## F-statistic: 842.7 on 1 and 1006 DF, p-value: < 2.2e-16
par(mfrow = c(2, 2))
plot(mod_log2)
par(mfrow = c(1, 1))
# 2. Transformación para Habitaciones y gráficos de supuestos
mod_log3 = lm(log(precio_millon) ~ Habitaciones, data = datos_sub)
summary(mod_log3)
##
## Call:
## lm(formula = log(precio_millon) ~ Habitaciones, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.78326 -0.18517 0.01834 0.20758 1.12457
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.63145 0.04132 112.1 <2e-16 ***
## Habitaciones 0.27695 0.01385 20.0 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2749 on 1006 degrees of freedom
## Multiple R-squared: 0.2845, Adjusted R-squared: 0.2838
## F-statistic: 399.9 on 1 and 1006 DF, p-value: < 2.2e-16
par(mfrow = c(2, 2))
plot(mod_log3)
par(mfrow = c(1, 1))
La transformación logarítmica fue altamente pertinente para el área construida, ya que logró elevar el R² del 49% al 66% y corrigió la heterocedasticidad. En cambio, para las variables discretas (baños y habitaciones), transformar el precio a escala logarítmica redujo su capacidad explicativa en comparación con los modelos lineales originales. Por lo tanto, la transformación se justifica prioritariamente para el modelo de área construida
##Estimación de los dos modelos
# Modelo Múltiple 1: Solo variables cuantitativas principales
mod_mult1 = lm(precio_millon ~ Area_contruida + Banos + Habitaciones, data = datos_sub)
summary(mod_mult1)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Banos + Habitaciones,
## data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -347.53 -38.66 1.35 29.54 273.95
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 26.66031 8.68495 3.070 0.0022 **
## Area_contruida 0.44067 0.03812 11.561 < 2e-16 ***
## Banos 49.48439 3.28797 15.050 < 2e-16 ***
## Habitaciones 20.23764 3.38083 5.986 2.99e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 52.62 on 1004 degrees of freedom
## Multiple R-squared: 0.6245, Adjusted R-squared: 0.6233
## F-statistic: 556.5 on 3 and 1004 DF, p-value: < 2.2e-16
# Modelo Múltiple 2: Cuantitativas + Variable DUMMY (Tipo de inmueble)
mod_mult2 = lm(precio_millon ~ Area_contruida + Banos + Habitaciones + Tipo, data = datos_sub)
summary(mod_mult2)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Banos + Habitaciones +
## Tipo, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -364.59 -39.13 2.25 28.11 279.21
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 14.17301 9.61343 1.474 0.14072
## Area_contruida 0.45383 0.03822 11.873 < 2e-16 ***
## Banos 54.16676 3.63290 14.910 < 2e-16 ***
## Habitaciones 21.31525 3.38703 6.293 4.64e-10 ***
## TipoCasa -17.91892 6.01601 -2.979 0.00297 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 52.42 on 1003 degrees of freedom
## Multiple R-squared: 0.6277, Adjusted R-squared: 0.6263
## F-statistic: 422.9 on 4 and 1003 DF, p-value: < 2.2e-16
##Punto 2
##Modelo Múltiple 1: Variables Cuantitativas Ecuación estimada: precio_millon = 26.66 + 0.44 * Area_contruida + 49.48 * Banos + 20.24 * Habitaciones
Área construida: Por cada metro cuadrado adicional, el precio aumenta en promedio 0.44 millones de pesos (440,000 COP), manteniendo constantes los baños y las habitaciones.
Baños: Por cada baño adicional, el precio sube en promedio 49.48 millones de pesos, manteniendo constantes las demás variables.
Habitaciones: Por cada habitación adicional, el precio se incrementa en promedio 20.24 millones de pesos, ceteris paribus.
Ajuste y significancia: El modelo explica el 62.45% de la variabilidad del precio (R² = 0.6245) y todas las variables son estadísticamente significativas (p < 0.001).
##Modelo Múltiple 2: Con Variable Dummy (Tipo de Vivienda) Ecuación estimada: precio_millon = 14.17 + 0.45 * Area_contruida + 54.17 * Banos + 21.32 * Habitaciones - 17.92 * TipoCasa
Interpretación de la Dummy (TipoCasa): La categoría base de referencia es Apartamento (TipoCasa = 0). A igual área, número de baños y habitaciones, una Casa tiene un precio promedio estimado de 17.92 millones de pesos menos que un Apartamento en Valle del Lili.
Significancia de la Dummy:El coeficiente de TipoCasa es estadísticamente significativo (p = 0.00297).
Ajuste: El R² se incrementa a 62.77% (R² ajustado = 0.6263).
# Selección automática de variables hacia atrás (Backward Stepwise) usando AIC
mod_step = step(mod_mult2, direction = "both")
## Start: AIC=7986.72
## precio_millon ~ Area_contruida + Banos + Habitaciones + Tipo
##
## Df Sum of Sq RSS AIC
## <none> 2755575 7986.7
## - Tipo 1 24373 2779949 7993.6
## - Habitaciones 1 108806 2864381 8023.8
## - Area_contruida 1 387274 3142849 8117.3
## - Banos 1 610760 3366335 8186.5
summary(mod_step)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Banos + Habitaciones +
## Tipo, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -364.59 -39.13 2.25 28.11 279.21
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 14.17301 9.61343 1.474 0.14072
## Area_contruida 0.45383 0.03822 11.873 < 2e-16 ***
## Banos 54.16676 3.63290 14.910 < 2e-16 ***
## Habitaciones 21.31525 3.38703 6.293 4.64e-10 ***
## TipoCasa -17.91892 6.01601 -2.979 0.00297 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 52.42 on 1003 degrees of freedom
## Multiple R-squared: 0.6277, Adjusted R-squared: 0.6263
## F-statistic: 422.9 on 4 and 1003 DF, p-value: < 2.2e-16
Como retirar cualquier predictor empeora el modelo (aumenta el AIC), el algoritmo conserva todas las variables (Area_contruida, Banos, Habitaciones y Tipo). El Modelo Múltiple 2 es seleccionado como el modelo óptimo.
##Validación de supuestos y transformación logarítmica
# Diagnóstico de supuestos del modelo múltiple final
par(mfrow = c(2, 2))
plot(mod_mult2)
par(mfrow = c(1, 1))
# Modelo múltiple con transformación logarítmica (Log-Lineal / Log-Log)
mod_mult_log = lm(log(precio_millon) ~ log(Area_contruida) + Banos + Habitaciones + Tipo, data = datos_sub)
summary(mod_mult_log)
##
## Call:
## lm(formula = log(precio_millon) ~ log(Area_contruida) + Banos +
## Habitaciones + Tipo, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.48465 -0.12683 0.03237 0.12597 0.59255
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.25141 0.09737 23.123 < 2e-16 ***
## log(Area_contruida) 0.68760 0.02775 24.782 < 2e-16 ***
## Banos 0.06624 0.01358 4.878 1.25e-06 ***
## Habitaciones 0.01121 0.01220 0.919 0.358
## TipoCasa -0.16645 0.02182 -7.630 5.44e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1838 on 1003 degrees of freedom
## Multiple R-squared: 0.681, Adjusted R-squared: 0.6798
## F-statistic: 535.4 on 4 and 1003 DF, p-value: < 2.2e-16
Los gráficos diagnósticos del modelo múltiple lineal evidencian el incumplimiento de los supuestos clásicos de regresión. En los gráficos de dispersión de residuos frente a valores ajustados se confirma la presencia de heterocedasticidad, ya que la variabilidad del error se incrementa conforme aumenta el valor estimado de los inmuebles. Asimismo, el gráfico de normalidad presenta marcadas desviaciones en los extremos respecto a la línea diagonal teórica, evidenciando colas pesadas y una marcada asimetría impulsada por registros extremos. En el análisis de apalancamiento, la observación 6121 muestra un nivel de apalancamiento superior a 0.30 y un residuo severamente negativo, actuando como un dato atípico influyente que distorsiona las estimaciones globales del modelo.
Para corregir estas deficiencias, se estimó el modelo múltiple transformado: log(precio_millon) = 2.25 + 0.69 * log(Area_contruida) + 0.066 * Banos + 0.011 * Habitaciones - 0.166 * TipoCasa. Con esta especificación, el coeficiente de determinación R² aumentó al 68.10% (frente al 62.77% del modelo lineal), optimizando el ajuste general y la capacidad explicativa. Las variables de área construida, baños y el tipo de vivienda resultaron altamente significativas (valores p menores a 0.001), mientras que la variable habitaciones perdió significancia estadística (p = 0.358), lo que indica que su aporte informativo queda absorbido por el metraje y los baños al modelar de forma no lineal. La variable dummy muestra que, a igualdad de condiciones en área y distribución, una casa tiene un precio promedio estimado cerca de un 16.6% menor que un apartamento en este sector. La transformación resultó plenamente pertinente, ya que comprimió las escalas, estabilizó la varianza y amortiguó de forma efectiva el impacto del valor atípico.
# Predicción hipotética (Apartamento de 80 m2, 2 baños, 3 habitaciones)
caso_nuevo = data.frame(
Area_contruida = 80,
Banos = 2,
Habitaciones = 3,
Tipo = "Apartamento"
)
# Predicción en escala lineal y escala original (aplicando exp para el modelo log)
pred_lineal = predict(mod_mult2, newdata = caso_nuevo)
pred_log = exp(predict(mod_mult_log, newdata = caso_nuevo))
pred_lineal
## 1
## 222.7587
pred_log
## 1
## 228.2827
# Cálculo de la métrica MAE (Error Absoluto Medio)
mae_lineal = mean(abs(datos_sub$precio_millon - predict(mod_mult2)))
mae_log = mean(abs(datos_sub$precio_millon - exp(predict(mod_mult_log))))
mae_lineal
## [1] 40.02446
mae_log
## [1] 37.0211
##Predicción hipotética y métricas de evaluación (MAE)##
Predicción para un caso hipotético: Para un apartamento representativo en Valle del Lili (80 m², 2 baños y 3 habitaciones), el modelo múltiple lineal estima un precio de 222.76 millones de pesos, mientras que el modelo múltiple con transformación logarítmica predice 228.28 millones de pesos. Ambas estimaciones resultan consistentes y acordes con la dinámica de precios observada en la zona.
Evaluación del error (MAE):El Error Absoluto Medio del modelo lineal es de 40.02 millones de pesos, mientras que el modelo logarítmico reduce el error a 37.02 millones de pesos. Esta disminución de 3 millones en el margen de error promedio confirma que el modelo transformado no solo mejora el ajuste teórico (\(R^2\)), sino que también ofrece una mayor precisión predictiva.
##Conclusión y Selección del Modelo Fina
lEl modelo óptimo para estimar los precios en Valle del Lili es el modelo múltiple con transformación logarítmica. Presenta el mejor ajuste global (\(R^2 = 68.10\%\)) y el menor margen de error promedio (\(\text{MAE} = 37.02\) millones de pesos), logrando corregir los problemas de heterocedasticidad y amortiguar el sesgo de las observaciones atípicas presentes en la escala natural.