5 Clasificador bayesiano ingenuo (Naive Bayes)

Objetivos del capítulo

Al finalizar la lectura de este capítulo el lector estará en capacidad de:

  • Explicar en sus propias palabras la utilidad de un modelo clasificador bayesiano ingenuo (Naive Bayes) para la tarea de clasificación.
  • Emplear un modelo clasificador bayesiano ingenuo en R.
  • Calcular métricas de la bondad de un modelo de clasificación estimado por medio de un modelo Naive Bayes.
  • Encontrar las predicciones de clasificación de un modelo Naive Bayes.

5.1 Introducción

El clasificador bayesiano ingenuo (también conocido como clasificador Naive Bayes o solamente Naive Bayes) es otro método estadístico que se basa en el teorema de Bayes para realizar la tarea de clasificación bajo el supuesto (ingenuo) de que las variables explicativas (o predictoras) son independientes entre sí.

El teorema de Bayes permite conocer cuál es la probabilidad de observar uno de los posibles valores de la variable aleatoria A (\(A_i\))39 dado que se observó el evento B. Esta probabilidad se escribe como40 \(P(A_i \lvert B)\). Esta probabilidad se conoce como la probabilidad a posteriori o probabilidad condicionada.

El teorema de Bayes implica que: \[\begin{equation} P(A_i \lvert B)= \frac{P(A_i)P(B \lvert A_i)}{P(B)} \end{equation}\] donde, \(P(A_i)\) es la probabilidad no condicionada de que ocurra el evento \(A_i\). \(P(B)\) es la probabilidad de observar el evento \(B\). Y \(P(B \lvert A_i)\) es la probabilidad de observar el evento \(B\) dado que ocurre \(A_i\).

Intuitivamente, se puede ver cómo es posible adaptar el teorema de Bayes para el caso de la clasificación con dos clases. En este caso solo existen dos posibles valores para la variable \(A\): \(A = 1\) y \(A = 0\). Adicionalmente, se puede considerar que \(B\) corresponde a las características del individuo a clasificar. Entonces, por ejemplo la probabilidad de que para un individuo se observe un uno será igual a: \[\begin{equation*} P(A=1 \lvert B)= \frac{P(A=1)P(B \lvert A=1)}{P(B)} \end{equation*}\]

Este método de clasificación empleará las frecuencias observadas en la muestra para calcular, por individuo, tanto la probabilidad de ser igual a uno como ser igual a cero para las características determinadas del individuo. Aquella categoría con mayor probabilidad será la asignada por este algoritmo.

En lo que resta de este capítulo discutiremos formalmente este método y demostraremos cómo emplear R para implementar el clasificador bayesiano ingenuo.

5.2 Detalles del modelo Naive Bayes

Definamos \(C_j\) como las categorías de \(y\), nuestra variable de interés. Adicionalmente, para encontrar la probabilidad de observar una determinada categoría \(C_j\) emplearemos las características recogidas en las \(p\) variables explicativas: \((X_1, X_2, X_3, \dots, X_p)\). Entonces, para cada individuo nuestro objetivo será calcular: \[\begin{equation*} P(y=C_j|X_1,X_2, X_3, \dots, X_p) \end{equation*}\]

En otras palabras, lo que deseamos encontrar es la probabilidad de pertenecer a cierta clase \(C_j\) dado ciertos valores de nuestras variables explicativas. Aplicando el teorema de Bayes, para una realización de las variables \(X_1,X_2,X_3,...,X_p\) tenemos: \[\begin{equation*} P(y=C_j|x_1, x_2, \dots, x_p)=\frac{P(y=C_j)P(x_1,x_2, \dots,x_p|y=C_j)}{P(x_1, x_2, \dots, x_p)} \end{equation*}\]

