Seleccionar una de las dos opciones de bases de datos i) automobile_insurance_claims o ii) health_insurance. A partir de dicha selección realizar las instrucciones 1 – 5. En el desarrollo del archivo de R-Markdown, por favor incluir data storytelling de los resultados del análisis exploratorio de los datos (EDA) así como la interpretación de los resultados estimados.
datos <- read.csv("/Users/lishdz/Desktop/6to/R/Módulo 3/health_insurance.csv")
library(DataExplorer)
library(corrplot)
## corrplot 0.92 loaded
library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
library(car) #vif
## Loading required package: carData
library(lmtest) #bptest
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(dlookr) #plot_normality
## Registered S3 methods overwritten by 'dlookr':
## method from
## plot.transform scales
## print.transform scales
##
## Attaching package: 'dlookr'
## The following object is masked from 'package:base':
##
## transform
library(spatialreg) #SAR
## Loading required package: spData
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
## Loading required package: Matrix
## Loading required package: sf
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(sp)
library(spdep) #moran test
##
## Attaching package: 'spdep'
## The following objects are masked from 'package:spatialreg':
##
## get.ClusterOption, get.coresOption, get.mcOption,
## get.VerboseOption, get.ZeroPolicyOption, set.ClusterOption,
## set.coresOption, set.mcOption, set.VerboseOption,
## set.ZeroPolicyOption
library(xgboost)
library(Metrics) #rmse() function for xgboost
##
## Attaching package: 'Metrics'
## The following objects are masked from 'package:caret':
##
## precision, recall
library(rpart)
library(rpart.plot)
library(e1071)
##
## Attaching package: 'e1071'
## The following objects are masked from 'package:dlookr':
##
## kurtosis, skewness
library(randomForest)
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:ggplot2':
##
## margin
library(neuralnet)
library(MASS)
i) ¿Qué es Supervised Machine Learning y cuáles son algunas
de sus aplicaciones en Inteligencia de Negocios?
Es la rama de la inteligencia artificial que utiliza datas previamente
etiquetada para posteriormente poder hacer predicciones basada en el
aprendizaje que haya hecho. La meta es entrenar modelos con los datos
etiquetados y que después sean capazes de clasificar (o predecir)
correctamente datos nunca antes vistos. En el ámbito de negocios se
puede utilizar para predecir el comportamiento de clientes, por ejemplo
predecir si serán buenos candidatos para recibir un crédito o predecir
el precio de casas.
iii) ¿Qué es la R2 Ajustada? ¿Qué es la métrica RMSE? ¿Cuál
es la diferencia entre la R2 Ajustada y la métrica RMSE?
La R2 Ajustada sirve para explicar el % de variación en la variable
dependiente que es causada por las variables independientes usadas en el
modelo. La métrica RMSE — En general muestra la diferencia promedio
entre los datos reales y los valores predichos por un modelo. Por lo
tanto, entre más pequeño, mejores son las predicciones hechas por el
modelo. Entonces, la diferencia es que ambas métricas es su propósito.
El Adj R2 te dice qué tanto de la variable independiente te explica el
modelo, y el RMSE qué tan confiable es esa explicación.
a. Identificación de NA’s
nas <- colSums(is.na(datos))
nas
## age sex bmi children smoker region expenses
## 0 0 0 0 0 0 0
b. Reemplazo de NA’s
No hay NAs – por lo tanto no se hace tratamiento.
c. Medidas descriptivas
datos$sex <- as.factor(datos$sex)
datos$smoker <- as.factor(datos$smoker)
datos$region <- as.factor(datos$region)
summary(datos)
## age sex bmi children smoker
## Min. :18.00 female:662 Min. :16.00 Min. :0.000 no :1064
## 1st Qu.:27.00 male :676 1st Qu.:26.30 1st Qu.:0.000 yes: 274
## Median :39.00 Median :30.40 Median :1.000
## Mean :39.21 Mean :30.67 Mean :1.095
## 3rd Qu.:51.00 3rd Qu.:34.70 3rd Qu.:2.000
## Max. :64.00 Max. :53.10 Max. :5.000
## region expenses
## northeast:324 Min. : 1122
## northwest:325 1st Qu.: 4740
## southeast:364 Median : 9382
## southwest:325 Mean :13270
## 3rd Qu.:16640
## Max. :63770
plot(datos$age, datos$expenses, main = "Expenses by age", xlab = "age", ylab = "expenses", col = "orange", pch = 16)
Parece haber tres grupos de expenses. La edad aparente tener poca influencia en expenses ya que, para los tres aparentes grupos de expenses hay de todas las edades en todos los rangos. Aunque conforme va aumentando la edad, el mínimo de expenses va aumantando.
plot(datos$region, datos$expenses, main = "Expenses por Region", xlab = "region", ylab = "expenses", col = "orange", pch = 16)
La región no paraece tener mucha influencia. La mediana de expenses para todas las regiones son cercanas, southeast muestra el mayor rango de costo.
b. Medidas de dispersión
plot_histogram(datos)
## Eliminar outliers
mean <- mean(datos$expenses)
sd <- sd(datos$expenses)
z_scores <- (datos$expenses - mean) / sd
threshold <- 3
outliers_index <- which(abs(z_scores) > threshold)
datos <- datos[-outliers_index, ]
plot_histogram(datos$expenses)
plot_correlation(datos)
La mátriz de correlación muestra indicios de que la variable que más influye a expenses (variable dependiente) es si fuman o no.
plot_boxplot(datos, by = "smoker")
Al analizar por smoker, la unica diferencia significativa en cuanto a dispersión es en expenses. La mediana de expense de un no fumador es alrededor de 10,000 y sube hasta 30,000 cuando son fumadores.
plot_boxplot(datos, by = "expenses")
plot_normality(datos, age, sex, bmi, children, smoker, region, expenses)
BMI tiene distribución normal.
plot_histogram(datos$expenses)
A partir de los resultados de EDA describir la especificación del modelo de regresión lineal a estimar. Brevemente, describir cómo es el posible impacto de cada una de las variables explicativas sobre la principal variable de estudio.
En al EDA, infiero que la variable más influyente será SMOKER. Porque tiene una fuerte correlación con expenses. Age en menor medida pero también.
#Crear la partición de datos
set.seed(123)
partition <- createDataPartition(y = datos$expenses, p=0.7, list=F)
train = datos[partition, ]
test = datos[-partition, ]
#Crear el modelo
set.seed(123)
ols_model <- lm(expenses ~ age + sex + bmi + children + smoker + region, data = train)
#Calcular el RMSE del modelo
RMSE_ols_model_train <- sqrt(mean(ols_model$residuals^2))
RMSE_ols_model_train #5755.15
## [1] 5755.16
summary(ols_model)
##
## Call:
## lm(formula = expenses ~ age + sex + bmi + children + smoker +
## region, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -10328.7 -2679.0 -962.7 1178.0 23722.4
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -11212.38 1108.30 -10.117 <2e-16 ***
## age 246.42 13.62 18.090 <2e-16 ***
## sexmale -68.04 380.67 -0.179 0.8582
## bmi 320.72 32.07 10.002 <2e-16 ***
## children 495.44 156.48 3.166 0.0016 **
## smokeryes 22869.14 470.05 48.653 <2e-16 ***
## regionnorthwest -69.93 554.54 -0.126 0.8997
## regionsoutheast -783.25 553.30 -1.416 0.1572
## regionsouthwest -1090.41 553.92 -1.969 0.0493 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5783 on 926 degrees of freedom
## Multiple R-squared: 0.7579, Adjusted R-squared: 0.7558
## F-statistic: 362.3 on 8 and 926 DF, p-value: < 2.2e-16
Primero, entrené el modelo de OLS usando el subset de train. Según el output, el modelo tiene un p-value muy bajo, lo que indica que el modelo si es estadisticamente significativo. También tiene un Adj. R2 bastante alta. De acuerdo al modelo, las variables más influyentes son la edad, el BMI y si son fumadores. Este modelo muestra un error de 5755.16 en la base de train.
Test
#Crear predicciones
predicciones_ols_model <- predict(ols_model, newdata = test)
summary(predicciones_ols_model)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -1655 6296 9485 12560 14458 39434
#Pasar las predicciones para poder utilizarla en calculos
predictions_df <- data.frame(fitted_values = predicciones_ols_model)
#Calcular el RMSE con los fitted values (predicciones) y los actual values (de la base de test)
RMSE_ols_model <-sqrt(mean((predictions_df$fitted_values-test$expenses)^2))
RMSE_ols_model
## [1] 5976.548
#RMSE = 5976.548
Después, para comprobar la precisón del modelo en datos no vistos, hice una prueba con el subset de test. Utilizando las predicciones que se crearon con el modelo, el RMSE aumentó. Lo que quiere decir que el modelo es peor para predecir datos no antes visto.
#Crear el modelo -- solo en LOG las variables relevantes
set.seed(123)
log_ols_model <- lm(log(expenses) ~ log(age) + sex + log(bmi) + children + smoker + region, data = train)
summary(log_ols_model)
##
## Call:
## lm(formula = log(expenses) ~ log(age) + sex + log(bmi) + children +
## smoker + region, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.79387 -0.20917 -0.06750 0.07304 2.25338
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.91530 0.25987 11.218 < 2e-16 ***
## log(age) 1.25811 0.03683 34.158 < 2e-16 ***
## sexmale -0.08966 0.02850 -3.147 0.00170 **
## log(bmi) 0.40088 0.07189 5.576 3.22e-08 ***
## children 0.08237 0.01174 7.014 4.45e-12 ***
## smokeryes 1.49941 0.03520 42.602 < 2e-16 ***
## regionnorthwest -0.04865 0.04150 -1.172 0.24145
## regionsoutheast -0.12897 0.04137 -3.117 0.00188 **
## regionsouthwest -0.12714 0.04149 -3.064 0.00224 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4329 on 926 degrees of freedom
## Multiple R-squared: 0.7786, Adjusted R-squared: 0.7767
## F-statistic: 407 on 8 and 926 DF, p-value: < 2.2e-16
De inicio, con los LOG practicamente todas las variables se vuelven influyentes al modelo. Pero edad y si son fumadores son las variables más signigicantes (tienen el p-value más chico). El Adj R2 aumenta 0.02 vs OLS original.
#Transformar los valores predichos a su magnitud original para poder compararlos con los valores reales
log_ols_model$fitted.values <- exp(log_ols_model$fitted.values)
#Calcular el RMSE del modelo de LOG
RMSE_log_ols_model_train <-sqrt(mean((log_ols_model$fitted.values-train$expenses)^2))
RMSE_log_ols_model_train
## [1] 7428.375
#RMSE Train = 7428.375
Test
#Crear predicciones
predicciones_log_ols_model <- predict(log_ols_model, newdata = test)
summary(predicciones_log_ols_model)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 7.610 8.552 9.048 9.045 9.370 11.055
#Pasar las predicciones para poder utilizarla en calculos
predictions_df_log <- data.frame(fitted_values = exp(predicciones_log_ols_model))
#Calcular el RMSE con los fitted values (predicciones) y los actual values (de la base de test)
RMSE_log_ols_model <-sqrt(mean((predictions_df_log$fitted_values-test$expenses)^2))
RMSE_log_ols_model
## [1] 7539.91
Al probar el modelo de LOG OLS para predecir se puede ver que mejoro un poco su precisión con datos no vistos antes. Sin embargo, sigue teniendo un RMSE más alto que el modelo de OLS sin transformación logaritmica.
vif(ols_model)
## GVIF Df GVIF^(1/(2*Df))
## age 1.022151 1 1.011015
## sex 1.012787 1 1.006373
## bmi 1.107041 1 1.052160
## children 1.004820 1 1.002407
## smoker 1.011864 1 1.005914
## region 1.094123 3 1.015105
No hay multicolinealidad – dado que ninguna variable tiene un valor de vif mayor a 5.
bptest(ols_model)
##
## studentized Breusch-Pagan test
##
## data: ols_model
## BP = 89.623, df = 8, p-value = 5.547e-16
Debido a que el valor p es considerablemente menor a 0.05, se rechaza
la hipótesis nula de homocedasticidad. Esto indica que existen
heterocedasticidad en los residuos del modelo.
Debido a la presencia de heterocedasticidad se modeló un modelo de
WLS.
Train
residuals <- residuals(ols_model)
rmse_ols_wls <- sqrt(mean(residuals^2))
set.seed(123)
weights <- 1 / (abs(residuals) + rmse_ols_wls)
wls_model <- lm(expenses ~ age + sex + bmi + children + smoker + region, data = train, weights = weights)
summary(wls_model)
##
## Call:
## lm(formula = expenses ~ age + sex + bmi + children + smoker +
## region, data = train, weights = weights)
##
## Weighted Residuals:
## Min 1Q Median 3Q Max
## -90.302 -18.860 -5.726 14.527 142.262
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -9287.596 826.814 -11.233 < 2e-16 ***
## age 251.048 9.879 25.411 < 2e-16 ***
## sexmale -125.544 277.388 -0.453 0.6509
## bmi 233.156 24.973 9.336 < 2e-16 ***
## children 486.635 113.556 4.285 2.01e-05 ***
## smokeryes 23549.271 416.716 56.512 < 2e-16 ***
## regionnorthwest -208.297 401.706 -0.519 0.6042
## regionsoutheast -742.206 408.612 -1.816 0.0696 .
## regionsouthwest -937.453 399.706 -2.345 0.0192 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 45.57 on 926 degrees of freedom
## Multiple R-squared: 0.8163, Adjusted R-squared: 0.8147
## F-statistic: 514.4 on 8 and 926 DF, p-value: < 2.2e-16
Test
set.seed(123)
wls_predict <- predict(wls_model, newdata = test)
RMSE_wls_model <-sqrt(mean((wls_predict-test$expenses)^2))
RMSE_wls_model
## [1] 6031.981
bptest(wls_model)
##
## studentized Breusch-Pagan test
##
## data: wls_model
## BP = 0.014444, df = 8, p-value = 1
Utilizando el método de WLS, dandole un peso proporcional al error que tiene cada observación se logra eliminar la tendencia de heterocedasticidad.
Al no tener un componente de tiempo o espacio (concreto) en los datos, no hay riesgo de autocorrelación serial o espacial
hist(wls_model$residuals, main = "Histogram of Residuals", xlab = "Residuals")
plot(ols_model$residuals, xlab= "Dependent Variable", ylab = "Residuals", main = 'OLS Regression Residuals')
abline(0,0)
Los modelos de SAR (Spatial Autoregressive Model) consideran tanto el comportamiento histórico de una variable como el comportamiento de esa variable en ubicaciones vecinas para realizar predicciones. Sin embargo, con esta base de datos no se tiene suficiente información geografica para hacer un modelo de SAR.
data_xgb <- datos %>% dplyr::select(expenses, age, sex, bmi, children, smoker, region)
data_xgb$sex <- ifelse(data_xgb$sex == "female", 1, 0)
# female = 1
# male = 0
data_xgb$smoker <- ifelse(data_xgb$smoker == "yes", 1, 0)
# smoker = 1
# no smoker = 0
data_xgb$region <- as.integer(factor(data_xgb$region, levels = c("northwest", "southeast", "southwest", "northeast"))) - 1
#northwest = 0
#southeast = 1
#soutwest = 2
#northeast = 3
data_xgb$age <- log(data_xgb$age)
data_xgb$bmi <- log(data_xgb$bmi)
set.seed(123)
cv_data <- createDataPartition(y = data_xgb$expenses, p=0.7, list=F)
cv_train = data_xgb[cv_data, ]
cv_test = data_xgb[-cv_data, ]
# define explanatory variables (X's) and dependent variable (Y) in training set
train_x = data.matrix(cv_train[, -1]) #seleccionar todas las columnas menos la primera pq es la dependiente
train_y = cv_train[,1] #seleccionar solamente la primera pq es la dependiente
# define explanatory variables (X's) and dependent variable (Y) in testing set
test_x = data.matrix(cv_test[, -1])
test_y = cv_test[, 1]
# define final training and testing sets
xgb_train = xgb.DMatrix(data = train_x, label = train_y)
xgb_test = xgb.DMatrix(data = test_x, label = test_y)
# Lets fit XGBoost regression model and display RMSE for both training and testing data at each round
watchlist = list(train=xgb_train, test=xgb_test)
model_xgb = xgb.train(data=xgb_train, max.depth=3, watchlist=watchlist, nrounds=70)
## [1] train-rmse:12698.948008 test-rmse:12830.938891
## [2] train-rmse:9453.026194 test-rmse:9647.038046
## [3] train-rmse:7308.136508 test-rmse:7614.969459
## [4] train-rmse:5939.287404 test-rmse:6322.438367
## [5] train-rmse:5106.060187 test-rmse:5580.661249
## [6] train-rmse:4620.218506 test-rmse:5156.688296
## [7] train-rmse:4341.595139 test-rmse:4928.135124
## [8] train-rmse:4182.786050 test-rmse:4794.995494
## [9] train-rmse:4090.964227 test-rmse:4717.928616
## [10] train-rmse:4034.004734 test-rmse:4678.770793
## [11] train-rmse:3987.028983 test-rmse:4661.195458
## [12] train-rmse:3944.847082 test-rmse:4641.082752
## [13] train-rmse:3915.882903 test-rmse:4628.702088
## [14] train-rmse:3891.668431 test-rmse:4625.272617
## [15] train-rmse:3859.956647 test-rmse:4597.826432
## [16] train-rmse:3833.503030 test-rmse:4603.486348
## [17] train-rmse:3819.170199 test-rmse:4604.548695
## [18] train-rmse:3795.564395 test-rmse:4611.952679
## [19] train-rmse:3770.129916 test-rmse:4620.257176
## [20] train-rmse:3744.657857 test-rmse:4625.036175
## [21] train-rmse:3726.065892 test-rmse:4605.296091
## [22] train-rmse:3695.416217 test-rmse:4618.539794
## [23] train-rmse:3689.422434 test-rmse:4621.970822
## [24] train-rmse:3680.883096 test-rmse:4621.031111
## [25] train-rmse:3656.329281 test-rmse:4647.701420
## [26] train-rmse:3630.738857 test-rmse:4655.319650
## [27] train-rmse:3614.602771 test-rmse:4656.852225
## [28] train-rmse:3597.552535 test-rmse:4658.813095
## [29] train-rmse:3584.101633 test-rmse:4654.933999
## [30] train-rmse:3569.062711 test-rmse:4656.475085
## [31] train-rmse:3566.337150 test-rmse:4657.611154
## [32] train-rmse:3554.301959 test-rmse:4661.074501
## [33] train-rmse:3545.396841 test-rmse:4663.433794
## [34] train-rmse:3540.343443 test-rmse:4663.819863
## [35] train-rmse:3515.629475 test-rmse:4671.462321
## [36] train-rmse:3488.713019 test-rmse:4677.821777
## [37] train-rmse:3484.605703 test-rmse:4676.320020
## [38] train-rmse:3465.582213 test-rmse:4675.660260
## [39] train-rmse:3446.532350 test-rmse:4689.529080
## [40] train-rmse:3437.266563 test-rmse:4696.554977
## [41] train-rmse:3425.082849 test-rmse:4698.109859
## [42] train-rmse:3406.535735 test-rmse:4700.732617
## [43] train-rmse:3393.302257 test-rmse:4708.861979
## [44] train-rmse:3372.675808 test-rmse:4711.385226
## [45] train-rmse:3369.191495 test-rmse:4714.231994
## [46] train-rmse:3354.253598 test-rmse:4722.935440
## [47] train-rmse:3339.538087 test-rmse:4729.513663
## [48] train-rmse:3332.932077 test-rmse:4735.218592
## [49] train-rmse:3324.163932 test-rmse:4739.821060
## [50] train-rmse:3321.223821 test-rmse:4740.794787
## [51] train-rmse:3320.326252 test-rmse:4741.110612
## [52] train-rmse:3315.595921 test-rmse:4740.458508
## [53] train-rmse:3304.431218 test-rmse:4752.471478
## [54] train-rmse:3294.444166 test-rmse:4759.653225
## [55] train-rmse:3283.052539 test-rmse:4768.196457
## [56] train-rmse:3278.770235 test-rmse:4773.326782
## [57] train-rmse:3271.511622 test-rmse:4777.815396
## [58] train-rmse:3261.429279 test-rmse:4776.975397
## [59] train-rmse:3254.980231 test-rmse:4777.501234
## [60] train-rmse:3254.361950 test-rmse:4777.887334
## [61] train-rmse:3242.165437 test-rmse:4782.527513
## [62] train-rmse:3238.118449 test-rmse:4782.875334
## [63] train-rmse:3227.372039 test-rmse:4789.700039
## [64] train-rmse:3214.749719 test-rmse:4797.915797
## [65] train-rmse:3200.652279 test-rmse:4801.888020
## [66] train-rmse:3187.230930 test-rmse:4801.220100
## [67] train-rmse:3175.199375 test-rmse:4812.412603
## [68] train-rmse:3151.365418 test-rmse:4815.973371
## [69] train-rmse:3137.222644 test-rmse:4825.309412
## [70] train-rmse:3132.148084 test-rmse:4826.759749
Basado en los resultado parece que el RMSE más bajo en ambos sets ocurre en la línea 15.
reg_xgb = xgboost(data = xgb_train, max.depth = 3, nrounds = 15, verbose = 0)
prediction_xgb_test<-predict(reg_xgb, xgb_test)
RMSE_XGB <- rmse(prediction_xgb_test, cv_test$expenses)
RMSE_XGB
## [1] 4597.826
# Plot first 3 trees of model
xgb.plot.tree(model=reg_xgb, trees=0:2)
importance_matrix <- xgb.importance(model = reg_xgb)
xgb.plot.importance(importance_matrix, xlab = "Explanatory Variables X's Importance")
xgb_reg_residuals<-cv_test$expenses - prediction_xgb_test
plot(xgb_reg_residuals, xlab= "Dependent Variable", ylab = "Residuals", main = 'XGBoost Regression Residuals')
abline(0,0)
El modelo de XGBoost obtuvo un RMSE de 4597.826, hasta ahora el más bajo. Debido a que no es tan fácil su interpretacación se generó el árbol de decisión y el gráfico de barras para identificar que las variables que más influyen en este modelo son: smoker, age y bmi.
set.seed(123)
#Crear el modelo con la base de train
decision_tree_model <- rpart(log(expenses) ~ log(age) + log(bmi) + region + sex + children + smoker, data = train)
# summary(decision_tree_regression)
plot(decision_tree_model, compress = TRUE)
text(decision_tree_model, use.n = TRUE)
rpart.plot(decision_tree_model)
### RMSE of DECISION TREE REGRESSION
decision_tree_prediction <- predict(decision_tree_model,test)
RMSE_decision_tree <- rmse(exp(decision_tree_prediction), test$expenses)
RMSE_decision_tree
## [1] 5160.639
El árbol de decisión es un modelo sumamente fácil de interpretar, en este caso también obtuvo un RMSE bastante bajo con los otros modelos. Nuevamente, smoker, edad y bmi son los factores principales.
rf_model <- randomForest(expenses ~ smoker + age + bmi + children + sex + region, data= train, proximity=TRUE)
print(rf_model) ### the train data set model accuracy is around 85%.
##
## Call:
## randomForest(formula = expenses ~ smoker + age + bmi + children + sex + region, data = train, proximity = TRUE)
## Type of random forest: regression
## Number of trees: 500
## No. of variables tried at each split: 2
##
## Mean of squared residuals: 20116171
## % Var explained: 85.3
#Mean of squared residuals = MSE = benchmark
#% of Var explained = R-sq de los Random Forrest
# Prediction & Confusion Matrix – test data
rf_prediction <- predict(rf_model,test)
RMSE_rf <- rmse(rf_prediction, test$expenses)
RMSE_rf
## [1] 4915.729
# Evalute Variables' Importance
varImpPlot(rf_model, n.var = 5, main = "Top Variables")
importance(rf_model)
## IncNodePurity
## smoker 76278382456
## age 17455600981
## bmi 17645637950
## children 2753263528
## sex 1213982605
## region 2787283454
El modelo de Random Forest combina muchos árboles de decisión para mejorar la predicción. En este caso el forest es capaz de explicar el 85% de la variabilid de la variable dependiente, lo cual es bastante alto. El RMSE también es bueno, es menor al del árbol de decisión individual.
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:MASS':
##
## select
## The following object is masked from 'package:neuralnet':
##
## compute
## The following object is masked from 'package:randomForest':
##
## combine
## The following object is masked from 'package:xgboost':
##
## slice
## The following object is masked from 'package:car':
##
## recode
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
nn_datos <- dplyr::select(datos, expenses, age, sex, bmi, children, smoker, region)
nn_datos$sex <- ifelse(data_xgb$sex == "female", 1, 0)
nn_datos$smoker <- ifelse(nn_datos$smoker == "yes", 1, 0)
# smoker = 1
# no smoker = 0
nn_datos$region <- as.integer(factor(nn_datos$region, levels = c("northwest", "southeast", "southwest", "northeast"))) - 1
#northwest = 0
#southeast = 1
#soutwest = 2
#northeast = 3
#Crear la partición de datos
set.seed(123)
partition <- createDataPartition(y = nn_datos$expenses, p=0.7, list=F)
nntrain = nn_datos[partition, ]
nntest = nn_datos[-partition, ]
#Crear el modelo
nn_model <- neuralnet(expenses ~ age + bmi + smoker + region + sex + children, data = nntrain, hidden = c(5, 3), linear.output = TRUE)
# Plot the neural network
plot(nn_model)
nn_test <- nntest %>% select(age, bmi, smoker, sex, region, children)
nnpred <- predict(nn_model, nn_test)
RMSE_nn <- rmse(nnpred, nntest$expenses)
RMSE_nn
## [1] 11692.29
El modelo de redes neuronales es bastante poderosos para crear modelos de regressión, sin embargo en este caso se obtuvo un RMSE bastante alto. Su interpretabilidad es baja y no es fácil identificar cuales son las variables que más influyen el modelo.
df_rmse <- data.frame( OLS = RMSE_ols_model, LOG = RMSE_log_ols_model, XGBoost = RMSE_XGB, DT = RMSE_decision_tree, RF = RMSE_rf, NN = RMSE_nn, WLS = RMSE_wls_model)
df_rmse
## OLS LOG XGBoost DT RF NN WLS
## 1 5976.548 7539.91 4597.826 5160.639 4915.729 11692.29 6031.981
df_rmse <- df_rmse[, order(colMeans(df_rmse))]
barplot(as.matrix(df_rmse), beside = TRUE, horiz = TRUE, xlim = c(0, 12000), xlab = "RMSE")
Con base unicamente en los resultados del RMSE, el modelo que
seleccionaría sería XGBoost ya que fue el más chico. Sin embargo, si
tomara en cuenta la interpretabilidad, seleccionaría Random Forest
porque se puede identificar las “decisiones” que toma el modelo para
llegar la las predicciones.
Desarrollar una breve descripción de los 6 – 10 principales hallazgos de: a. EDA:
b. Modelo seleccionado: El modelo seleccionado fue XGBoost ya que tienen el RMSE más bajo de todos los modelos probados.
i. ¿Cuáles son las variables que contribuyen a explicar los cambios de la principal variable de estudio?
Las variables que más afectan son: Smoker, Age y BMI.
ii. ¿Cómo es el impacto de dichas variables explicativas sobre la variable dependiente?. Las variables de age, bmi y smoker, tienen un impacto positivo en la variable dependiente, es decir que si estos aumentan, expenses aumenta también.