Esta técnica estadÃstica permite evaluar la relación entre una variable dependiente (numérica) y más de una variable predictora (tambien numérica). de modo que evalúa además el efecto de cada predictor en presencia del resto.
Para más información general de regresión vea https://rpubs.com/paraneda/regresion
La ecuaciónde regresión lineal múltiple se deriva de la regresión simple:
\[y = (\beta_{0} + \beta_{1} x_{1i} + \beta_{2} x_{2i} + \beta_{3} x_{3i} + ...+\beta_{n} x_{ni}) + \epsilon_{i}\]
# librerias a cargar
library(mlbench) # dataset destinados a pruebas de machine learning
library(tidyverse)#
library(corrplot) #
library(plotly) #
library(caret) # creación de entrenamiento de clasificación y regresión
library(caTools) #
library(reshape2) #
Para determinar que tan bien se ajusta el modelo se utiliza \(R^2\) y el Error estándar residual (RSE)
Registros del valor de una casa en los suburbios de Boston (USA) en base a diversas variables. Contiene 506 filas y 14 variables.
Fuente: https://www.kaggle.com/c/boston-housing
# carga de data
data(BostonHousing)
<- BostonHousing
boston str(boston) # mostrar la estructura de los datos.
## 'data.frame': 506 obs. of 14 variables:
## $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ...
## $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
## $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
## $ chas : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
## $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
## $ rm : num 6.58 6.42 7.18 7 7.15 ...
## $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
## $ dis : num 4.09 4.97 4.97 6.06 6.06 ...
## $ rad : num 1 2 2 3 3 3 5 5 5 5 ...
## $ tax : num 296 242 242 222 222 222 311 311 311 311 ...
## $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
## $ b : num 397 397 393 395 397 ...
## $ lstat : num 4.98 9.14 4.03 2.94 5.33 ...
## $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
Parametros:
#nombre de las variables
names(boston)
## [1] "crim" "zn" "indus" "chas" "nox" "rm" "age"
## [8] "dis" "rad" "tax" "ptratio" "b" "lstat" "medv"
# temas pendientes...
# exploración de datos
# limpieza de datos
La librerÃa corrplot perite una visualización gráfica de la relación entre variables
# descartamos la variable chas por no ser numérica.
corrplot(round(cor(subset(boston, select = -chas)), digits = 3), type = "lower")
### Matriz de correlación
# se descartó variable "chas" por no ser numérica
round(cor(select(boston, -chas)), 3)
## crim zn indus nox rm age dis rad tax ptratio
## crim 1.000 -0.200 0.407 0.421 -0.219 0.353 -0.380 0.626 0.583 0.290
## zn -0.200 1.000 -0.534 -0.517 0.312 -0.570 0.664 -0.312 -0.315 -0.392
## indus 0.407 -0.534 1.000 0.764 -0.392 0.645 -0.708 0.595 0.721 0.383
## nox 0.421 -0.517 0.764 1.000 -0.302 0.731 -0.769 0.611 0.668 0.189
## rm -0.219 0.312 -0.392 -0.302 1.000 -0.240 0.205 -0.210 -0.292 -0.356
## age 0.353 -0.570 0.645 0.731 -0.240 1.000 -0.748 0.456 0.506 0.262
## dis -0.380 0.664 -0.708 -0.769 0.205 -0.748 1.000 -0.495 -0.534 -0.232
## rad 0.626 -0.312 0.595 0.611 -0.210 0.456 -0.495 1.000 0.910 0.465
## tax 0.583 -0.315 0.721 0.668 -0.292 0.506 -0.534 0.910 1.000 0.461
## ptratio 0.290 -0.392 0.383 0.189 -0.356 0.262 -0.232 0.465 0.461 1.000
## b -0.385 0.176 -0.357 -0.380 0.128 -0.274 0.292 -0.444 -0.442 -0.177
## lstat 0.456 -0.413 0.604 0.591 -0.614 0.602 -0.497 0.489 0.544 0.374
## medv -0.388 0.360 -0.484 -0.427 0.695 -0.377 0.250 -0.382 -0.469 -0.508
## b lstat medv
## crim -0.385 0.456 -0.388
## zn 0.176 -0.413 0.360
## indus -0.357 0.604 -0.484
## nox -0.380 0.591 -0.427
## rm 0.128 -0.614 0.695
## age -0.274 0.602 -0.377
## dis 0.292 -0.497 0.250
## rad -0.444 0.489 -0.382
## tax -0.442 0.544 -0.469
## ptratio -0.177 0.374 -0.508
## b 1.000 -0.366 0.333
## lstat -0.366 1.000 -0.738
## medv 0.333 -0.738 1.000
# determinación de modelo con más variables aplicadas
<- lm(medv ~ rm + zn + dis +b, data = boston)
modelo summary(modelo)
##
## Call:
## lm(formula = medv ~ rm + zn + dis + b, data = boston)
##
## Residuals:
## Min 1Q Median 3Q Max
## -20.768 -2.877 -0.264 2.407 37.908
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -37.446075 2.707528 -13.830 < 2e-16 ***
## rm 8.194770 0.409907 19.992 < 2e-16 ***
## zn 0.062711 0.016134 3.887 0.000115 ***
## dis -0.238285 0.178453 -1.335 0.182391
## b 0.024306 0.003134 7.755 4.98e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.129 on 501 degrees of freedom
## Multiple R-squared: 0.5595, Adjusted R-squared: 0.5559
## F-statistic: 159.1 on 4 and 501 DF, p-value: < 2.2e-16
<- lm(medv ~ rm + zn + dis +b + crim + indus + nox, data = boston)
modelo2 summary(modelo2)
##
## Call:
## lm(formula = medv ~ rm + zn + dis + b + crim + indus + nox, data = boston)
##
## Residuals:
## Min 1Q Median 3Q Max
## -16.188 -3.223 -0.534 2.155 36.389
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -10.165095 4.311853 -2.357 0.018785 *
## rm 7.015433 0.408120 17.190 < 2e-16 ***
## zn 0.071032 0.015150 4.688 3.56e-06 ***
## dis -1.497164 0.227595 -6.578 1.21e-10 ***
## b 0.014106 0.003135 4.499 8.52e-06 ***
## crim -0.177686 0.034430 -5.161 3.56e-07 ***
## indus -0.205569 0.063313 -3.247 0.001245 **
## nox -15.533971 4.010253 -3.874 0.000122 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5.702 on 498 degrees of freedom
## Multiple R-squared: 0.621, Adjusted R-squared: 0.6156
## F-statistic: 116.5 on 7 and 498 DF, p-value: < 2.2e-16
# Cómo se distribuye la variable medv
ggplotly(boston %>%
ggplot(aes(medv)) +
stat_density() +
theme_bw())
Establecer una partición de los datos de manera de utilizar una parte para entrenar el valor de predicción y el resto para testear el modelo.
# establecer una semilla
set.seed(123) # para generar num aleatorios , dos decimales seteo dos decimales .. ->ajustar datos
#Seccionar los datos , `split ()` asigna un booleano a una nueva columna basada en el SplitRatio especificado.
<- sample.split(boston, SplitRatio =0.8)
split
<- subset(boston,split==TRUE)#extrae secciones de db housing
train <- subset(boston,split==FALSE)
test
#modelo
<- lm(medv ~ -1 + rm + zn + dis + b, data = train) #especifico data para no usar $
model summary(model)
##
## Call:
## lm(formula = medv ~ -1 + rm + zn + dis + b, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -16.2262 -4.7026 -0.7294 2.1897 28.8332
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## rm 3.060724 0.228885 13.372 < 2e-16 ***
## zn 0.128693 0.020315 6.335 6.49e-10 ***
## dis -0.440750 0.228170 -1.932 0.05412 .
## b 0.010587 0.004022 2.632 0.00882 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.047 on 394 degrees of freedom
## Multiple R-squared: 0.9159, Adjusted R-squared: 0.915
## F-statistic: 1073 on 4 and 394 DF, p-value: < 2.2e-16
Un valor R-squared: 0.9159 indica una alta relación del modelo de regresión.
<- residuals(model)
res # Convertir residuos en un DataFrame
#
<- as.data.frame(res)
res #un modelo es aceptable si las var son significativas
#r^2 ajustado >=0.5
#residuos se ajusta distr normal media=0,varianza=1...-> N)(0,1)
#residuos no corelacionados (No siguen 1 patró, deben estar dispersos)
ggplot(res,aes(res)) + geom_histogram(fill='blue',alpha=0.5)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Modelo prediccionando datos de prueba.
$predicted.medv <- predict(model,test)
test
<-test %>%
pl1 ggplot(aes(medv,predicted.medv)) +
geom_point(alpha=0.7) +
geom_smooth(aes(colour='black')) +
xlab('Actual value of medv') +
ylab('Predicted value of medv')+
theme_bw()
ggplotly(pl1)
Para analizar la confiabilidad de un modelo de regresión, además de la determinación del error medio (RMSE) también se realiza un análisis de residuos.
<- test$medv - test$predicted.medv
error <- sqrt(mean(error)^2)
rmse rmse
## [1] 0.1491127
Supuesto 1: Los errores deben seguir una distribución normal
<- rstandard(model) # residuos estándares del modelo ajustado (completo)
residuos par(mfrow = c(1,3)) # divide la ventana en una fila y tres columnas
hist(residuos) # histograma de los residuos estandarizados
boxplot(residuos) # diagrama de cajas de los residuos estandarizados
qqnorm(residuos) # gráfico de cuantiles de los residuos estandarizados
qqline(residuos)
Supuesto 2: La varianza de los errores es constante
plot(fitted.values(model), rstandard(model), xlab="Valores ajustados", ylab="Residuos estandarizados") # gráfico 2D de los valores ajustados vs. los residuos estandarizados
abline(h=0) # dibuja la recta en cero