Ahora, suponiendo (de manera ingenua) que las variables explicativas \((x_1,x_2,\dots ,x_p)\) son independientes para las categorías \(C_j\) tendremos que: \[\begin{equation*} P(x_1,x_2, \dots,x_p|y=C_j) = P(x_1 |y=C_j) P(x_2 |y=C_j) \dots P(x_p |y=C_j) \end{equation*}\] y además la independencia de las variables explicativas implicará: \[\begin{equation*} P(x_1,x_2, \dots,x_p) = P(x_1) P(x_2) \dots P(x_p) \end{equation*}\]

Finalmente, entonces el teorema de Bayes en este contexto y con el supuesto de independencia implicará: \[\begin{equation*} P(y=C_j|x_1,x_2, \dots,x_p)=\frac{{P(y=C_j)\prod_{j=1}^p P(x_j|y=C_j)}}{{P(x_1)P(x_2)...P(x_p)}} \end{equation*}\]

Noten que para un individuo el denominador será igual para cualquier categoría que adopte la variable \(y\). Así, si se desea encontrar la categoría \(C_j\) con la mayor probabilidad para un individuo, esto equivale a comparar solamente los numeradores. O dicho de otra manera, la probabilidad condicional es proporcional al numerador. Es decir, \[\begin{equation} P(y=C_j|x_1,x_2, \dots,x_p)\propto{P(y=C_j)\prod_{j=1}^p P(x_j|y=C_j)} \end{equation}\]

Entonces, la idea de este algoritmo es asignar la categoría \(C_j\) al individuo \(i\) si esta tiene la mayor probabilidad de ocurrencia. Es decir, \[\begin{equation} C_j= argmax_{C_j}{P(y=C_j)\prod_{j=1}^p P(x_j|y=C_j)} \end{equation}\]

Evaluaremos el producto de la probabilidad no condicionada de observar cada categoría de \(y\) y la probabilidad condicional de observar cada uno de los valores de las variables explicativas del individuo \(i\) condicionado a la correspondiente categoría. Y se escoge la categoría que tenga dicho producto más alto.

La probabilidad no condicionada \(P(y=C_j)\) no es más que dividir el total de observaciones en la clase \(j\) entre el total de observaciones de todas las clases. El término \(\prod_{j=1}^p P(x_j|y=C_j)\) se requiere de las distribuciones de probabilidad condicional \(f(X_j|y=C_j)\) para \(j=1,2,3,..,p\). Habitualmente se asume normalidad si la variable es continua y distribución multinomial si es discreta.

5.3 Aplicación en R del modelo Naive Bayes

Para nuestro trabajo en R, seguiremos empleando los mismos datos que empleamos en el Capítulo 3 y Capítulo 4 (Ver detalles de cada uno de los pasos para construir la base de datos en el Capítulo 3). Carga el working space que guardaste en el Capítulo 4.

Recuerda que contamos con un objeto que contiene la muestra de estimación datos_dummies_est y otro con la muestra de evaluación datos_dummies_eval.

Para aplicar el modelo Naive Bayes en R, vamos a usar el paquete e1071 (Meyer et al., 2023) , existen otros paquetes como naivebayes (Majka, 2019) que también permite hacer la estimación del modelo. La función naiveBayes(), realiza los pasos anteriormente descritos para el clasificador bayesiano ingenuo. Esta función requiere argumentos similares a la función glm() estudiada en el Capítulo 3, el primer argumento debe ser la fórmula y el segundo los datos. Veamos un ejemplo empleando todas las variables en el objeto :

library(e1071)
# Estimar el modelo Naive Bayes
model_naive <- naiveBayes(y ~ . ,
                          data = datos_dummies_est)

