#cargado librerias
library(dplyr)
library(caret)
Descripcion: Este conjunto de datos contiene 10,692 propiedades para alquilar en cinco ciudades de brazil con 13 características diferentes
city: Ciudad donde se encuentra la propiedad
area: Área de la propiedad
rooms: Cantidad de habitaciones
bathroom: Cantidad de baños
parking spaces: Cantidad de plazas de estacionamiento
floor: Piso
animal: si acepta animales o no
furniture: amoblado o no
hoa: impuesto de la comunidad de propietarios
rent amount: monto del alquiler
property tax: impuesto predial municipal
fire insurance: valor del seguro de incendio
total: la suma de todos los valores
Target: rent amount
Contexto del problema:
Predicir el precio de alquiler de una vivienda en 05 ciudades de Brazil en base al area de la propiedad.
Las variables a ser utilizadas:
area: variable predictora
rent amount: variable respuesta
Fuente de datos en: https://www.kaggle.com/datasets/rubenssjr/brasilian-houses-to-rent.
#cargando los datos
df_HouseTR= read.csv('houses_to_rent_v2.csv',check.names=FALSE)
head(df_HouseTR,5)
#dimensiones del dataset
print(dim(df_HouseTR))
## [1] 10692 13
#renombrando nombre de las variables
df_HouseTR <- df_HouseTR %>%
rename(
'parkingspaces'='parking spaces',
'hoa' = 'hoa (R$)',
'rentamount' ='rent amount (R$)',
'propertytax'='property tax (R$)',
'fireinsurance'='fire insurance (R$)',
'total'='total (R$)')
#revisando los tipos de variables
str(df_HouseTR)
## 'data.frame': 10692 obs. of 13 variables:
## $ city : chr "São Paulo" "São Paulo" "Porto Alegre" "Porto Alegre" ...
## $ area : int 70 320 80 51 25 376 72 213 152 35 ...
## $ rooms : int 2 4 1 2 1 3 2 4 2 1 ...
## $ bathroom : int 1 4 1 1 1 3 1 4 2 1 ...
## $ parkingspaces: int 1 0 1 0 0 7 0 4 1 0 ...
## $ floor : chr "7" "20" "6" "2" ...
## $ animal : chr "acept" "acept" "acept" "acept" ...
## $ furniture : chr "furnished" "not furnished" "not furnished" "not furnished" ...
## $ hoa : int 2065 1200 1000 270 0 0 740 2254 1000 590 ...
## $ rentamount : int 3300 4960 2800 1112 800 8000 1900 3223 15000 2300 ...
## $ propertytax : int 211 1750 0 22 25 834 85 1735 250 35 ...
## $ fireinsurance: int 42 63 41 17 11 121 25 41 191 30 ...
## $ total : int 5618 7973 3841 1421 836 8955 2750 7253 16440 2955 ...
#creado dataframe con las variables en estudio
df_Htor=select(df_HouseTR,area, rentamount)
#Analizando grafico de dispersión
plot(sqrt(df_Htor$area),sqrt(df_Htor$rentamount))
#analisando outliers
par(mfrow=c(1,2))
boxplot(df_Htor$area, main='area')
boxplot(df_Htor$rentamount, main='rentamount')
#describe: area y rentamount
summary(df_Htor)
## area rentamount
## Min. : 11.0 Min. : 450
## 1st Qu.: 56.0 1st Qu.: 1530
## Median : 90.0 Median : 2661
## Mean : 149.2 Mean : 3896
## 3rd Qu.: 182.0 3rd Qu.: 5000
## Max. :46335.0 Max. :45000
#analizando valore ourlier por percentiles: variable area
quantile(df_Htor$area, seq(.75,1,.01))
## 75% 76% 77% 78% 79% 80% 81% 82%
## 182.00 190.00 200.00 200.00 208.00 215.00 220.00 230.00
## 83% 84% 85% 86% 87% 88% 89% 90%
## 240.00 250.00 250.00 263.26 276.00 288.08 300.00 300.00
## 91% 92% 93% 94% 95% 96% 97% 98%
## 320.00 340.00 353.00 380.00 400.00 429.36 472.54 530.00
## 99% 100%
## 650.09 46335.00
#valor maximo admitido (percentil 99) - se perdera el 1% de los datos
area_max=650.09
df_Htor=df_Htor[df_Htor$area<=area_max,]
#Boxplot: analisando outliers
par(mfrow=c(1,2))
boxplot(df_Htor$area, main='area')
boxplot(df_Htor$rentamount, main='rentamount')
#Realizando conversion de las variables aplicando logaritmo
df_Htor$area=log(df_Htor$area)
df_Htor$rentamount=log(df_Htor$rentamount)
#Boxplot:
par(mfrow=c(1,2))
boxplot(df_Htor$area, main='area')
boxplot(df_Htor$rentamount, main='rentamount')
#Analizando grafico de dispersión nuevamente
plot(df_Htor$area,df_Htor$rentamount)
cor(df_Htor$area, df_Htor$rentamount, method = "pearson")
## [1] 0.7214561
cor(df_Htor$area, df_Htor$rentamount, method = "spearman")
## [1] 0.7224891
ml_rent <- lm(rentamount ~ area, data = df_Htor)
summary(ml_rent)
##
## Call:
## lm(formula = rentamount ~ area, data = df_Htor)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.9579 -0.3992 -0.0260 0.3657 2.3071
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.589232 0.031665 144.9 <2e-16 ***
## area 0.727847 0.006791 107.2 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5412 on 10583 degrees of freedom
## Multiple R-squared: 0.5205, Adjusted R-squared: 0.5205
## F-statistic: 1.149e+04 on 1 and 10583 DF, p-value: < 2.2e-16
plot(df_Htor$area,df_Htor$rentamount)
abline(ml_rent, col="red", lwd=2)
par(mfrow = c(2, 2))
plot(ml_rent)
Residual vs Fitted (linealidad)
Normal Q-Q (normalidad)
Scale - Location (homocedasticidad)
Residual vs Leverage (datos alejados)
RNGkind(sample.kind = "Rejection")
set.seed(7345)
ind.train <- createDataPartition(y = df_Htor$rentamount, p = 0.70, list = FALSE)
data.train <- df_Htor[ind.train, ]
data.test <- df_Htor[-ind.train, ]
ctrl <- trainControl(method = 'none')
ml_rent2 <- train(rentamount ~ area, data = data.train, method = 'lm',
trControl = ctrl)
ml_rent2
## Linear Regression
##
## 7411 samples
## 1 predictor
##
## No pre-processing
## Resampling: None
ml_rent2.pred <- predict(ml_rent2, newdata = data.test)
postResample(ml_rent2.pred, data.test$rentamount)
## RMSE Rsquared MAE
## 0.5372819 0.5243059 0.4357497
Existen tres tipos de gradiente descendiente:
Batch Gradient Descent
En Batch Gradient Descent, todos los datos de entrenamiento se tienen en cuenta para dar un solo paso. Tomamos el promedio de las gradientes de todos los ejemplos de entrenamiento y luego usamos esa gradiente media para actualizar nuestros parámetros. Eso es solo un paso de descenso de gradiente en una época.
Batch Gradient Descent es ideal para variedades de error convexas o relativamente suaves. En este caso, nos movemos algo directamente hacia una solución óptima.
El gráfico de costo frente a épocas también es bastante suave porque estamos promediando todos los gradientes de datos de entrenamiento para un solo paso. El costo sigue disminuyendo a lo largo de las épocas.
Mini-batch Gradient Descent
calcula el gradiente a partir de un pequeño subconjunto aleatorio de muestras llamadas mini-batches y no a partir de todo el conjunto de entrenamiento ni a partir de una única muestra. Normalmente, este algoritmo tarda menos en alcanzar el mínimo que Batch Gradient Descent pero corre el riesgo de caer en un mínimo local y no ser capaz de salir de él. El valor n suele denominarse batch size.
Por lo tanto, cuando usamos el descenso de gradiente de mini lotes, actualizamos nuestros parámetros con frecuencia y podemos usar la implementación vectorizada para cálculos más rápidos.
gradientDesc <- function(x, y, learn_rate, conv_threshold, n, max_iter) {
plot(x, y, col = "blue", pch = 20)
m <- runif(1, 0, 1)
c <- runif(1, 0, 1)
yhat <- m * x + c
MSE <- sum((y - yhat) ^ 2) / n
converged = F
iterations = 0
while(converged == F) {
## Implement the gradient descent algorithm
m_new <- m - learn_rate * ((1 / n) * (sum((yhat - y) * x)))
c_new <- c - learn_rate * ((1 / n) * (sum(yhat - y)))
m <- m_new
c <- c_new
yhat <- m * x + c
MSE_new <- sum((y - yhat) ^ 2) / n
if(MSE - MSE_new <= conv_threshold) {
abline(c, m)
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
iterations = iterations + 1
if(iterations > max_iter) {
abline(c, m)
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
}
}
gradientDesc(df_Htor$area, df_Htor$rentamount, 0.0000293, 0.001, 32, 100000)
## [1] "Optimal intercept: 4.58923244569354 Optimal slope: 0.727847232666991"