Teoría

lm() es la función en R para ajustar modelos lineales. Es el modelo estadístico más básico que existe y más fácil de interpretar. Para interpretarlo se usa la medida R-cuadrada, que significa qué tan cerca están los datos de la regresión. Va de 0 a 1, dónde 1 es que el modelo explica toda la variabilidad.

Contexto

Una inmobiliaria cuenta con el registro de propiedades vendidas, incluyendo su ubicación, características físicas y categoría de la ciudad. Se desea generar un modelo predictivo del precio de venta.

Instalar paquetes y librerías

# install.packages("corrplot")
library(corrplot)
## corrplot 0.95 loaded

Importar la base de datos

df = read.csv(file.choose())

Entender la base de 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  
## 
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 ...
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
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
correlaciones = cor(df[,sapply(df, is.numeric)], use="complete.obs")
corrplot(correlaciones)

Limpiar la base de datos

df$Carpet[is.na(df$Carpet)] = median(df$Carpet, na.rm=TRUE)
df = df[df$Observation != 361, ]
df = df[df$Rainfall >= 0, ]

Generar el modelo

regresion = lm(House_Price~.-Observation, data=df)
summary(regresion)
## 
## Call:
## lm(formula = House_Price ~ . - Observation, data = df)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -3553952  -814979   -69511   779532  4458423 
## 
## Coefficients:
##                       Estimate Std. Error t value Pr(>|t|)    
## (Intercept)          5.631e+06  3.678e+05  15.310  < 2e-16 ***
## Dist_Taxi            3.235e+01  2.683e+01   1.206 0.228238    
## Dist_Market          1.147e+01  2.077e+01   0.552 0.581092    
## Dist_Hospital        4.711e+01  3.011e+01   1.565 0.118000    
## Carpet               2.091e+03  2.423e+03   0.863 0.388295    
## Builtup             -1.073e+03  2.020e+03  -0.531 0.595274    
## ParkingNo Parking   -5.810e+05  1.389e+05  -4.183 3.16e-05 ***
## ParkingNot Provided -4.760e+05  1.230e+05  -3.871 0.000116 ***
## ParkingOpen         -2.430e+05  1.122e+05  -2.166 0.030603 *  
## City_CategoryCAT B  -1.896e+06  9.584e+04 -19.784  < 2e-16 ***
## City_CategoryCAT C  -2.901e+06  1.059e+05 -27.406  < 2e-16 ***
## Rainfall            -1.486e+02  1.551e+02  -0.958 0.338301    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1226000 on 891 degrees of freedom
## Multiple R-squared:  0.5003, Adjusted R-squared:  0.4942 
## F-statistic:  81.1 on 11 and 891 DF,  p-value: < 2.2e-16

Ajustar el modelo

regresion2 = lm(House_Price~Parking+City_Category, data=df)
summary(regresion2)
## 
## Call:
## lm(formula = House_Price ~ Parking + City_Category, data = df)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -3406949  -793897   -57389   778314  4445611 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)          7706056     106884  72.097  < 2e-16 ***
## ParkingNo Parking    -519667     141252  -3.679 0.000248 ***
## ParkingNot Provided  -466367     125284  -3.722 0.000210 ***
## ParkingOpen          -250946     114721  -2.187 0.028967 *  
## City_CategoryCAT B  -1901161      97502 -19.499  < 2e-16 ***
## City_CategoryCAT C  -2891211     108336 -26.687  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1258000 on 897 degrees of freedom
## Multiple R-squared:  0.4711, Adjusted R-squared:  0.4681 
## F-statistic: 159.8 on 5 and 897 DF,  p-value: < 2.2e-16

Generar Predicciones

datos_nuevos = data.frame(Parking=c("Covered","Not Provided","Open","No Parking"),
                           City_Category=c("CAT A","CAT B","CAT B","CAT C"))
