En este informe se realizará un estudio del valor de la vivienda en Boston en función de diversos factores que hacen que la tasación aumente o disminuya. Se tratará de determinar si las variables existentes en el fichero de datos a analizar tienen una cierta relación con el precio aproximado de las casas. Por otra parte, dada la gran cantidad de variables con las que contamos y el inmenso número de observaciones tomadas, prestaremos atención a aquellos pares de variables cuya correlación estadística es alta.
El fichero empleado cuenta con 506 observaciones tomadas por el Servicio del Censo de EE.UU. en 1978. Estas observaciones representan los distintos vecindarios de Boston, en las que se tuvieron en cuenta tasas de criminalidad, calidad del aire, edad de las viviendas o el nivel socioeconómico de los propios residentes, entre otras características.
Para empezar, leeremos nuestro fichero de datos ‘BostonHousing’, que está ubicado en la carpeta ‘data’. El fichero descargado se encuentra en formato csv.
boston_housing <- read.csv("../data/BostonHousing.csv", sep=",", encoding = "UTF-8")
A continuación, observamos un resumen de las variables con las que contamos.
summary(boston_housing)
## crim zn indus chas
## Min. : 0.00632 Min. : 0.00 Min. : 0.46 Min. :0.00000
## 1st Qu.: 0.08205 1st Qu.: 0.00 1st Qu.: 5.19 1st Qu.:0.00000
## Median : 0.25651 Median : 0.00 Median : 9.69 Median :0.00000
## Mean : 3.61352 Mean : 11.36 Mean :11.14 Mean :0.06917
## 3rd Qu.: 3.67708 3rd Qu.: 12.50 3rd Qu.:18.10 3rd Qu.:0.00000
## Max. :88.97620 Max. :100.00 Max. :27.74 Max. :1.00000
## nox rm age dis
## Min. :0.3850 Min. :3.561 Min. : 2.90 Min. : 1.130
## 1st Qu.:0.4490 1st Qu.:5.886 1st Qu.: 45.02 1st Qu.: 2.100
## Median :0.5380 Median :6.208 Median : 77.50 Median : 3.207
## Mean :0.5547 Mean :6.285 Mean : 68.57 Mean : 3.795
## 3rd Qu.:0.6240 3rd Qu.:6.623 3rd Qu.: 94.08 3rd Qu.: 5.188
## Max. :0.8710 Max. :8.780 Max. :100.00 Max. :12.127
## rad tax ptratio b
## Min. : 1.000 Min. :187.0 Min. :12.60 Min. : 0.32
## 1st Qu.: 4.000 1st Qu.:279.0 1st Qu.:17.40 1st Qu.:375.38
## Median : 5.000 Median :330.0 Median :19.05 Median :391.44
## Mean : 9.549 Mean :408.2 Mean :18.46 Mean :356.67
## 3rd Qu.:24.000 3rd Qu.:666.0 3rd Qu.:20.20 3rd Qu.:396.23
## Max. :24.000 Max. :711.0 Max. :22.00 Max. :396.90
## lstat medv
## Min. : 1.73 Min. : 5.00
## 1st Qu.: 6.95 1st Qu.:17.02
## Median :11.36 Median :21.20
## Mean :12.65 Mean :22.53
## 3rd Qu.:16.95 3rd Qu.:25.00
## Max. :37.97 Max. :50.00
Estas 14 variables tienen nombres poco intuitivos a la hora de querer relacionarlas entre sí. Por ello, optaremos por cambiar sus nombres de modo que nos digan qué están midiendo. Aparte, habrá que tener en cuenta que no deben ser nombres muy largos para que los gráficos se puedan ver adecuadamente.
colnames(boston_housing)<-c("Crimenes", "Habitabilidad", "Bullicio", "Rio",
"Conc_NO", "Rooms", "Age", "Dist_Empleo",
"Accesos","Carga_Fiscal", "Alu_Prof",
"Pob_Afro", "Pobreza", "Precio")
Estos son los significados de las variables que hemos renombrado:
Crimenes(crim): Indica la tasa de
criminalidad por zona (crímenes por cada 100.000 habitantes).
Habitabilidad (zn): Muestra la proporción
de espacio residencial para lotes de más de 25.000 pies
cuadrados.
Bullicio (indus): Proporción de superficie
para espacios comerciales donde se aglomera gran cantidad de gente por
zona (acres de negocios no minoristas).
Rio (chas): Variable binaria que indica si
la zona limita con el río Charles (1 sí, 0 no).
Conc_NO (nox): Mide la concentración de
óxidos nítricos en el aire de esa zona.
Rooms (rm): Proporciona la media de
habitaciones por viviendas en la zona.
Age (age): Estima la proporción de
viviendas construidas antes del año 1940. Cuantas más casas anteriores a
esta fecha, más antigua es la zona.
Dist_Empleo (dis): Anota una distancia
ponderada respecto a 5 centros de empleo en Boston.
Accesos (rad): Nos aporta un índice de
accesibilidad a las principales vías de comunicación (autopistas,
carreteras).
Carga_Fiscal (tax): Marca la tasa de
impuesto a la vivienda respecto a su valor total. Para dos casas
semejantes los impuestos a pagar serán mayores en función de la
tasa.
Alu_Prof (pratio): Relaciona la cantidad
alumnos en colegios por cada profesor.
Pob_Afro (black): Muestra la proporción de
habitantes afroamericanos.
Pobreza (lstat): Nos ofrece el porcentaje
de población con un nivel socioeconómico bajo.
Precio (medv): Corresponde al valor mediano
de las viviendas en la zona (en miles de dólares).
Comprobamos que no haya ningún dato perdido en el fichero.
any(is.na(boston_housing))
## [1] FALSE
Como estrategia, generaremos un mapa de color con el que conoceremos a priori como es la relación entre cada par de variables.
attach(boston_housing)
corrplot::corrplot(cor(boston_housing))
Probaremos a graficar la distribución de los valores medianos de las casas.
hist(boston_housing$Precio, probability = T, main = "Distribución de valores mediano de las casas", xlab = "Valor mediano de la casa")
curve(dnorm(x, mean(boston_housing$Precio), sd(boston_housing$Precio)),
add = TRUE,col='red', xlim = c(0,50))
El histograma graficado tiene una forma singular. Según va creciendo el valor de la casa la frecuencia aumenta, hasta que el valor llega a los 25.000 dolares, donde la frecuencia se desploma para luego decrecer paulatinamente. Tras dibujar la campana de Gauss, vemos que no termina de asemejarse a una distribución normal debido a la falta de simetría en el histograma.
En el mapa de calor anterior, nos dimos cuenta de que
Rooms es una de las variables que juega un papel importante
a la hora de decidir el precio de la vivienda. En ese caso, reflejaremos
esta relación mediante un gráfico de dispersión.
cor(Precio, Rooms)
## [1] 0.6953599
plot(Rooms, Precio, xlab = "Nº de habitaciones", ylab = "Valor mediano de la casa", pch=20)
abline(lm(data.frame(Precio, Rooms)), col = 'purple', lwd=3)
La recta se ajusta a muchos puntos, pero otros muchos se alejan demasiado. Para plasmar estos errores, podemos hacer un gráfico de residuos.
lm(Precio~Rooms)
##
## Call:
## lm(formula = Precio ~ Rooms)
##
## Coefficients:
## (Intercept) Rooms
## -34.671 9.102
m<-function(x) -34.671 + 9.102*x
e<-Precio-m(Rooms)
plot(e, type='h', ylab='Residuos', xlab='Registros')
Obsérvese que entre los registros 350 y 475 (aproximadamente) encontramos una gran cantidad de residuos. Podríamos hacer un nuevo data frame y buscarle una explicación mediante otras variables.
par(mfrow=c(2,2))
bh_2<-boston_housing[c(350:475),]
hist(bh_2$Dist_Empleo, xlab = "Distancia media a zonas de empleo",
main = " ")
hist(bh_2$Bullicio, xlab = "Proporción de espacios comerciales de tránsito",
main = " ")
hist(bh_2$Conc_NO, xlab = "Concentración de NO en la zona",
main = " ")
hist(bh_2$Precio, xlab = "Valor mediano de la casa",
main = " ")
Estos últimos registros analizados son de casas con un valor, en su
mayoría, menor a los 25.000 dolares, cifra que se corresponde con la
media de la variable Precio de boston_housing.
Las características de estos registros se corresponden con casas donde
la distancia al empleo es corta, hay alto nivel de contaminación y son
zonas donde hay bastante tránsito de gente. Pueden tratarse de viviendas
que se encuentran en pleno centro de Boston. Aunque, de significar eso,
las casas donde hay mayor movimiento comercial y empresarial serían las
más baratas, contra todo pronóstico. Sin embargo, estos vecindarios no
deberían ser de alto índice de pobreza por su constante actividad
económica. Salgamos de dudas con un gráfico.
hist(bh_2$Pobreza, probability = T, xlab = "Índice de pobreza", main = "Distribución de pobreza")
curve(dnorm(x, mean(bh_2$Pobreza), sd(bh_2$Pobreza)),
add = TRUE,col='red', xlim = c(0,40))
Nótese la casi perfecta simetría del gráfico. Al parecerse el histograma a una campana de Gauss, deducimos que se trata una distribución normal donde los propietarios más frecuentes son los que tienen un índice de pobreza entorno al 15 y 20%. Ahora bien, ¿quiere decir esto que los vecindarios que hemos seleccionado tienen un índice de pobreza medio? Deberíamos en ese caso hacer una comparación con los registros de todas las zonas.
hist(boston_housing$Pobreza, probability = T, xlab = "Índice de pobreza", main = "Distribución de pobreza (Global)")
curve(dnorm(x, mean(boston_housing$Pobreza), sd(boston_housing$Pobreza)),
add = TRUE,col='red', xlim = c(0,40))
En esta ocasión, la curva normal se ha desplazado significativamente
hacia la izquierda, donde las barras de frecuencia más altas están
entorno al 10%. Además, la densidad de población con un índice de
pobreza entorno al 30% ha disminuido considerablemente. Entonces, las
casas de bh_2 son de zonas con un índice de pobreza
generalmente mayor respecto al global, lo que da una explicación a
porque para estas viviendas el valor mediano es menor y no se ajustaba a
la recta de regresión.
Ahora nos centraremos en el estudio de otras variables. Apreciábamos en el mapa de calor anterior que existía una fuerte correlación positiva entre la accesibilidad a las vías de comunicación y la carga fiscal de la vivienda.
cor(Accesos, Carga_Fiscal)
## [1] 0.9102282
plot(Accesos,Carga_Fiscal, pch=20)
abline(lm(Carga_Fiscal~Accesos), col='purple')
sum(Accesos>20 & Carga_Fiscal>500)
## [1] 132
sum(Carga_Fiscal>700)
## [1] 5
Parece que no tiene sentido la alta relación entre estas dos variables tras ver la nube de puntos, pero tenemos que tener en cuenta que son variables discretas, lo que quiere decir que varios puntos (x,y) se pueden repetir varias veces.
En el diagrama distinguimos tres grupos, uno en la esquina inferior izquierda donde se aglutinan la mayoría de puntos, otro en la esquina superior derecha donde se concentran 132 registros y otro grupo más pequeño (5 registros) en la esquina superior izquierda donde están los valores atípicos. El primer grupo corresponde a casas con difíciles accesos a carreteras pero menor tasa de impuestos y el segundo grupo a viviendas con mayor accesibilidad a carreteras pero con mayor carga fiscal.
cor(Conc_NO,Bullicio)
## [1] 0.7636514
La pareja de variables Conc_NO y Bullicio
también tienen buena correlación. Es lógico pensar que en aquellas zonas
donde hay más tráfico sean las que más problemas de contaminación del
aire tengan.
Importamos la librería tidyverse para poder ilustrar los
datos con representaciones gráficas.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
cor(Conc_NO, Dist_Empleo)
## [1] -0.7692301
boston_housing %>%
ggplot(aes(x=Dist_Empleo, y=Conc_NO)) +
geom_point() +
geom_smooth(col='red')
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Las variables Conc_NO y Dist_Empleo deben
ser inversamente proporcionales, ya que cuanto más alejada esté la
vivienda del empleo más alejada también estará de otros espacios
comerciales donde existe contaminación acústica. Luego, al comparar esta
vez la distancia al empleo con la contaminación del aire vemos como el
valor de la correlación es muy parecido en valor absoluto con el de la
anterior correlación.
cor(Dist_Empleo, Age)
## [1] -0.7478805
boston_housing %>%
ggplot(aes(x=Dist_Empleo, y=Age)) +
geom_point() +
geom_smooth(col='red')
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
La distancia al empleo y la antigüedad de las viviendas es inversamente proporcional. La explicación a esto es que según las ciudades van creciendo a lo largo de los años las viviendas se construyen en zonas más periféricas, de modo que el radio del núcleo urbano va creciendo con el paso del tiempo. Por esta razón, las vecindarios con viviendas de más edad se encuentran en el casco urbano de la ciudad y las más nuevas se encuentran alejadas de los puntos neurálgicos de Boston.
Para finalizar, haremos un gráfico de tarta para mostrar cuales son las variables que más han influido en el precio.
coef_cor <- cor(boston_housing)[, "Precio"]
coef_det<-coef_cor^2
coef_det<-coef_det[-14]
pie(coef_det)
El set de datos BostonHousing cuenta con una gran cantidad
de información a la hora de establecer una relación entre el precio de
la vivienda y los factores que determinan su valor. Hay variables que
han tenido un papel destacado a la hora influir en el precio, como
Pobreza y Rooms, lo que refleja la importancia
de tener en cuenta estos aspectos en la planificación urbana y el
desarrollo de políticas públicas. Por otro lado, variables como
Habitabilidad, Rio o Dist_Empleo
no han ayudado mucho a determinar el valor de la casa según la zona,
pero han servido para establecer una relación con otras variables
abriendo nuevos caminos a futuras investigaciones en el área
inmobiliaria.
En definitiva, podemos concluir que el análisis de las viviendas en Boston puede ser muy útil para tomar decisiones en cuanto a inversiones inmobiliarias o políticas de vivienda se refiere.