La regresión lineal es un método que permite analizar la relación entre una variable que queremos predecir y diferentes variables que pueden explicarla.
En R se utiliza la función lm() para crear este tipo de modelos.
Una medida importante para evaluar el modelo es la R-Cuadrada, que toma valores entre 0 y 1. Entre más cercano sea el valor a 1, mayor cantidad de la variación de la variable objetivo está explicando el modelo.
Una inmobiliaria cuenta con información de diferentes casas que ya fueron vendidas. La base incluye características como tamaño, ubicación, estacionamiento y distancia a distintos servicios.
El objetivo es generar un modelo de regresión lineal que permita estimar el precio de una casa a partir de sus características.
# install.packages("corrplot")
library(corrplot)
df <- read.csv("/Users/kamilahchaidez/Downloads/HousePriceData.csv")
# Resumen general de los datos
summary(df)
## Observation Dist_Taxi Dist_Market Dist_Hospital
## Min. : 1.0 Min. : 146 Min. : 1666 Min. : 3227
## 1st Qu.:237.0 1st Qu.: 6477 1st Qu.: 9367 1st Qu.:11302
## Median :469.0 Median : 8228 Median :11149 Median :13189
## Mean :468.4 Mean : 8235 Mean :11022 Mean :13091
## 3rd Qu.:700.0 3rd Qu.: 9939 3rd Qu.:12675 3rd Qu.:14855
## Max. :932.0 Max. :20662 Max. :20945 Max. :23294
##
## Carpet Builtup Parking City_Category
## Min. : 775 Min. : 932 Length :905 Length :905
## 1st Qu.: 1317 1st Qu.: 1579 N.unique : 4 N.unique : 3
## Median : 1478 Median : 1774 N.blank : 0 N.blank : 0
## Mean : 1511 Mean : 1794 Min.nchar: 4 Min.nchar: 5
## 3rd Qu.: 1654 3rd Qu.: 1985 Max.nchar: 12 Max.nchar: 5
## Max. :24300 Max. :12730
## NAs :7
## Rainfall House_Price
## Min. :-110.0 Min. : 1492000
## 1st Qu.: 600.0 1st Qu.: 4623000
## Median : 780.0 Median : 5860000
## Mean : 786.9 Mean : 6083992
## 3rd Qu.: 970.0 3rd Qu.: 7200000
## Max. :1560.0 Max. :150000000
##
# Tipo de variables
str(df)
## 'data.frame': 905 obs. of 10 variables:
## $ Observation : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Dist_Taxi : int 9796 8294 11001 8301 10510 6665 13153 5882 7495 8233 ...
## $ Dist_Market : int 5250 8186 14399 11188 12629 5142 11869 9948 11589 7067 ...
## $ Dist_Hospital: int 10703 12694 16991 12289 13921 9972 17811 13315 13370 11400 ...
## $ Carpet : int 1659 1461 1340 1451 1770 1442 1542 1261 1090 1030 ...
## $ Builtup : int 1961 1752 1609 1748 2111 1733 1858 1507 1321 1235 ...
## $ Parking : chr "Open" "Not Provided" "Not Provided" "Covered" ...
## $ City_Category: chr "CAT B" "CAT B" "CAT A" "CAT B" ...
## $ Rainfall : int 530 210 720 620 450 760 1030 1020 680 1130 ...
## $ House_Price : int 6649000 3982000 5401000 5373000 4662000 4526000 7224000 3772000 4631000 4415000 ...
# Primeras filas
head(df)
## Observation Dist_Taxi Dist_Market Dist_Hospital Carpet Builtup Parking
## 1 1 9796 5250 10703 1659 1961 Open
## 2 2 8294 8186 12694 1461 1752 Not Provided
## 3 3 11001 14399 16991 1340 1609 Not Provided
## 4 4 8301 11188 12289 1451 1748 Covered
## 5 5 10510 12629 13921 1770 2111 Not Provided
## 6 6 6665 5142 9972 1442 1733 Open
## City_Category Rainfall House_Price
## 1 CAT B 530 6649000
## 2 CAT B 210 3982000
## 3 CAT A 720 5401000
## 4 CAT B 620 5373000
## 5 CAT B 450 4662000
## 6 CAT B 760 4526000
# Últimas filas
tail(df)
## Observation Dist_Taxi Dist_Market Dist_Hospital Carpet Builtup Parking
## 900 927 10915 17486 15964 1549 1851 Not Provided
## 901 928 12176 8518 15673 1582 1910 Covered
## 902 929 7214 8717 10553 1387 1663 Open
## 903 930 7423 11708 13220 1200 1436 Open
## 904 931 15082 14700 19617 1299 1560 Open
## 905 932 9297 12537 14418 1174 1429 Covered
## City_Category Rainfall House_Price
## 900 CAT C 1220 7062000
## 901 CAT C 1080 6639000
## 902 CAT A 850 8208000
## 903 CAT A 1060 7644000
## 904 CAT B 770 9661000
## 905 CAT C 1110 5434000
La variable que queremos predecir es House_Price, mientras que las demás variables contienen diferentes características de las casas.
Algunas variables son numéricas y otras son categóricas, como
Parking y City_Category.
# Seleccionar únicamente las columnas numéricas
numericas <- df[sapply(df, is.numeric)]
# Crear matriz de correlaciones
correlacion <- cor(
numericas,
use = "complete.obs"
)
# Graficar correlaciones
corrplot(correlacion)
La gráfica permite identificar cuáles variables presentan una relación más fuerte.
Los círculos más grandes representan correlaciones más altas. En este
caso, las variables relacionadas con el tamaño de la
casa, como Carpet y Builtup,
presentan una relación importante entre ellas y también con el
precio.
Por otro lado, algunas variables de distancia presentan una relación
mucho menor con House_Price.
# Revisar valores faltantes por columna
colSums(is.na(df))
## Observation Dist_Taxi Dist_Market Dist_Hospital Carpet
## 0 0 0 0 7
## Builtup Parking City_Category Rainfall House_Price
## 0 0 0 0 0
# Eliminar filas con datos faltantes
df <- na.omit(df)
Se eliminan los registros que contienen valores faltantes para trabajar con una base completa antes de generar el modelo.
Como la cantidad de registros eliminados es pequeña comparada con el total de observaciones, se puede continuar con el análisis sin perder una cantidad importante de información.
# Crear modelo utilizando todas las variables
regresion <- lm(
House_Price ~ .,
data = df
)
summary(regresion)
##
## Call:
## lm(formula = House_Price ~ ., data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3694478 -799483 -54242 780191 4539531
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.331e+06 3.781e+05 14.097 < 2e-16 ***
## Observation 4.070e+02 1.524e+02 2.670 0.00773 **
## Dist_Taxi 2.777e+01 2.685e+01 1.034 0.30127
## Dist_Market 1.444e+01 2.083e+01 0.693 0.48839
## Dist_Hospital 4.921e+01 3.011e+01 1.634 0.10257
## Carpet 9.894e+03 1.423e+02 69.508 < 2e-16 ***
## Builtup -7.544e+03 2.407e+02 -31.344 < 2e-16 ***
## ParkingNo Parking -6.156e+05 1.388e+05 -4.435 1.04e-05 ***
## ParkingNot Provided -4.975e+05 1.236e+05 -4.027 6.15e-05 ***
## ParkingOpen -2.575e+05 1.127e+05 -2.285 0.02253 *
## City_CategoryCAT B -1.874e+06 9.613e+04 -19.494 < 2e-16 ***
## City_CategoryCAT C -2.897e+06 1.059e+05 -27.367 < 2e-16 ***
## Rainfall -9.559e+01 1.543e+02 -0.620 0.53564
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1224000 on 885 degrees of freedom
## Multiple R-squared: 0.9433, Adjusted R-squared: 0.9426
## F-statistic: 1228 on 12 and 885 DF, p-value: < 2.2e-16
En los resultados del modelo se puede observar qué variables presentan una mayor relación con el precio.
Las variables con mayor significancia son principalmente:
CarpetBuiltupParkingCity_CategoryMientras que variables como las distancias al mercado, hospital o taxi presentan menor importancia en el modelo.
La R-Cuadrada del modelo es aproximadamente 0.9433, lo que significa que el modelo explica cerca del 94% de la variación del precio de las casas.
La variable Observation no representa una característica
real de una casa, ya que funciona solamente como un identificador de los
registros, por lo que no es recomendable utilizarla para realizar
predicciones.
# Crear un segundo modelo únicamente con las variables más relevantes
regresion2 <- lm(
House_Price ~ Carpet + Builtup + Parking + City_Category,
data = df
)
summary(regresion2)
##
## Call:
## lm(formula = House_Price ~ Carpet + Builtup + Parking + City_Category,
## data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3430967 -802513 -46915 775070 4263090
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6477702.2 272077.2 23.808 < 2e-16 ***
## Carpet 9968.8 143.3 69.584 < 2e-16 ***
## Builtup -7611.6 243.3 -31.279 < 2e-16 ***
## ParkingNo Parking -536301.8 139943.6 -3.832 0.000136 ***
## ParkingNot Provided -457380.4 125020.1 -3.658 0.000269 ***
## ParkingOpen -236576.3 114356.8 -2.069 0.038857 *
## City_CategoryCAT B -1918518.1 97007.4 -19.777 < 2e-16 ***
## City_CategoryCAT C -2908756.6 107359.6 -27.094 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1243000 on 890 degrees of freedom
## Multiple R-squared: 0.9412, Adjusted R-squared: 0.9407
## F-statistic: 2034 on 7 and 890 DF, p-value: < 2.2e-16
En este segundo modelo se eliminaron las variables que tenían menor importancia.
La R-Cuadrada se mantiene aproximadamente en 0.9412, por lo que disminuye muy poco comparada con el modelo anterior.
Esto indica que se puede utilizar un modelo más sencillo con menos variables y obtener prácticamente el mismo nivel de explicación.
Los resultados del modelo permiten observar cómo las diferentes características modifican el precio estimado de una casa.
Carpet: al aumentar el tamaño de la propiedad, también aumenta el precio estimado.
Builtup: se encuentra muy relacionada con
Carpet, por lo que ambas variables pueden influir entre sí
dentro del modelo.
City_Category: la ubicación tiene un efecto importante en el precio. Las casas ubicadas en diferentes categorías de ciudad presentan diferencias considerables en su valor.
Parking: contar o no con determinado tipo de estacionamiento también modifica el precio esperado de la propiedad.
# Crear ejemplos de casas nuevas para estimar su precio
datos_nuevos <- data.frame(
Carpet = 1500,
Builtup = 1800,
Parking = "Covered",
City_Category = c(
"CAT A",
"CAT B",
"CAT C"
)
)
predict(
regresion2,
newdata = datos_nuevos
)
## 1 2 3
## 7729938 5811420 4821181
En este ejemplo se utiliza una casa con las mismas características de superficie y estacionamiento, pero se modifica la categoría de la ciudad.
De esta forma podemos observar cómo la ubicación puede cambiar considerablemente el precio estimado, aunque el resto de las características de la propiedad permanezcan iguales.
A partir del modelo de regresión lineal se observa que las variables que tienen una mayor relación con el precio de una casa son principalmente su tamaño, la ubicación y el estacionamiento.
El primer modelo explicó aproximadamente el 94% de la variación del precio, pero al eliminar variables poco relevantes el resultado prácticamente no cambió.
Por esta razón, el segundo modelo es más conveniente, ya que utiliza menos variables y mantiene un nivel de explicación muy similar.
Finalmente, las predicciones muestran que una casa con las mismas características puede tener precios diferentes dependiendo principalmente de la categoría de la ciudad donde se encuentre.