predict(regresion2, datos_nuevos)
##       1       2       3       4 
## 7706056 5338528 5553949 4295178
LS0tDQp0aXRsZTogIlJlZ3Jlc2nDs24gTGluZWFsIC0gUHJlZGljY2nDs24gZGUgUHJlY2lvcyBkZSBDYXNhcyINCmF1dGhvcjogIk1hcsOtYSBGZXJuYW5kYSBTYW4gUm9tw6FuIE9yb3pjbyAtIEEwMTQyNDY5MSINCmRhdGU6ICIyMC8wOC8yMDI2Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IGNvc21vDQotLS0NCg0KIVtdKGh0dHBzOi8vbWVkaWEudGVub3IuY29tL0Nsc0RhTThDN2NZQUFBQU0vZGFuY2luZy1ob3VzZS5naWYpDQoNCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjpibGFjayI+VGVvcsOtYTwvc3Bhbj4NCioqbG0oKSoqIGVzIGxhIGZ1bmNpw7NuIGVuIFIgcGFyYSBhanVzdGFyIG1vZGVsb3MgbGluZWFsZXMuDQpFcyBlbCBtb2RlbG8gZXN0YWTDrXN0aWNvIG3DoXMgYsOhc2ljbyBxdWUgZXhpc3RlIHkgbcOhcyBmw6FjaWwgZGUgaW50ZXJwcmV0YXIuDQpQYXJhIGludGVycHJldGFybG8gc2UgdXNhIGxhIG1lZGlkYSBSLWN1YWRyYWRhLCBxdWUgc2lnbmlmaWNhIHF1w6kgdGFuIGNlcmNhIGVzdMOhbiBsb3MgZGF0b3MgZGUgbGEgcmVncmVzacOzbi4gVmEgZGUgMCBhIDEsIGTDs25kZSAxIGVzIHF1ZSBlbCBtb2RlbG8gZXhwbGljYSB0b2RhIGxhIHZhcmlhYmlsaWRhZC4NCg0KIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmJsYWNrIj5Db250ZXh0bzwvc3Bhbj4NClVuYSBpbm1vYmlsaWFyaWEgY3VlbnRhIGNvbiBlbCByZWdpc3RybyBkZSBwcm9waWVkYWRlcyB2ZW5kaWRhcywgaW5jbHV5ZW5kbyBzdSB1YmljYWNpw7NuLCBjYXJhY3RlcsOtc3RpY2FzIGbDrXNpY2FzIHkgY2F0ZWdvcsOtYSBkZSBsYSBjaXVkYWQuIFNlIGRlc2VhIGdlbmVyYXIgdW4gbW9kZWxvIHByZWRpY3Rpdm8gZGVsIHByZWNpbyBkZSB2ZW50YS4NCg0KIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmJsYWNrIj5JbnN0YWxhciBwYXF1ZXRlcyB5IGxpYnJlcsOtYXM8L3NwYW4+DQpgYGB7cn0NCiMgaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKQ0KbGlicmFyeShjb3JycGxvdCkNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0iY29sb3I6YmxhY2siPkltcG9ydGFyIGxhIGJhc2UgZGUgZGF0b3M8L3NwYW4+DQpgYGB7cn0NCmRmID0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSkNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0iY29sb3I6YmxhY2siPkVudGVuZGVyIGxhIGJhc2UgZGUgZGF0b3M8L3NwYW4+DQpgYGB7cn0NCnN1bW1hcnkoZGYpDQpzdHIoZGYpDQpoZWFkKGRmKQ0KdGFpbChkZikNCmNvcnJlbGFjaW9uZXMgPSBjb3IoZGZbLHNhcHBseShkZiwgaXMubnVtZXJpYyldLCB1c2U9ImNvbXBsZXRlLm9icyIpDQpjb3JycGxvdChjb3JyZWxhY2lvbmVzKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjpibGFjayI+TGltcGlhciBsYSBiYXNlIGRlIGRhdG9zPC9zcGFuPg0KYGBge3J9DQpkZiRDYXJwZXRbaXMubmEoZGYkQ2FycGV0KV0gPSBtZWRpYW4oZGYkQ2FycGV0LCBuYS5ybT1UUlVFKQ0KZGYgPSBkZltkZiRPYnNlcnZhdGlvbiAhPSAzNjEsIF0NCmRmID0gZGZbZGYkUmFpbmZhbGwgPj0gMCwgXQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjpibGFjayI+R2VuZXJhciBlbCBtb2RlbG88L3NwYW4+DQpgYGB7cn0NCnJlZ3Jlc2lvbiA9IGxtKEhvdXNlX1ByaWNlfi4tT2JzZXJ2YXRpb24sIGRhdGE9ZGYpDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0iY29sb3I6YmxhY2siPkFqdXN0YXIgZWwgbW9kZWxvPC9zcGFuPg0KYGBge3J9DQpyZWdyZXNpb24yID0gbG0oSG91c2VfUHJpY2V+UGFya2luZytDaXR5X0NhdGVnb3J5LCBkYXRhPWRmKQ0Kc3VtbWFyeShyZWdyZXNpb24yKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjpibGFjayI+R2VuZXJhciBQcmVkaWNjaW9uZXM8L3NwYW4+DQpgYGB7cn0NCmRhdG9zX251ZXZvcyA9IGRhdGEuZnJhbWUoUGFya2luZz1jKCJDb3ZlcmVkIiwiTm90IFByb3ZpZGVkIiwiT3BlbiIsIk5vIFBhcmtpbmciKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENpdHlfQ2F0ZWdvcnk9YygiQ0FUIEEiLCJDQVQgQiIsIkNBVCBCIiwiQ0FUIEMiKSkNCnByZWRpY3QocmVncmVzaW9uMiwgZGF0b3NfbnVldm9zKQ0KYGBg