Construir y evaluar un modelo KNN para predecir si una persona es FELIZ O NO FELIZ
Cargar librerías, datos y hacer lo necesario
library(class) # Funciones para clasificación
library(caret) # Funciones para Clasificación y Regresión
library(mlbench) # Funciones para Machine Learning
library(e1071) # Estadísticas
library(ggplot2) # Gráficas
library(dplyr) # Operaciones con datos
library(knitr) # Para tablas amigables
library (readr) # para leer datos
datos <- read.csv("https://raw.githubusercontent.com/rpizarrog/Industrias-4.0/main/datos/estado%20de%20felicidad%20variables.csv", encoding = "UTF-8")
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 |
Dejar algunas variables o utilizar solo las variables independientes de interés
datos.prep <- select(datos, satisfaccion.laboral, satisfaccion.profesional, vida.familiar, vida.social, dinero, estado )
kable(datos.prep, caption = "Datos preparados. Variables de interés")
| satisfaccion.laboral | satisfaccion.profesional | vida.familiar | vida.social | dinero | estado |
|---|---|---|---|---|---|
| 80.0 | 90.0 | 70.0 | 80.00 | 90.0 | FELIZ |
| 50.0 | 80.0 | 60.0 | 70.00 | 30.0 | NO FELIZ |
| 70.0 | 78.0 | 80.0 | 40.00 | 70.0 | FELIZ |
| 50.0 | 80.0 | 60.0 | 80.00 | 20.0 | NO FELIZ |
| 40.0 | 50.0 | 60.0 | 70.00 | 60.0 | NO FELIZ |
| 50.0 | 60.0 | 54.0 | 60.00 | 50.0 | NO FELIZ |
| 71.5 | 60.8 | 86.9 | 70.60 | 70.0 | FELIZ |
| 60.0 | 80.0 | 30.0 | 50.00 | 20.0 | NO FELIZ |
| 70.0 | 60.0 | 72.0 | 60.00 | 70.0 | FELIZ |
| 80.0 | 80.0 | 90.0 | 60.00 | 80.0 | FELIZ |
| 60.0 | 60.0 | 70.0 | 50.00 | 90.0 | FELIZ |
| 60.0 | 50.0 | 50.0 | 45.50 | 70.0 | NO FELIZ |
| 50.0 | 45.0 | 80.0 | 60.00 | 20.0 | NO FELIZ |
| 60.0 | 40.0 | 50.0 | 80.00 | 65.9 | FELIZ |
| 50.0 | 65.0 | 56.0 | 62.58 | 33.5 | NO FELIZ |
| 80.0 | 70.0 | 20.0 | 20.00 | 20.5 | NO FELIZ |
| 50.0 | 50.0 | 50.0 | 50.00 | 49.5 | FELIZ |
| 54.0 | 80.0 | 56.0 | 60.00 | 55.0 | FELIZ |
| 60.0 | 70.0 | 80.0 | 50.00 | 100.0 | FELIZ |
| 40.0 | 50.0 | 80.0 | 90.00 | 95.0 | FELIZ |
| 50.0 | 60.0 | 60.0 | 80.00 | 70.0 | FELIZ |
| 60.0 | 60.0 | 60.0 | 60.00 | 60.0 | FELIZ |
| 60.0 | 60.0 | 60.0 | 60.00 | 50.0 | FELIZ |
| 50.0 | 60.0 | 60.0 | 30.00 | 35.0 | NO FELIZ |
| 50.0 | 40.0 | 80.0 | 30.00 | 30.0 | NO FELIZ |
| 80.0 | 70.0 | 40.0 | 40.00 | 40.0 | NO FELIZ |
| 65.0 | 60.0 | 62.0 | 87.00 | 56.5 | FELIZ |
| 45.0 | 50.0 | 40.0 | 90.00 | 60.0 | NO FELIZ |
| 60.0 | 60.0 | 60.0 | 60.00 | 49.0 | FELIZ |
| 80.0 | 70.0 | 30.0 | 40.00 | 45.0 | NO FELIZ |
| 85.0 | 80.0 | 90.0 | 50.00 | 80.0 | FELIZ |
| 60.0 | 80.0 | 90.0 | 80.00 | 60.0 | FELIZ |
| 80.0 | 60.0 | 70.0 | 50.00 | 60.0 | FELIZ |
| 60.0 | 80.0 | 40.0 | 50.00 | 30.0 | NO FELIZ |
| 60.0 | 70.0 | 50.0 | 30.00 | 50.0 | FELIZ |
| 95.0 | 80.0 | 90.0 | 90.00 | 80.0 | FELIZ |
| 70.0 | 70.0 | 65.0 | 89.00 | 75.0 | FELIZ |
| 65.0 | 70.0 | 45.0 | 65.00 | 45.0 | FELIZ |
| 24.0 | 57.0 | 33.0 | 71.00 | 100.0 | NO FELIZ |
| 80.0 | 80.0 | 90.0 | 30.00 | 50.0 | FELIZ |
| 60.0 | 80.0 | 48.0 | 50.00 | 60.0 | FELIZ |
| 90.0 | 80.0 | 50.0 | 100.00 | 80.0 | FELIZ |
| 90.0 | 95.0 | 90.0 | 100.00 | 90.0 | FELIZ |
| 65.0 | 66.0 | 89.0 | 87.00 | 45.0 | NO FELIZ |
| 90.0 | 90.0 | 90.0 | 100.00 | 75.0 | FELIZ |
| 80.0 | 80.0 | 90.0 | 90.00 | 90.0 | FELIZ |
| 50.0 | 80.0 | 90.0 | 80.00 | 90.0 | FELIZ |
| 30.0 | 60.0 | 80.0 | 50.00 | 50.0 | NO FELIZ |
| 80.0 | 80.0 | 80.0 | 80.00 | 70.0 | FELIZ |
| 60.0 | 80.0 | 48.0 | 50.00 | 50.0 | NO FELIZ |
| 100.0 | 100.0 | 100.0 | 100.00 | 100.0 | NO FELIZ |
| 70.0 | 80.0 | 80.0 | 80.00 | 80.0 | FELIZ |
En este ejercicio, el modelo de vecinos mas cercanos (KNN) se construye con los mismos datos preparados y las columnas numéricas [,1:5] para posteriormente evaluar el modelo mediante los criterios de una matriz de confusión.
modelo <- knn(train = datos.prep[,1:5], test = datos.prep[,1:5], k = 4, cl = datos.prep[,6] )
modelo
## [1] FELIZ NO FELIZ FELIZ NO FELIZ FELIZ FELIZ FELIZ NO FELIZ
## [9] FELIZ FELIZ FELIZ FELIZ NO FELIZ FELIZ NO FELIZ NO FELIZ
## [17] FELIZ FELIZ FELIZ FELIZ FELIZ FELIZ FELIZ FELIZ
## [25] NO FELIZ NO FELIZ FELIZ FELIZ FELIZ NO FELIZ FELIZ FELIZ
## [33] FELIZ NO FELIZ FELIZ FELIZ FELIZ FELIZ NO FELIZ FELIZ
## [41] FELIZ FELIZ FELIZ FELIZ FELIZ FELIZ FELIZ NO FELIZ
## [49] FELIZ FELIZ FELIZ FELIZ
## Levels: FELIZ NO FELIZ
summary(modelo)
## FELIZ NO FELIZ
## 40 12
Se construye un conjunto de datos llamado datos.r.p con valores reales y valores predichos a partir de los datos preparados incorporados en el algoritmo KNN.
datos.r.p <- data.frame(reales = datos.prep$estado, prediccion = modelo)
datos.r.p
## reales prediccion
## 1 FELIZ FELIZ
## 2 NO FELIZ NO FELIZ
## 3 FELIZ FELIZ
## 4 NO FELIZ NO FELIZ
## 5 NO FELIZ FELIZ
## 6 NO FELIZ FELIZ
## 7 FELIZ FELIZ
## 8 NO FELIZ NO FELIZ
## 9 FELIZ FELIZ
## 10 FELIZ FELIZ
## 11 FELIZ FELIZ
## 12 NO FELIZ FELIZ
## 13 NO FELIZ NO FELIZ
## 14 FELIZ FELIZ
## 15 NO FELIZ NO FELIZ
## 16 NO FELIZ NO FELIZ
## 17 FELIZ FELIZ
## 18 FELIZ FELIZ
## 19 FELIZ FELIZ
## 20 FELIZ FELIZ
## 21 FELIZ FELIZ
## 22 FELIZ FELIZ
## 23 FELIZ FELIZ
## 24 NO FELIZ FELIZ
## 25 NO FELIZ NO FELIZ
## 26 NO FELIZ NO FELIZ
## 27 FELIZ FELIZ
## 28 NO FELIZ FELIZ
## 29 FELIZ FELIZ
## 30 NO FELIZ NO FELIZ
## 31 FELIZ FELIZ
## 32 FELIZ FELIZ
## 33 FELIZ FELIZ
## 34 NO FELIZ NO FELIZ
## 35 FELIZ FELIZ
## 36 FELIZ FELIZ
## 37 FELIZ FELIZ
## 38 FELIZ FELIZ
## 39 NO FELIZ NO FELIZ
## 40 FELIZ FELIZ
## 41 FELIZ FELIZ
## 42 FELIZ FELIZ
## 43 FELIZ FELIZ
## 44 NO FELIZ FELIZ
## 45 FELIZ FELIZ
## 46 FELIZ FELIZ
## 47 FELIZ FELIZ
## 48 NO FELIZ NO FELIZ
## 49 FELIZ FELIZ
## 50 NO FELIZ FELIZ
## 51 NO FELIZ FELIZ
## 52 FELIZ FELIZ
Ahora se construye la matriz de confusión con la función confusionMatrix() no sin antes categorizar o factorizar los valores de datos.r.p
datos.r.p$reales <- as.factor(datos.r.p$reales)
datos.r.p$prediccion <- as.factor(datos.r.p$prediccion)
matriz <- confusionMatrix(datos.r.p$reales, datos.r.p$prediccion)
matriz
## Confusion Matrix and Statistics
##
## Reference
## Prediction FELIZ NO FELIZ
## FELIZ 32 0
## NO FELIZ 8 12
##
## Accuracy : 0.8462
## 95% CI : (0.7192, 0.9312)
## No Information Rate : 0.7692
## P-Value [Acc > NIR] : 0.12206
##
## Kappa : 0.6486
##
## Mcnemar's Test P-Value : 0.01333
##
## Sensitivity : 0.8000
## Specificity : 1.0000
## Pos Pred Value : 1.0000
## Neg Pred Value : 0.6000
## Prevalence : 0.7692
## Detection Rate : 0.6154
## Detection Prevalence : 0.6154
## Balanced Accuracy : 0.9000
##
## 'Positive' Class : FELIZ
##
exactitud <- round(as.numeric(matriz$overall[1]) * 100,2)
sensibilidad <- round(as.numeric(matriz$byClass[1]) * 100,2)
especificidad <- round(as.numeric(matriz$byClass[2]) * 100,2)
precision.FELIZ <- round(as.numeric(matriz$byClass[3]) * 100,2)
precision.NOFELIZ <- round(as.numeric(matriz$byClass[4]) * 100,2)
kappa <- round(as.numeric(matriz$overall[2]) * 100,2)
exactitud
## [1] 84.62
sensibilidad
## [1] 80
especificidad
## [1] 100
precision.FELIZ
## [1] 100
precision.NOFELIZ
## [1] 60
kappa
## [1] 64.86
Se interpreta que el valor de accuracy o exactitud es del: 84.62 %, es decir, es el porcentaje de aciertos
¿Qué porcentajes es de sensibilidad y qué significa?. 80 % y significa …
¿Qué porcentaje es de especificidad y qué significa?. 100 % y significa …
¿Qué porcentaje es precisión (Pos Pred Value) relación a los casos POSITIVOS ‘FELIZ’ y qué significa?. 100 % y significa …
¿Qué porcentaje es precisión (Neg Pred Value) con relación a los casos NEGATIVOS ‘NO FELIZ’ y qué significa?. 60 % y significa …
¿Hay otros criterios que permiten evaluar el modelo?, valor de kappa con 64.86 y significa ….
Se crean datos nuevos
Primero hay que generar los nuevos datos
#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)
estado = c('?', '?', '?')
datos.nuevos <- data.frame(satisfaccion.laboral, satisfaccion.profesional, vida.familiar, vida.social, dinero, estado )
kable(datos.nuevos, caption = "Datos nuevos")
| satisfaccion.laboral | satisfaccion.profesional | vida.familiar | vida.social | dinero | estado |
|---|---|---|---|---|---|
| 40 | 60 | 80 | 60 | 40 | ? |
| 50 | 50 | 70 | 50 | 50 | ? |
| 60 | 40 | 60 | 76 | 60 | ? |
modelo <- knn(train = datos.prep[,1:5], test = datos.nuevos[,1:5], k = 4, cl = datos.prep[,6] )
modelo
## [1] NO FELIZ FELIZ FELIZ
## Levels: FELIZ NO FELIZ
summary(modelo)
## FELIZ NO FELIZ
## 2 1
datos.nuevos <- mutate(datos.nuevos, prediccion = modelo)
kable(datos.nuevos, caption = "Predicción de datos nuevos")
| satisfaccion.laboral | satisfaccion.profesional | vida.familiar | vida.social | dinero | estado | prediccion |
|---|---|---|---|---|---|---|
| 40 | 60 | 80 | 60 | 40 | ? | NO FELIZ |
| 50 | 50 | 70 | 50 | 50 | ? | FELIZ |
| 60 | 40 | 60 | 76 | 60 | ? | FELIZ |