Clasificador Naive Bayes
Universidad Tecnológica de Bolivar
6/8/23
En un sentido amplio, los modelos de Naive Bayes son una clase especial de algoritmos de clasificación de Aprendizaje Automatico, o Machine Learning, tal y como nos referiremos de ahora en adelante.
Se basan en una técnica de clasificación estadística llamada “teorema de Bayes”.
Estos modelos son llamados algoritmos “Naive”, o “Inocentes” en español. En ellos se asume que las variables predictoras son independientes entre sí.
En otras palabras, que la presencia de una cierta característica en un conjunto de datos no está en absoluto relacionada con la presencia de cualquier otra característica.
Proporcionan una manera fácil de construir modelos con un comportamiento muy bueno debido a su simplicidad.
El teorema de Bayes expresa la probabilidad de que ocurra el evento A, dado que ha ocurrido B, en función de la probabilidad de que ocurra B dado que ha ocurrido A, de la probabilidad de A y de la probabilidad de B. La fórmula del teorema de Bayes es la siguiente:
\[P(B|A)=\frac{P(B)P(A|B)}{P(A)}\]
Donde:
Como se puede apreciar, el teorema de Bayes permite calcular la probabilidad de que ocurra un evento, a partir de valores conocidos de otras probabilidades relacionadas al evento.
El teorema o regla de Bayes fue planteado por el matemático y religioso inglés Thomas Bayes. Este teorema fue publicado en el año 1763, dos años después de la muerte de Bayes.
En la academia de Matemóvil, la probabilidad de que a un alumno seleccionado al azar le guste el helado es del 60%, mientras que la probabilidad de que a un alumno le guste la torta es del 36%. Además, se sabe que la probabilidad de que a un alumno le guste la torta dado que le gusta el helado es del 40%. Calcular la probabilidad de que a un alumno le guste el helado, dado que le gusta la torta.
Primero definimos los 2 eventos con los que vamos a trabajar:
Tenemos los siguientes datos:
Nos piden calcular \(P(H|T)\). Aplicamos el teorema de Bayes:
\[\begin{align*} P(H|T)= & \frac{P(H)P(T|H)}{P(T)} \\ = & \frac{0.6 \times 0.4 }{0.36} \\ = & 0.6667 \end{align*}\]
Entonces, la probabilidad de que un alumno le guste el helado dado que le gusta la torta es de 0.6667 o 66.67%.
El clasificador Naive Bayes aplica el bien conocido teorema de Bayes para la probabilidad condicional. En su forma más simple para el evento A y B, el teorema de Bayes relaciona dos probabilidades condicionales de la siguiente manera:
\[P(A\cap B)=P(A, B)=P(A)P(B|A)=P(B)P(A|B) \implies P(B|A)=\frac{P(B)P(A|B)}{P(A)}\]
Ahora veamos cómo se puede usar esta fórmula simple para hacer un clasificador.
\[X_1=x_1,\ X_2=x_2,\ X_3=x_3,\dots , X_n=x_n\]
Ahora, lo que queremos hacer es evaluar la probabilidad de que la observación provenga de cualquiera de las \(K\) clases, es decir, de algún \(C_k\). Podemos escribir esto en términos de notación de probabilidad condicional:
\[P(y=C_k|X_1=x_1, X_2=x_2,\dots , X_n=x_n), \\ \text{de forma breve,}\ \ \ \ \ \ P(C_k|x_1, x_2,x_3,\dots , x_n)\]
En la fórmula de Bayes anterior, si reemplazamos
\[B = C_k \quad \text{ y } \quad A=x_1 \cap x_2 \cap, \dots, \cap x_n=\{x_1,x_2,\dots,x_n\}\]
podemos escribir la probabilidad condicional anterior de la siguiente manera:
\[P(C_k|x_1, x_2,\dots , x_n)=\frac{P(C_k)P(x_1, x_2,\dots,x_n|C_k)}{P(x_1, x_2,\dots,x_n)}\]
Ahora el numerador de lo anterior es solo la probabilidad conjunta de \(C_k\) y \(\{x_1,x_2,\dots,x_n\}\), es decir \[P(C_k\cap \{ x_1, x_2,\dots,x_n\})=P(C_k, x_1, x_2,\dots,x_n)\]
Ahora , podemos aplicar la fórmula de Bayes repetidamente para obtener el siguientes resultado:
\[P(C_k)P(x_n|C_k)P(x_{n-1}|x_n,C_k)\dots P(x_1|x_2,x_3, \dots,x_n, C_k)\]
La expresión anterior es bastante larga, también implica un número de probabilidades condicionales. Pero con un supuesto de independencia condicional, esta larga expresión se puede reducir a una forma muy simple.
\[P(A|B,C)=P(A|C)\]
Ahora bien, esta fórmula se puede aplicar para nuestro caso. Asumimos que todos los predictores \(x_1,x_2, \dots,x_n\) son independientes condicionados a la clase \(C_k\). Por lo tanto,
\[\begin{align*} P(x_1|x_2,x_3,\dots, x_n,C_k)= & P(x_1|C_k)\\ P(x_2|x_3,x_4,\dots, x_n,C_k)= & P(x_2|C_k) \end{align*}\] etcétera. Entonces, la expresión larga anterior se puede escribir como:
\[P(x_1, x_2,\dots,x_n, C_k)=P(C_k)P(x_n|C_k)P(x_{n-1}|C_k)P(x_{n-2}|C_k)\dots P(x_1|C_k)\]
\[\implies P(x_1, x_2,\dots,x_n, C_k)=P(C_k)\prod_{j=1}^{n}P(x_j|C_k)\]
Luego, tenemos que:
\[P(C_k|x_1, x_2,x_3,\dots , x_n)=\frac{P(C_k)\prod_{j=1}^{n}P(x_j|C_k)}{P(x_1, x_2,\dots,x_n)}\]
\[P(C_k) \quad \text { y } \quad \prod^n_{j=1}P(x_j|C_k)\] en la expresión anterior se conocen como a priori y verosimilitud respectivamente. La probabilidad a priori se puede estimar como
\[P(C_k)=\frac{n_{class \ k}}{n_{total}}\]
Usaremos los paquetes DescTools, caret y e1071; además, el archivo DirectMarketing.csv, que contiene información de 1000 clientes de una empresa que vende productos por catálogo de pedidos por correo. El problema es el siguiente:
Las variables incluyen:
Librerías nocesarias
Primero, podemos obtener información de alto nivel sobre el marco de datos de DM para observar los tipos de variables y verificar los valores faltantes (NA).
A continuación, podemos convertir nuestra variable de clase objetivo que queremos predecir, Importe, en una variable de factor nominal.
Aunque es ordinal, la usaremos como variable nominal por compatibilidad. Identificaremos el nivel 1 como Below_Avg y el nivel 2 como Above_Avg para reflejar el orden conocido.
Podemos trazar la distribución utilizando un gráfico de barras, que es el gráfico predeterminado para la función plot() cuando se aplica a variables de factores.
Solo tenemos una variable numérica, Salario. Podemos configurar un valor con nombre, nums (aunque no es necesario).
Finalmente, podemos crear nuestro vector de conveniencia de variables predictoras (vars) que contiene todos nuestros predictores. Podemos ver los predictores por nombre ejecutando una línea de código del objeto vars.
Veamos la información de summary() para nuestros datos preparados.
Variables redundantes: necesitamos identificar variables predictoras numéricas (X) altamente correlacionadas y excluirlas de nuestro modelo predictivo. Dado que solo tenemos una variable numérica, no debemos preocuparnos por la redundancia.
Variables numéricas normalmente distribuidas: por suposición, Naive Bayes espera que las variables numéricas tengan una distribución normal. Podemos inspeccionar visualmente la distribución de nuestra variable numérica, Salario, utilizando un histograma.
Podemos transformar la variable Salario a aproximadamente normal.
Usamos la función createDataPartition() del paquete caret para el conjunto de entrenamiento. Dado que la función toma una muestra aleatoria, primero inicializamos una semilla (set.seed(831)) aleatoria para la reproducibilidad de la partición de los datos.
Subconjunto de las filas del marco de datos DM_bcs para incluir los números de fila en el subobjeto para crear el marco de datos del tren. Usamos todas las observaciones que no están en el subobjeto para crear el marco de datos de prueba.
Usamos la función naiveBayes() del paquete e1071 para realizar la clasificación Naive Bayes.
Si tenemos valores de NA que no manejamos durante el preprocesamiento, podemos usar el argumento na.action, que por defecto es na.pass, lo que significa que las NA no se incluirán al calcular las probabilidades. Alternativamente, se puede especificar na.action = na.omit y los NA no se incluirán en el modelado.
El valor predeterminado de Laplace es 0, lo que significa que no se aplica el suavizado de Laplace.
Para determinar si necesitamos usar el suavizado de Laplace, debemos buscar categorías de probabilidad cero.
Como tenemos categorías con frecuencia 0, estableceremos laplace = 1.
El modelo con sus parámetros sería:
Para evaluar la bondad de ajuste del modelo, comparamos el rendimiento de entrenamiento y prueba. Por esta razón, necesitamos evaluar qué tan bien funciona el modelo en la muestra de entrenamiento.
Para evaluar el rendimiento del modelo, nos enfocamos en el rendimiento del modelo aplicado al conjunto de prueba. A continuación, usamos la función predict() para obtener las predicciones de clase (type = “class”) para los datos de prueba basados en nuestro modelo NB.
Nuevamente, usamos la función confusionMatrix() del paquete caret para obtener una matriz de confusión y obtener medidas de rendimiento para nuestro modelo, esta vez aplicadas al conjunto de datos de prueba (prueba).
Podemos describir el rendimiento general en función de nuestra precisión y valores kappa.
Podemos describir el rendimiento a nivel de clase para los diferentes niveles de clase. Tenga en cuenta que arriba establecemos positivo = “Above_Avg”, ya que estamos más interesados en predecir clientes que gastarán una cantidad superior a la media
Comparemos ahora el rendimiento de nivel de clase en los conjuntos de entrenamiento y prueba.
Con los datos salary_data_2