print(model_naive)
## 
## Naive Bayes Classifier for Discrete Predictors
## 
## Call:
## naiveBayes.default(x = X, y = Y, laplace = laplace)
## 
## A-priori probabilities:
## Y
##       no      yes 
## 0.885736 0.114264 
## 
## Conditional probabilities:
##      age
## Y         [,1]      [,2]
##   no  39.90269  9.889701
##   yes 41.03373 13.918015
## 
##      campaign
## Y         [,1]     [,2]
##   no  2.638444 2.914564
##   yes 2.030013 1.659482
## 
##      previous
## Y          [,1]      [,2]
##   no  0.1322255 0.4066817
##   yes 0.5003984 0.8794576
## 
##      poutcome
## Y        failure nonexistent    success
##   no  0.10008566  0.88665410 0.01326024
##   yes 0.12934927  0.67808765 0.19256308
## 
##      emp_var_rate
## Y           [,1]     [,2]
##   no   0.2440055 1.484797
##   yes -1.2249668 1.618526
## 
##      cons_price_idx
## Y         [,1]      [,2]
##   no  93.60406 0.5597387
##   yes 93.36144 0.6752099
## 
##      cons_conf_idx
## Y          [,1]     [,2]
##   no  -40.59526 4.395171
##   yes -39.89065 6.102165
## 
##      euribor3m
## Y         [,1]     [,2]
##   no  3.805837 1.640795
##   yes 2.125707 1.741372
## 
##      j_blue_collar
## Y          [,1]      [,2]
##   no  0.2360116 0.4246367
##   yes 0.1362550 0.3431047
## 
##      j_entrepreneur
## Y           [,1]      [,2]
##   no  0.03659414 0.1877664
##   yes 0.02788845 0.1646751
## 
##      j_housemaid
## Y           [,1]      [,2]
##   no  0.02604077 0.1592593
##   yes 0.02177955 0.1459824
## 
##      j_management
## Y           [,1]      [,2]
##   no  0.07102964 0.2568787
##   yes 0.07224436 0.2589265
## 
##      j_retired
## Y           [,1]      [,2]
##   no  0.03536063 0.1846928
##   yes 0.09614874 0.2948343
## 
##      j_self_employed
## Y           [,1]      [,2]
##   no  0.03477814 0.1832206
##   yes 0.03213811 0.1763902
## 
##      j_services
## Y           [,1]      [,2]
##   no  0.09957170 0.2994332
##   yes 0.06932271 0.2540358
## 
##      j_student
## Y           [,1]      [,2]
##   no  0.01668665 0.1280967
##   yes 0.06002656 0.2375676
## 
##      j_technician
## Y          [,1]      [,2]
##   no  0.1647079 0.3709231
##   yes 0.1553785 0.3623132
## 
##      j_unemployed
## Y           [,1]      [,2]
##   no  0.02360802 0.1518271
##   yes 0.03187251 0.1756840
## 
##      j_unknown
## Y            [,1]       [,2]
##   no  0.008017817 0.08918410
##   yes 0.008499336 0.09181142
## 
##      m_married
## Y          [,1]      [,2]
##   no  0.6130204 0.4870673
##   yes 0.5426295 0.4982456
## 
##      m_single
## Y          [,1]      [,2]
##   no  0.2717492 0.4448689
##   yes 0.3450199 0.4754379
## 
##      m_unknown
## Y            [,1]       [,2]
##   no  0.001816001 0.04257659
##   yes 0.002921647 0.05398041
## 
##      e_basic_6y
## Y           [,1]      [,2]
##   no  0.05718691 0.2322034
##   yes 0.03984064 0.1956106
## 
##      e_basic_9y
## Y          [,1]      [,2]
##   no  0.1518246 0.3588569
##   yes 0.1011952 0.3016271
## 
##      e_high_school
## Y          [,1]      [,2]
##   no  0.2341271 0.4234593
##   yes 0.2223108 0.4158541
## 
##      e_illiterate
## Y             [,1]       [,2]
##   no  0.0003083776 0.01755828
##   yes 0.0007968127 0.02822037
## 
##      e_professional_course
## Y          [,1]      [,2]
##   no  0.1269145 0.3328829
##   yes 0.1280212 0.3341578
## 
##      e_university_degree
## Y          [,1]      [,2]
##   no  0.2869625 0.4523517
##   yes 0.3598938 0.4800328
## 
##      e_unknown
## Y           [,1]      [,2]
##   no  0.04019188 0.1964124
##   yes 0.05577689 0.2295209
## 
##      def_unknown
## Y           [,1]      [,2]
##   no  0.22288847 0.4161912
##   yes 0.09508632 0.2933731
## 
##      def_yes
## Y             [,1]       [,2]
##   no  0.0001027925 0.01013832
##   yes 0.0000000000 0.00000000
## 
##      h_unknown
## Y           [,1]      [,2]
##   no  0.02388213 0.1526846
##   yes 0.02390438 0.1527716
## 
##      h_yes
## Y          [,1]      [,2]
##   no  0.5198218 0.4996155
##   yes 0.5397078 0.4984870
## 
##      l_unknown
## Y           [,1]      [,2]
##   no  0.02388213 0.1526846
##   yes 0.02390438 0.1527716
## 
##      l_yes
## Y          [,1]      [,2]
##   no  0.1525441 0.3595537
##   yes 0.1500664 0.3571839
## 
##      c_telephone
## Y          [,1]      [,2]
##   no  0.3907144 0.4879189
##   yes 0.1715803 0.3770654
## 
##      mon_aug
## Y          [,1]      [,2]
##   no  0.1504883 0.3575555
##   yes 0.1359894 0.3428228
## 
##      mon_dec
## Y            [,1]       [,2]
##   no  0.002535549 0.05029122
##   yes 0.018061089 0.13319008
## 
##      mon_jul
## Y          [,1]      [,2]
##   no  0.1771458 0.3817986
##   yes 0.1434263 0.3505536
## 
##      mon_jun
## Y          [,1]      [,2]
##   no  0.1311633 0.3375846
##   yes 0.1235060 0.3290608
## 
##      mon_mar
## Y           [,1]       [,2]
##   no  0.00729827 0.08511905
##   yes 0.06002656 0.23756760
## 
##      mon_may
## Y          [,1]      [,2]
##   no  0.3528182 0.4778549
##   yes 0.1909695 0.3931172
## 
##      mon_nov
## Y           [,1]      [,2]
##   no  0.10083947 0.3011212
##   yes 0.08924303 0.2851321
## 
##      mon_oct
## Y           [,1]      [,2]
##   no  0.01134144 0.1058924
##   yes 0.06401062 0.2448044
## 
##      mon_sep
## Y            [,1]       [,2]
##   no  0.008771629 0.09324691
##   yes 0.054448871 0.22693142
## 
##      d_mon
## Y          [,1]      [,2]
##   no  0.2081891 0.4060198
##   yes 0.1824701 0.3862828
## 
##      d_thu
## Y          [,1]      [,2]
##   no  0.2075381 0.4055511
##   yes 0.2278884 0.4195260
## 
##      d_tue
## Y          [,1]      [,2]
##   no  0.1957855 0.3968110
##   yes 0.1984064 0.3988528
## 
##      d_wed
## Y          [,1]      [,2]
##   no  0.1956484 0.3967058
##   yes 0.2071713 0.4053332

