A través de un conjunto de datos (TABLON_ENTRENAMIENTO.csv) se debe entrenar un modelo que realice la predicción de la variable TARGET teniendo en cuenta los inputs dados por las variables (VAR1, VAR2, VAR3, VAR4).
Se debe realizar el test del modelo utilizando los datos del fichero TABLON_VALIDACION.csv. Para ello, elija la métrica que mejor se adapte a la naturaleza de los datos. Pista: la variable TARGET es cuantitativa continua.
Este reto se debe resolver en RStudio y presentar los resultados a través de un documento (html o pdf) creado con RMarkdown.
Debe indagar sobre diferentes naturalezas de modelos predictivos y mostrar cuál de ellos es el que mejor resultado arroja para el caso bajo estudio tras realizar la comparación entre las métricas obtenidas.
Cargamos las librerías necesarias:
library(moments)
library(gplots)
library(ggplot2)
library(DescTools)
library(dplyr)
library(corrplot)
library(car)
library(vcd)
library(cluster)
library(ggdendro)
library(factoextra)
library(cli)
library(GGally)
library(rpart)
library(rpart.plot)
library(randomForest)
library(caret)
library(mltools)
library(e1071)
library(ROCR)
library(scales)
library(MLmetrics)train.target <- read.csv("TABLON_ENTRENAMIENTO.csv", header = TRUE, sep = ";")
test.target <- read.csv("TABLON_VALIDACION.csv", header = TRUE, sep = ";")## 'data.frame': 3150 obs. of 5 variables:
## $ TARGET: num 0.128 0.138 0.167 0.277 0.376 ...
## $ VAR1 : int 1 2 3 4 5 6 7 8 9 10 ...
## $ VAR2 : num 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
## $ VAR3 : int 1 1 1 1 1 1 1 1 1 1 ...
## $ VAR4 : int 300 300 300 300 300 300 300 300 300 300 ...
## TARGET VAR1 VAR2 VAR3 VAR4
## Min. :0.1277 Min. : 1.0 Min. : 0.500 Min. :1.000 Min. :300
## 1st Qu.:2.2131 1st Qu.:13.0 1st Qu.: 0.750 1st Qu.:1.000 1st Qu.:300
## Median :3.5503 Median :25.5 Median : 2.500 Median :3.000 Median :400
## Mean :3.0593 Mean :25.5 Mean : 3.893 Mean :3.333 Mean :400
## 3rd Qu.:4.1773 3rd Qu.:38.0 3rd Qu.: 7.500 3rd Qu.:6.000 3rd Qu.:500
## Max. :4.6191 Max. :50.0 Max. :10.000 Max. :6.000 Max. :500
## 'data.frame': 2250 obs. of 5 variables:
## $ TARGET: num 0.153 0.164 0.183 0.291 0.402 ...
## $ VAR1 : int 1 2 3 4 5 6 7 8 9 10 ...
## $ VAR2 : num 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 ...
## $ VAR3 : int 1 1 1 1 1 1 1 1 1 1 ...
## $ VAR4 : int 300 300 300 300 300 300 300 300 300 300 ...
## TARGET VAR1 VAR2 VAR3 VAR4
## Min. :0.1486 Min. : 1.0 Min. :0.80 Min. :1.000 Min. :300
## 1st Qu.:2.3024 1st Qu.:13.0 1st Qu.:2.00 1st Qu.:1.000 1st Qu.:300
## Median :3.7150 Median :25.5 Median :4.00 Median :3.000 Median :400
## Mean :3.1526 Mean :25.5 Mean :4.16 Mean :3.333 Mean :400
## 3rd Qu.:4.2959 3rd Qu.:38.0 3rd Qu.:6.00 3rd Qu.:6.000 3rd Qu.:500
## Max. :4.6055 Max. :50.0 Max. :8.00 Max. :6.000 Max. :500
## [1] 3150
## [1] 2250
Dados los rangos entre los que se encuentran nuestras variables y hacer más eficiente el uso de ciertos modelos de ML pare regresión, es necesario estandarizar la escala de nuestros valores.
#Escalaremos las variables entre [0,1] en nuestro set de entrenamiento y prueba
train.target$VAR1 <- rescale(train.target$VAR1)
train.target$VAR2 <- rescale(train.target$VAR2)
train.target$VAR3 <- rescale(train.target$VAR3)
train.target$VAR4 <- rescale(train.target$VAR4)
train.target$TARGET <- rescale(train.target$TARGET)
test.target$VAR1 <- rescale(test.target$VAR1)
test.target$VAR2 <- rescale(test.target$VAR2)
test.target$VAR3 <- rescale(test.target$VAR3)
test.target$VAR4 <- rescale(test.target$VAR4)
test.target$TARGET <- rescale(test.target$TARGET)Previo al entrenamiento de modelos, revisemos la relación que existe entre las variables predictoras y la variable a predecir.
Se observa una correlación positiva entre la variable TARGET y VAR1, con el resto de variables por los valores que puede tomar es difícil establecer una relación.
Observemos la matriz de covarianzas:
## TARGET VAR1 VAR2 VAR3 VAR4
## TARGET 1.00000000 9.083607e-01 1.281319e-01 -2.437229e-02 -0.03365784
## VAR1 0.90836072 1.000000e+00 2.703670e-20 -6.635590e-21 0.00000000
## VAR2 0.12813185 2.703670e-20 1.000000e+00 2.034745e-19 0.00000000
## VAR3 -0.02437229 -6.635590e-21 2.034745e-19 1.000000e+00 0.00000000
## VAR4 -0.03365784 0.000000e+00 0.000000e+00 0.000000e+00 1.00000000
Dado que los valores en relación a TARGET con las variables VAR2/3/4 son muy cercanos a cero, podemos concluir que no existe una relación entre ellas, indicando independencia entre sí.
Nos enfrentamos con un problema de regresión, para el cual evaluaremos los siguientes 3 modelos:
## [1] 0.000000000 0.002281702 0.008660137 0.033168841 0.055198576
## [1] 0.001074291 0.003502215 0.007688314 0.031891941 0.056934044
set.seed(123)
ctrl <- trainControl(method = "repeatedcv", repeats = 3)
#Ejecutamos en modelo
KNN.model.reg <- train(y= train.target.y, x= train.target.x, method = "knn", trControl = ctrl)## k-Nearest Neighbors
##
## 3150 samples
## 4 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 3 times)
## Summary of sample sizes: 2835, 2834, 2835, 2836, 2835, 2835, ...
## Resampling results across tuning parameters:
##
## k RMSE Rsquared MAE
## 5 0.01965327 0.9962844 0.01428469
## 7 0.02657084 0.9937080 0.01715075
## 9 0.03748034 0.9876412 0.02243624
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was k = 5.
De acuerdo a este resultado 5 es el número óptimo para el parámetro k.
## [1] 0.005364582 0.006682387 0.015655048 0.032337768 0.059865548 0.093799484
## [7] 0.134835053 0.182530708 0.232414775 0.284796995
## [1] 0.9982207
#Ahora probemos sobre test
KNN.model.reg.test <- train(y= test.target.y, x= test.target.x, method = "knn", trControl = ctrl)## k-Nearest Neighbors
##
## 2250 samples
## 4 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 3 times)
## Summary of sample sizes: 2026, 2024, 2026, 2026, 2025, 2024, ...
## Resampling results across tuning parameters:
##
## k RMSE Rsquared MAE
## 5 0.01957159 0.9969145 0.01327093
## 7 0.03051527 0.9935138 0.01840020
## 9 0.04453787 0.9868923 0.02490235
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was k = 5.
De acuerdo a este resultado 5 es el número óptimo para el parámetro k.
## [1] 0.02021816 0.02021816 0.02021816 0.03776706 0.06142574 0.09630958
## [7] 0.13829389 0.18702935 0.24073631 0.29730252
## [1] 0.9990997
El R2 también es bastante alto al aplicar en el set de prueba, con lo cual descartamos estemos teniendo un overfitting.
## [1] 0.01000418
## [1] "Mean of squared errors (MSE): 0.010"
Al ser cercana a 0, resulta ser un buen indicador para el modelo.
Ahora intentemos resolver el problema con un modelo de regresión lineal.
##
## Call:
## lm(formula = TARGET ~ ., data = train.target)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.29211 -0.10991 0.02023 0.10661 0.22270
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.158559 0.006005 26.405 < 2e-16 ***
## VAR1 0.947571 0.007377 128.455 < 2e-16 ***
## VAR2 0.121574 0.005985 20.312 < 2e-16 ***
## VAR3 -0.021884 0.005286 -4.140 3.57e-05 ***
## VAR4 -0.025658 0.005321 -4.822 1.49e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1219 on 3145 degrees of freedom
## Multiple R-squared: 0.8435, Adjusted R-squared: 0.8433
## F-statistic: 4238 on 4 and 3145 DF, p-value: < 2.2e-16
#hagamos la predicción sobre el set de prueba
predict.test.lm <- predict(model, test.target)
head(predict.test.lm,n=10)## 1 2 3 4 5 6 7 8
## 0.1585594 0.1778976 0.1972358 0.2165739 0.2359121 0.2552503 0.2745885 0.2939266
## 9 10
## 0.3132648 0.3326030
## [1] 0.8423778
El R2 también es bastante alto al aplicar en el set de prueba, con lo cual descartamos estemos teniendo un overfitting.
## [1] 0.125488
## [1] "Mean of squared errors (MSE): 0.125"
La métrica al ser cercana a cero es buena.
No obstante, es necesario validemos los supuestos para este modelo.
El R2 resulta bueno, sin embargo, es necesario validemos si cumple los supuestos para este modelo.
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: residuos
## D = 0.094072, p-value < 2.2e-16
## alternative hypothesis: two-sided
##
## Shapiro-Wilk normality test
##
## data: residuos
## W = 0.95004, p-value < 2.2e-16
H0: la variable se distribuya como una normal
H1: la variable no se distribuya como una normal
El p-value corresponde a 2.2e-16 el cual es menor a .05, por lo tanto, se rechaza H0, es decir, los residuos NO se distribuyen como una normal
Gráficamente también se observa que los residuos no siguen una distribución, con lo cual, el primer supuesto no se cumple.
##
## Bartlett test of homogeneity of variances
##
## data: train.target
## Bartlett's K-squared = 591.33, df = 4, p-value < 2.2e-16
H0: varianza(i)=varianza(j)=cte H1: son diferentes, no es constante
El p-value corresponde a 2.2e-16 el cual es menor a .05, por lo tanto, se rechaza H0, es decir, la varianza NO es constante, con lo cual tampoco se cumple este supuesto.
Hasta este punto ya podríamos decir que pese a que el modelo arroja una R2 significativa, no resulta ser un buen modelo predictor.
Finalmente entrenemos el modelo a través de un Randon Forest.
##
## Call:
## randomForest(x = train.target, y = train.target$TARGET, importance = TRUE)
## Type of random forest: regression
## Number of trees: 500
## No. of variables tried at each split: 1
##
## Mean of squared residuals: 0.003168046
## % Var explained: 96.66
Lo que nos dice la gráfica es que a partir de cerca de ntrees= 70 el modelo ya no muestra una mejoría significativa.
El porentaje de variabilidad que explica es 96.66, la cual es buena, solo faltaría validar que no se trata de overffiting. Para ello predecimos sobre el set de prueba y calculamos R2 y MSE.
## 1 2 3 4 5 6 7 8
## 0.1383424 0.1384214 0.1392956 0.1449234 0.1562603 0.1779716 0.2011958 0.2220415
## 9 10
## 0.3057056 0.3379231
## [1] 0.9896118
El R2 obtenido también es alto con lo cual podemos decir que no existe overfitting y resulta ser un buen método predictor.
## [1] 0.05877679
## [1] "Mean of squared errors (MSE): 0.059"
Comparemos las métricas obtenidas
| Modelo / Métrica | MSE | R2 |
|---|---|---|
| Regresión Lineal | 0.125 | 0.8435 |
| Random Forest | 0.057 | 0.9896118 |
| KNN | 0.010 | 0.9990997 |
De acuerdo a las métricas obtenidos podemos decir que tanto KNN como Random Forest resultan ser buenos modelos predictores, sin embargo, KNN resulta ser el mejor modelo.
Para este problema la Regresión Lineal NO resulta ser viable dado que no cumple los supuestos que requiere el modelo.