Objetivo

Construir y evaluar un modelo KNN para predecir si una persona es FELIZ O NO FELIZ

Descripción

Cargar librerías, datos y hacer lo necesario

Desarrollo

Cargar librerías

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

Cargar los 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")
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

Preparar los datos

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")
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

Construir el modelo KNN

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

Evaluar el modelo

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

Categorizar o factorizar

datos.r.p$reales <- as.factor(datos.r.p$reales)
datos.r.p$prediccion <- as.factor(datos.r.p$prediccion)

Crear matriz de confusión

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 ….

Predecir con datos nuevos

Se crean datos nuevos

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")
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 ?

Predicciones

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")
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