Realicemos la predicción, empleando la función predict() aplicada al objeto de clase naiveBayes que tiene el modelo del que se quiere hacer la predicción. Esta es la misma función que empleamos en el Capítulo 4, la diferencia es que en este caso el argumento type debe ser “class”, de esta forma, sobre la muestra de evaluación las predicciones son:

# Calcular las predicciones del modelo para la muestra de evaluación
pred_modelo_naive <- predict(model_naive, newdata = datos_dummies_eval, 
                             type = "class")

# ver las 10 primeras predicciones
head(pred_modelo_naive, 10)
##  [1] no no no no no no no no no no
## Levels: no yes

Como podemos observar, ya no nos arroja una probabilidad sino la categoría a la que pertenece la observación, en nuestro caso “yes” o “no”.

5.4 Bondad de ajuste del modelo

Ahora calculemos las métricas de evaluación derivadas de la matriz de confusión, usando la función confusionMatrix() del paquete caret (Kuhn & Max, 2008) como lo realizamos en el Capítulo 4:

library(caret)
# Calcular métricas del modelo Naive Bayes
mo_naive <- confusionMatrix(pred_modelo_naive, datos_dummies_eval$y, positive = "yes")
print(mo_naive)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   no  yes
##        no  6620  462
##        yes  743  413
##                                           
##                Accuracy : 0.8537          
##                  95% CI : (0.8459, 0.8613)
##     No Information Rate : 0.8938          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.3251          
##                                           
##  Mcnemar's Test P-Value : 7.257e-16       
##                                           
##             Sensitivity : 0.47200         
##             Specificity : 0.89909         
##          Pos Pred Value : 0.35727         
##          Neg Pred Value : 0.93476         
##              Prevalence : 0.10622         
##          Detection Rate : 0.05013         
##    Detection Prevalence : 0.14033         
##       Balanced Accuracy : 0.68555         
##                                           
##        'Positive' Class : yes             
## 

