Construir interpretar un modelo de árbol de clasificación para predecir estados de felicidad de una persona conforme a características.
Se cargan datos de github: https://raw.githubusercontent.com/rpizarrog/Industrias-4.0/main/datos/estado%20de%20felicidad%20variables.csv
Se asignan a una variable datos
Se cargan las librerías necesarias
Se muestra la estructura de los mismos con función str() y se describen con la función summary()
Se define la tarea de clasificación y sus métricas
Se construye un modelo
Se interpreta el modelo
Se hacen predicciones
Se concluye con explicaciones
Cargar librerías y es necesario instalar aquellas que no se tienen de manera anticipada.
library(readr) # install.package
library(dplyr)
library(caret) # Para matriz de confusion
library(rpart) # Para arbol
library(rpart.plot) # Para arbol
library(knitr) # Para tablas amigables con los datos
datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/Industrias-4.0/main/datos/estado%20de%20felicidad%20variables.csv", encoding = "UTF-8", stringsAsFactors = TRUE)
kable(datos, caption = "Los datos")
| genero | esto.civil | edad | satisfaccion.laboral | satisfaccion.profesional | vida.familiar | vida.social | salud | dinero | estado |
|---|---|---|---|---|---|---|---|---|---|
| MASCULINO | SOLTERO | 25 | 80.0 | 90.0 | 70.0 | 80.00 | BUENO | 90.0 | FELIZ |
| FEMENINO | CASADO | 35 | 50.0 | 80.0 | 60.0 | 70.00 | MALO | 30.0 | NO FELIZ |
| MASCULINO | DIVORCIADO | 45 | 70.0 | 78.0 | 80.0 | 40.00 | REGULAR | 70.0 | FELIZ |
| FEMENINO | VIUDO | 54 | 50.0 | 80.0 | 60.0 | 80.00 | BUENO | 20.0 | NO FELIZ |
| MASCULINO | CASADO | 52 | 40.0 | 50.0 | 60.0 | 70.00 | BUENO | 60.0 | NO FELIZ |
| FEMENINO | SOLTERO | 28 | 50.0 | 60.0 | 54.0 | 60.00 | MALO | 50.0 | NO FELIZ |
| MASCULINO | VIUDO | 56 | 71.5 | 60.8 | 86.9 | 70.60 | MALO | 70.0 | FELIZ |
| FEMENINO | DIVORCIADO | 32 | 60.0 | 80.0 | 30.0 | 50.00 | REGULAR | 20.0 | NO FELIZ |
| MASCULINO | CASADO | 35 | 70.0 | 60.0 | 72.0 | 60.00 | BUENO | 70.0 | FELIZ |
| FEMENINO | SOLTERO | 29 | 80.0 | 80.0 | 90.0 | 60.00 | MALO | 80.0 | FELIZ |
| MASCULINO | DIVORCIADO | 45 | 60.0 | 60.0 | 70.0 | 50.00 | REGULAR | 90.0 | FELIZ |
| FEMENINO | VIUDO | 48 | 60.0 | 50.0 | 50.0 | 45.50 | MALO | 70.0 | NO FELIZ |
| MASCULINO | CASADO | 26 | 50.0 | 45.0 | 80.0 | 60.00 | MALO | 20.0 | NO FELIZ |
| FEMENINO | SOLTERO | 34 | 60.0 | 40.0 | 50.0 | 80.00 | BUENO | 65.9 | FELIZ |
| MASCULINO | DIVORCIADO | 42 | 50.0 | 65.0 | 56.0 | 62.58 | REGULAR | 33.5 | NO FELIZ |
| FEMENINO | VIUDO | 35 | 80.0 | 70.0 | 20.0 | 20.00 | MALO | 20.5 | NO FELIZ |
| MASCULINO | CASADO | 48 | 50.0 | 50.0 | 50.0 | 50.00 | BUENO | 49.5 | FELIZ |
| FEMENINO | SOLTERO | 34 | 54.0 | 80.0 | 56.0 | 60.00 | REGULAR | 55.0 | FELIZ |
| MASCULINO | DIVORCIADO | 34 | 60.0 | 70.0 | 80.0 | 50.00 | MALO | 100.0 | FELIZ |
| FEMENINO | SOLTERO | 32 | 40.0 | 50.0 | 80.0 | 90.00 | BUENO | 95.0 | FELIZ |
| MASCULINO | SOLTERO | 29 | 50.0 | 60.0 | 60.0 | 80.00 | MALO | 70.0 | FELIZ |
| FEMENINO | SOLTERO | 26 | 60.0 | 60.0 | 60.0 | 60.00 | BUENO | 60.0 | FELIZ |
| MASCULINO | CASADO | 45 | 60.0 | 60.0 | 60.0 | 60.00 | BUENO | 50.0 | FELIZ |
| FEMENINO | VIUDO | 45 | 50.0 | 60.0 | 60.0 | 30.00 | REGULAR | 35.0 | NO FELIZ |
| MASCULINO | CASADO | 28 | 50.0 | 40.0 | 80.0 | 30.00 | MALO | 30.0 | NO FELIZ |
| FEMENINO | DIVORCIADO | 32 | 80.0 | 70.0 | 40.0 | 40.00 | MALO | 40.0 | NO FELIZ |
| MASCULINO | SOLTERO | 36 | 65.0 | 60.0 | 62.0 | 87.00 | REGULAR | 56.5 | FELIZ |
| FEMENINO | CASADO | 40 | 45.0 | 50.0 | 40.0 | 90.00 | MALO | 60.0 | NO FELIZ |
| MASCULINO | SOLTERO | 41 | 60.0 | 60.0 | 60.0 | 60.00 | BUENO | 49.0 | FELIZ |
| FEMENINO | VIUDO | 38 | 80.0 | 70.0 | 30.0 | 40.00 | BUENO | 45.0 | NO FELIZ |
| MASCULINO | CASADO | 36 | 85.0 | 80.0 | 90.0 | 50.00 | BUENO | 80.0 | FELIZ |
| FEMENINO | CASADO | 38 | 60.0 | 80.0 | 90.0 | 80.00 | BUENO | 60.0 | FELIZ |
| FEMENINO | CASADO | 37 | 80.0 | 60.0 | 70.0 | 50.00 | BUENO | 60.0 | FELIZ |
| FEMENINO | SOLTERO | 40 | 60.0 | 80.0 | 40.0 | 50.00 | REGULAR | 30.0 | NO FELIZ |
| MASCULINO | CASADO | 40 | 60.0 | 70.0 | 50.0 | 30.00 | BUENO | 50.0 | FELIZ |
| FEMENINO | CASADO | 43 | 95.0 | 80.0 | 90.0 | 90.00 | BUENO | 80.0 | FELIZ |
| MASCULINO | CASADO | 55 | 70.0 | 70.0 | 65.0 | 89.00 | MALO | 75.0 | FELIZ |
| MASCULINO | SOLTERO | 45 | 65.0 | 70.0 | 45.0 | 65.00 | BUENO | 45.0 | FELIZ |
| FEMENINO | CASADO | 41 | 24.0 | 57.0 | 33.0 | 71.00 | BUENO | 100.0 | NO FELIZ |
| FEMENINO | SOLTERO | 40 | 80.0 | 80.0 | 90.0 | 30.00 | REGULAR | 50.0 | FELIZ |
| MASCULINO | SOLTERO | 39 | 60.0 | 80.0 | 48.0 | 50.00 | BUENO | 60.0 | FELIZ |
| MASCULINO | SOLTERO | 42 | 90.0 | 80.0 | 50.0 | 100.00 | REGULAR | 80.0 | FELIZ |
| FEMENINO | SOLTERO | 45 | 90.0 | 95.0 | 90.0 | 100.00 | BUENO | 90.0 | FELIZ |
| MASCULINO | VIUDO | 88 | 65.0 | 66.0 | 89.0 | 87.00 | REGULAR | 45.0 | NO FELIZ |
| MASCULINO | CASADO | 54 | 90.0 | 90.0 | 90.0 | 100.00 | BUENO | 75.0 | FELIZ |
| MASCULINO | SOLTERO | 80 | 80.0 | 80.0 | 90.0 | 90.00 | BUENO | 90.0 | FELIZ |
| MASCULINO | SOLTERO | 39 | 50.0 | 80.0 | 90.0 | 80.00 | REGULAR | 90.0 | FELIZ |
| FEMENINO | SOLTERO | 40 | 30.0 | 60.0 | 80.0 | 50.00 | REGULAR | 50.0 | NO FELIZ |
| FEMENINO | SOLTERO | 49 | 80.0 | 80.0 | 80.0 | 80.00 | BUENO | 70.0 | FELIZ |
| MASCULINO | SOLTERO | 39 | 60.0 | 80.0 | 48.0 | 50.00 | REGULAR | 50.0 | NO FELIZ |
| FEMENINO | SOLTERO | 30 | 100.0 | 100.0 | 100.0 | 100.00 | BUENO | 100.0 | NO FELIZ |
| FEMENINO | SOLTERO | 32 | 70.0 | 80.0 | 80.0 | 80.00 | BUENO | 80.0 | FELIZ |
summary(datos)
## genero esto.civil edad satisfaccion.laboral
## FEMENINO :26 CASADO :16 Min. :25.00 Min. : 24.00
## MASCULINO:26 DIVORCIADO: 6 1st Qu.:34.00 1st Qu.: 50.00
## SOLTERO :23 Median :39.50 Median : 60.00
## VIUDO : 7 Mean :40.79 Mean : 64.03
## 3rd Qu.:45.00 3rd Qu.: 80.00
## Max. :88.00 Max. :100.00
## satisfaccion.profesional vida.familiar vida.social salud
## Min. : 40.00 Min. : 20.00 Min. : 20.00 BUENO :25
## 1st Qu.: 60.00 1st Qu.: 50.00 1st Qu.: 50.00 MALO :13
## Median : 70.00 Median : 61.00 Median : 60.00 REGULAR:14
## Mean : 68.98 Mean : 65.48 Mean : 64.57
## 3rd Qu.: 80.00 3rd Qu.: 80.00 3rd Qu.: 80.00
## Max. :100.00 Max. :100.00 Max. :100.00
## dinero estado
## Min. : 20.00 FELIZ :32
## 1st Qu.: 48.00 NO FELIZ:20
## Median : 60.00
## Mean : 60.86
## 3rd Qu.: 80.00
## Max. :100.00
str(datos)
## 'data.frame': 52 obs. of 10 variables:
## $ genero : Factor w/ 2 levels "FEMENINO","MASCULINO": 2 1 2 1 2 1 2 1 2 1 ...
## $ esto.civil : Factor w/ 4 levels "CASADO","DIVORCIADO",..: 3 1 2 4 1 3 4 2 1 3 ...
## $ edad : int 25 35 45 54 52 28 56 32 35 29 ...
## $ satisfaccion.laboral : num 80 50 70 50 40 50 71.5 60 70 80 ...
## $ satisfaccion.profesional: num 90 80 78 80 50 60 60.8 80 60 80 ...
## $ vida.familiar : num 70 60 80 60 60 54 86.9 30 72 90 ...
## $ vida.social : num 80 70 40 80 70 60 70.6 50 60 60 ...
## $ salud : Factor w/ 3 levels "BUENO","MALO",..: 1 2 3 1 1 2 2 3 1 2 ...
## $ dinero : num 90 30 70 20 60 50 70 20 70 80 ...
## $ estado : Factor w/ 2 levels "FELIZ","NO FELIZ": 1 2 1 2 2 2 1 2 1 1 ...
Realizar una tarea de clasificación para predecir si una persona es FELIZ O NO FELIZ de acuerdo a ciertas características o variables independientes.
El modelo debe tener un valor de exactitud mayor al 60%
El modelo debe garantizar una precisión de valores positivos mayor al 50%
El modelo debe garantizar una precisión de valores negativos mayor al 20%
Debe tener un valor de sensibilidad superior al 40%
Debe tener un valor de especificidad superior al 35%
modelo <- rpart(estado ~ ., data = datos)
sm <- summary(modelo)
## Call:
## rpart(formula = estado ~ ., data = datos)
## n= 52
##
## CP nsplit rel error xerror xstd
## 1 0.55 0 1.00 1.00 0.1754116
## 2 0.05 1 0.45 0.55 0.1472504
## 3 0.01 2 0.40 0.75 0.1633484
##
## Variable importance
## dinero vida.familiar satisfaccion.laboral
## 45 17 13
## esto.civil satisfaccion.profesional vida.social
## 10 8 7
##
## Node number 1: 52 observations, complexity param=0.55
## predicted class=FELIZ expected loss=0.3846154 P(node) =1
## class counts: 32 20
## probabilities: 0.615 0.385
## left son=2 (39 obs) right son=3 (13 obs)
## Primary splits:
## dinero < 47 to the right, improve=10.051280, (0 missing)
## vida.familiar < 42.5 to the right, improve= 6.126496, (0 missing)
## satisfaccion.laboral < 52 to the right, improve= 5.127096, (0 missing)
## esto.civil splits as LLLR, improve= 3.612210, (0 missing)
## salud splits as LRR, improve= 3.282051, (0 missing)
## Surrogate splits:
## vida.familiar < 46.5 to the right, agree=0.827, adj=0.308, (0 split)
## esto.civil splits as LLLR, agree=0.808, adj=0.231, (0 split)
## vida.social < 42.75 to the right, agree=0.788, adj=0.154, (0 split)
## satisfaccion.profesional < 47.5 to the right, agree=0.769, adj=0.077, (0 split)
##
## Node number 2: 39 observations, complexity param=0.05
## predicted class=FELIZ expected loss=0.2051282 P(node) =0.75
## class counts: 31 8
## probabilities: 0.795 0.205
## left son=4 (30 obs) right son=5 (9 obs)
## Primary splits:
## satisfaccion.laboral < 52 to the right, improve=2.8735040, (0 missing)
## vida.familiar < 55 to the right, improve=2.3386380, (0 missing)
## satisfaccion.profesional < 58.5 to the right, improve=2.2893770, (0 missing)
## genero splits as RL, improve=1.0989010, (0 missing)
## dinero < 62.95 to the right, improve=0.6255574, (0 missing)
## Surrogate splits:
## satisfaccion.profesional < 58.5 to the right, agree=0.846, adj=0.333, (0 split)
## vida.familiar < 44 to the right, agree=0.821, adj=0.222, (0 split)
##
## Node number 3: 13 observations
## predicted class=NO FELIZ expected loss=0.07692308 P(node) =0.25
## class counts: 1 12
## probabilities: 0.077 0.923
##
## Node number 4: 30 observations
## predicted class=FELIZ expected loss=0.1 P(node) =0.5769231
## class counts: 27 3
## probabilities: 0.900 0.100
##
## Node number 5: 9 observations
## predicted class=NO FELIZ expected loss=0.4444444 P(node) =0.1730769
## class counts: 4 5
## probabilities: 0.444 0.556
sm
## n= 52
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 52 20 FELIZ (0.61538462 0.38461538)
## 2) dinero>=47 39 8 FELIZ (0.79487179 0.20512821)
## 4) satisfaccion.laboral>=52 30 3 FELIZ (0.90000000 0.10000000) *
## 5) satisfaccion.laboral< 52 9 4 NO FELIZ (0.44444444 0.55555556) *
## 3) dinero< 47 13 1 NO FELIZ (0.07692308 0.92307692) *
prp(modelo, main = "Arbol de Clasificación")
prp(modelo, main="Arbol de Clasificación",
nn = TRUE, # display the node numbers
fallen.leaves = TRUE, # put the leaves on the bottom of the page
shadow.col = "gray", # shadows under the leaves
branch.lty = 3, # draw branches using dotted lines
branch = .5, # change angle of branch lines
faclen = 0, # faclen = 0 to print full factor names
trace = 1, # print the auto calculated cex, xlim, ylim
split.cex = 1.2, # make the split text larger than the node text
split.prefix = "is ", # put "is " before split text
split.suffix = "?", # put "?" after split text
split.box.col = "lightblue", # lightgray split boxes (default is white)
split.border.col = "darkgray", # darkgray border on split boxes
split.round = 0.5) # round the split box corners a tad
## cex 1 xlim c(-0.2, 1.2) ylim c(-0.15, 1.15)
Por medio de una matriz de confusión construida a partir de los valores reales de la variable estado de los datos y los valores de predicción de la misma variable estado. Se identifican las métricas generadas de la matriz de confusión y se comparan con los criterios establecidos inicialmente.
La variable datos.R.P (datos reales y predicción) tendrá dos columnas ,los datos reales y los de predicción de la variable estado conforme al modelo y a partir de ella construir la matriz de confusión.
Se genera predicción con datos originales
prediccion <- predict(object = modelo, datos, type = "class")
prediccion
## 1 2 3 4 5 6 7 8
## FELIZ NO FELIZ FELIZ NO FELIZ NO FELIZ NO FELIZ FELIZ NO FELIZ
## 9 10 11 12 13 14 15 16
## FELIZ FELIZ FELIZ FELIZ NO FELIZ FELIZ NO FELIZ NO FELIZ
## 17 18 19 20 21 22 23 24
## NO FELIZ FELIZ FELIZ NO FELIZ NO FELIZ FELIZ FELIZ NO FELIZ
## 25 26 27 28 29 30 31 32
## NO FELIZ NO FELIZ FELIZ NO FELIZ FELIZ NO FELIZ FELIZ FELIZ
## 33 34 35 36 37 38 39 40
## FELIZ NO FELIZ FELIZ FELIZ FELIZ NO FELIZ NO FELIZ FELIZ
## 41 42 43 44 45 46 47 48
## FELIZ FELIZ FELIZ NO FELIZ FELIZ FELIZ NO FELIZ NO FELIZ
## 49 50 51 52
## FELIZ FELIZ FELIZ FELIZ
## Levels: FELIZ NO FELIZ
datos.R.P <- data.frame(realidad = datos$estado, prediccion)
kable(datos.R.P, caption = "Reales / Predicciones")
| realidad | prediccion |
|---|---|
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | NO FELIZ |
| FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| FELIZ | FELIZ |
| FELIZ | NO FELIZ |
| NO FELIZ | NO FELIZ |
| FELIZ | FELIZ |
| NO FELIZ | FELIZ |
| NO FELIZ | FELIZ |
| FELIZ | FELIZ |
Antes de crear matriz de confusión asegurarse de que las etiquetas del datos.R.P son de tipo factor
datos.R.P$realidad <- as.factor(datos.R.P$realidad)
datos.R.P$prediccion <- as.factor(datos.R.P$prediccion)
matriz <- confusionMatrix(datos.R.P$realidad, datos.R.P$prediccion)
matriz
## Confusion Matrix and Statistics
##
## Reference
## Prediction FELIZ NO FELIZ
## FELIZ 27 5
## NO FELIZ 3 17
##
## Accuracy : 0.8462
## 95% CI : (0.7192, 0.9312)
## No Information Rate : 0.5769
## P-Value [Acc > NIR] : 3.104e-05
##
## Kappa : 0.681
##
## Mcnemar's Test P-Value : 0.7237
##
## Sensitivity : 0.9000
## Specificity : 0.7727
## Pos Pred Value : 0.8438
## Neg Pred Value : 0.8500
## Prevalence : 0.5769
## Detection Rate : 0.5192
## Detection Prevalence : 0.6154
## Balanced Accuracy : 0.8364
##
## 'Positive' Class : FELIZ
##
De acuerdo a los valores de las métricas de la matriz de confusión con el modelo de árbol de clasificación, las métricas superan las expectativas el ejercicio.
La exactitud es 84.62% que significa que el modelo se equivoca en un 16%.
La precisión de casos positivos es de 84.38% que significa que de acuerdo a la clase de FELIZ el modelo acierta en ese porcentaje.
La precisión de casos negativos es de 85.00% que significa que de acuerdo a la clase de NO FELIZ el modelo acierta en ese porcentaje.
La sensibilidad es del 90% y la especificidad es del 77% que significan e indican la capacidad de estimador para discriminar los casos positivos, de los negativos.
Sensibilidad significa la proporción de casos positivos que fueron correctamente identificadas por el modelo y especificidad significa que de los casos negativos que el modelo ha clasificado correctamente.
Se crean tres casos nuevos :
genero <- c('MASCULINO', 'FEMENINO', 'FEMENINO')
esto.civil <- c('SOLTERO', 'CASADO', 'DIVORCIADO')
edad <- c(30, 25, 40)
satisfaccion.laboral <- c(40, 50, 60)
satisfaccion.profesional <- c(60, 50, 40)
vida.familiar <- c(80, 70, 60)
vida.social <- c(60,50,76)
salud <- c('BUENO', 'REGULAR', 'MALO')
dinero <- c(40, 50, 60)
prediccion = c('?', '?', '?')
datos.nuevos <- data.frame(genero, edad, satisfaccion.laboral, satisfaccion.profesional, vida.familiar, vida.social, dinero, prediccion )
kable(datos.nuevos, captio = "Datos nuevos")
| genero | edad | satisfaccion.laboral | satisfaccion.profesional | vida.familiar | vida.social | dinero | prediccion |
|---|---|---|---|---|---|---|---|
| MASCULINO | 30 | 40 | 60 | 80 | 60 | 40 | ? |
| FEMENINO | 25 | 50 | 50 | 70 | 50 | 50 | ? |
| FEMENINO | 40 | 60 | 40 | 60 | 76 | 60 | ? |
Se hace la predicción
prediccion.nueva <- predict(object = modelo, newdata = datos.nuevos, type = 'class')
prediccion.nueva
## 1 2 3
## NO FELIZ NO FELIZ FELIZ
## Levels: FELIZ NO FELIZ
Pendiente …