Ahora podemos compararlo con lo obtenido con el mejor modelo Logit identificado en el Capítulo 4. En ese caso teníamos:

confusionMatrix(pred_modelo2, datos_dummies_eval$y, positive = "yes")$table
##           Reference
## Prediction   no  yes
##        no  6427  334
##        yes  936  541

Las otras métricas estudiadas del mejor modelo Logit y el Naive Bayes se reportan en el Cuadro 5.1. La medida de accuracy del modelo de Naive Bayes (85.4%) es más alto comparado con el modelo Logit (84.6%); sin embargo, clasificando el valor positivo “yes”, no es muy bueno. Se observa que clasifica mal a 74341 observaciones en la clase “yes”, que realmente no fueron “yes”. Noten que un problema similar se presenta en el modelo Logit (con 936 falsos positivos que corresponden al 63.4 % de los positivos que predice el modelo). Veamos las métricas para los dos modelos vistos hasta el momento.

Cuadro 5.1: Métricas de comparación de modelos para modelo Logit y Naive Bayes
Accuracy Sensitivity Specificity Precision F1
Modelo Logit 0.846 0.618 0.873 0.366 0.460
Naive Bayes 0.854 0.472 0.899 0.357 0.407
Fuente: elaboración propia.

Para terminar, guarda el espacio de trabajo para ser empleado en los siguientes capítulos.

5.5 Comentarios Finales

En este Capítulo hemos aprendido otro método estadístico para realizar la tarea de clasificación. En los próximos capítulos estudiaremos métodos de aprendizaje de máquinas que también sirven para realizar la tarea de clasificar. Como se mencionó anteriormente, a priori, es imposible saber si este método será mejor que el estadístico u otros de aprendizaje de máquina. Por eso, es una buena práctica emplear diferentes aproximaciones y compararlas para obtener el mejor modelo para responder la pregunta de negocio.

Las aplicaciones de estos métodos de clasificación son muchas en el mundo de los negocios y definitivamente estos modelos son necesarios en la caja de herramientas de un científico de datos.

Referencias

Kuhn, & Max. (2008). Building predictive models in r using the caret package. Journal of Statistical Software, 28(5), 1–26. https://doi.org/10.18637/jss.v028.i05
Majka, M. (2019). Naivebayes: High performance implementation of the naive bayes algorithm in r. https://CRAN.R-project.org/package=naivebayes
Meyer, D., Dimitriadou, E., Hornik, K., Weingessel, A., & Leisch, F. (2023). e1071: Misc functions of the department of statistics, probability theory group (formerly: E1071), TU wien. https://CRAN.R-project.org/package=e1071

  1. \(A_i\) puede tomar cualquier valor del conjunto (\({A_1, A_2, ..., A_i, ..., A_n}\)) con probabilidad \(P(A_i)\). \(P(A_i)\) se conoce como la probabilidad a priori o no condicionada de que ocurra el evento \(A_i\).↩︎

  2. Esto se lee como la probabilidad de que ocurra \(A_i\) dado B.↩︎

  3. Esto representa el 64.3% de todos los positivos predichos por el modelo Naive Bayes.↩︎