Saltar al contenido principal

Tutorial de clasificación Naive Bayes con Scikit-learn

Aprende a construir y evaluar un Clasificador Naive Bayes utilizando el paquete Scikit-learn de Python.
13 mar 2024  · 13 min de lectura

Ejecute y edite el código de este tutorial en línea

Ejecutar código

Supón que eres director de producto y quieres clasificar las opiniones de los clientes en clases positivas y negativas. O como gestor de préstamos, quieres identificar qué solicitantes de préstamos son seguros o arriesgados. Como analista sanitario, quieres predecir qué pacientes pueden padecer la enfermedad de la diabetes. Todos los ejemplos tienen el mismo tipo de problema para clasificar reseñas, solicitantes de préstamos y pacientes.

Naive Bayes es el algoritmo de clasificación más sencillo y rápido, adecuado para una gran cantidad de datos. El clasificador Naive Bayes se utiliza con éxito en diversas aplicaciones, como el filtrado de spam, la clasificación de textos, el análisis de opinión y los sistemas de recomendación. Utiliza el teorema de Bayes de la probabilidad para la predicción de la clase desconocida.

En este tutorial, vas a aprender todo lo siguiente:

  • Flujo de trabajo de la clasificación
  • ¿Qué es el clasificador Naive Bayes?
  • ¿Cómo funciona el clasificador Naive Bayes?
  • Creación de clasificadores en Scikit-learn
  • Problema de probabilidad cero
  • Ventajas y desventajas

Más información sobre Scikit-learn en Python en nuestro curso de Aprendizaje supervisado con scikit-learn.

Flujo de trabajo de la clasificación

Siempre que realices una clasificación, el primer paso es comprender el problema e identificar las posibles características y la etiqueta. Los rasgos son aquellas características o atributos que afectan a los resultados de la etiqueta. Por ejemplo, en el caso de la distribución de un préstamo, los gestores del banco identifican la ocupación, los ingresos, la edad, la ubicación, el historial de préstamos anteriores, el historial de transacciones y la puntuación crediticia del cliente. Estas características se conocen como rasgos que ayudan al modelo a clasificar a los clientes.

La clasificación tiene dos fases, una de aprendizaje y otra de evaluación. En la fase de aprendizaje, el clasificador entrena su modelo en un conjunto de datos determinado, y en la fase de evaluación, comprueba el rendimiento del clasificador. El rendimiento se evalúa en función de varios parámetros, como la exactitud, el error, la precisión y el recuerdo.

Flujo de trabajo de clasificación

¿Qué es el clasificador Naive Bayes?

Naive Bayes es una técnica de clasificación estadística basada en el Teorema de Bayes. Es uno de los algoritmos de aprendizaje supervisado más sencillos. El clasificador Naive Bayes es un algoritmo rápido, preciso y fiable. Los clasificadores Naive Bayes tienen una gran precisión y velocidad en grandes conjuntos de datos.

El clasificador Naive Bayes asume que el efecto de una característica concreta en una clase es independiente de otras características. Por ejemplo, un solicitante de préstamo es deseable o no en función de sus ingresos, su historial previo de préstamos y transacciones, su edad y su ubicación. Aunque estas características sean interdependientes, se siguen considerando de forma independiente. Esta suposición simplifica el cálculo, y por eso se considera ingenua. Este supuesto se denomina independencia condicional de clase.

¿Qué es el clasificador Naive Bayes?
  • P(h): la probabilidad de que la hipótesis h sea cierta (independientemente de los datos). Esto se conoce como probabilidad a priori de h.
  • P(D): la probabilidad de los datos (independientemente de la hipótesis). Esto se conoce como probabilidad a priori.
  • P(h|D): la probabilidad de la hipótesis h dados los datos D. Se conoce como probabilidad posterior.
  • P(D|h): la probabilidad de los datos d dado que la hipótesis h fuera cierta. Esto se conoce como probabilidad posterior.

¿Cómo funciona el clasificador Naive Bayes?

Comprendamos el funcionamiento de Naive Bayes mediante un ejemplo. Pon un ejemplo de las condiciones meteorológicas y la práctica de deportes. Tienes que calcular la probabilidad de practicar deporte. Ahora, tienes que clasificar si los jugadores jugarán o no, en función de las condiciones meteorológicas.

Primer enfoque (en caso de una única característica)

El clasificador Naive Bayes calcula la probabilidad de un suceso en los siguientes pasos:

  • Paso 1: calcula la probabilidad a priori de las etiquetas de clase dadas
  • Paso 2: encuentra la Probabilidad con cada atributo para cada clase
  • Paso 3: pon estos valores en la Fórmula de Bayes y calcula la probabilidad posterior.
  • Paso 4: comprueba qué clase tiene mayor probabilidad, dado que la entrada pertenece a la clase de mayor probabilidad.

Para simplificar el cálculo de probabilidades a priori y a posteriori, puedes utilizar las dos tablas de frecuencias y probabilidades. Ambas tablas te ayudarán a calcular la probabilidad a priori y a posteriori. Frequency table contiene la frecuencia de aparición de etiquetas para todas las características. Hay dos tablas de probabilidad. Likelihood Table 1 muestra las probabilidades a priori de las etiquetas y la Likelihood Table 2 muestra la probabilidad a posteriori.

tablas

Supón ahora que quieres calcular la probabilidad de jugar cuando el tiempo está nublado.

Probabilidad de jugar:

P(Yes | Overcast) = P(Overcast | Yes) P(Yes) / P (Overcast) .....................(1)

  1. Calcula las probabilidades previas:

    P(Overcast) = 4/14 = 0.29

    P(Yes)= 9/14 = 0.64

  1. Calcula las Probabilidades Posteriores:

    P(Overcast |Yes) = 4/9 = 0.44

  1. Pon las probabilidades Prior y Posterior en la ecuación (1)

    P (Yes | Overcast) = 0.44 * 0.64 / 0.29 = 0.98(Higher)

Del mismo modo, puedes calcular la probabilidad de no jugar:

Probabilidad de no jugar:

P(No | Overcast) = P(Overcast | No) P(No) / P (Overcast) .....................(2)

  1. Calcula las probabilidades previas:

    P(Overcast) = 4/14 = 0.29

    P(No)= 5/14 = 0.36

  1. Calcula las Probabilidades Posteriores:

    P(Overcast |No) = 0/9 = 0

  1. Pon las probabilidades Prior y Posterior en la ecuación (2)

    P (No | Overcast) = 0 * 0.36 / 0.29 = 0

La probabilidad de una clase "Yes" es mayor. Así que puedes determinar aquí si el tiempo está nublado que los jugadores practicarán el deporte.

Segundo enfoque (en caso de características múltiples)

¿Cómo funciona el clasificador Naive Bayes?

Supón ahora que quieres calcular la probabilidad de jugar cuando el tiempo está nublado y la temperatura es suave.

Probabilidad de jugar:

P(Play= Yes | Weather=Overcast, Temp=Mild) = P(Weather=Overcast, Temp=Mild | Play= Yes)P(Play=Yes) ..........(1)

P(Weather=Overcast, Temp=Mild | Play= Yes)= P(Overcast |Yes) P(Mild |Yes) ………..(2)

  1. Calcula las probabilidades previas: P(Yes)= 9/14 = 0.64

  2. Calcula las Probabilidades Posteriores: P(Overcast |Yes) = 4/9 = 0.44 P(Mild |Yes) = 4/9 = 0.44

  3. Pon las probabilidades Posteriores en la ecuación (2) P(Weather=Overcast, Temp=Mild | Play= Yes) = 0.44 * 0.44 = 0.1936(Higher)

  4. Pon las probabilidades a priori y a posteriori en la ecuación (1) P(Play= Yes | Weather=Overcast, Temp=Mild) = 0.1936*0.64 = 0.124

Del mismo modo, puedes calcular la probabilidad de no jugar:

Probabilidad de no jugar:

P(Play= No | Weather=Overcast, Temp=Mild) = P(Weather=Overcast, Temp=Mild | Play= No)P(Play=No) ..........(3)

P(Weather=Overcast, Temp=Mild | Play= No)= P(Weather=Overcast |Play=No) P(Temp=Mild | Play=No) ………..(4)

  1. Calcula las probabilidades previas: P(No)= 5/14 = 0.36

  2. Calcula las Probabilidades Posteriores: P(Weather=Overcast |Play=No) = 0/9 = 0 P(Temp=Mild | Play=No)=2/5=0.4

  3. Pon las probabilidades posteriores en la ecuación (4) P(Weather=Overcast, Temp=Mild | Play= No) = 0 * 0.4= 0

  4. Pon las probabilidades a priori y a posteriori en la ecuación (3) P(Play= No | Weather=Overcast, Temp=Mild) = 0*0.36=0

La probabilidad de una clase "Yes" es mayor. Así que se puede decir que si el tiempo está nublado, los jugadores practicarán deporte.

Creación de clasificadores en Scikit-learn

Clasificador Naive Bayes con conjunto de datos sintéticos

En el primer ejemplo, generaremos datos sintéticos utilizando scikit-learn y entrenaremos y evaluaremos el algoritmo gaussiano Naive Bayes. 

Generar el conjunto de datos

Scikit-learn nos proporciona un ecosistema de machine learning para que puedas generar el conjunto de datos y evaluar diversos algoritmos de machine learning. 

En nuestro caso, estamos creando un conjunto de datos con seis características, tres clases y 800 muestras mediante la función `make_classification`. 

from sklearn.datasets import make_classification

X, y = make_classification(
    n_features=6,
    n_classes=3,
    n_samples=800,
    n_informative=2,
    random_state=1,
    n_clusters_per_class=1,
)

Utilizaremos la función `scatter` de matplotlib.pyplot para visualizar el conjunto de datos. 

import matplotlib.pyplot as plt

plt.scatter(X[:, 0], X[:, 1], c=y, marker="*");

Como podemos observar, hay tres tipos de etiquetas objetivo, y vamos a entrenar un modelo de clasificación multiclase. 

División de prueba de entrenamiento

Antes de iniciar el proceso de entrenamiento, tenemos que dividir el conjunto de datos en entrenamiento y prueba para evaluar el modelo. 

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.33, random_state=125
)

Construcción de modelos y formación 

Construye un Naive Bayes gaussiano genérico y entrénalo en un conjunto de datos de entrenamiento. Después, introduce una muestra de prueba aleatoria en el modelo para obtener un valor predicho.

from sklearn.naive_bayes import GaussianNB

# Build a Gaussian Classifier
model = GaussianNB()

# Model training
model.fit(X_train, y_train)

# Predict Output
predicted = model.predict([X_test[6]])

print("Actual Value:", y_test[6])
print("Predicted Value:", predicted[0])

Tanto los valores reales como los previstos son iguales. 

Actual Value: 0
Predicted Value: 0

Evaluación del modelo

No haremos evolucionar el modelo sobre un conjunto de datos de prueba no visto. En primer lugar, predeciremos los valores del conjunto de datos de prueba y los utilizaremos para calcular la precisión y la puntuación F1. 

from sklearn.metrics import (
    accuracy_score,
    confusion_matrix,
    ConfusionMatrixDisplay,
    f1_score,
)

y_pred = model.predict(X_test)
accuray = accuracy_score(y_pred, y_test)
f1 = f1_score(y_pred, y_test, average="weighted")

print("Accuracy:", accuray)
print("F1 Score:", f1)

Nuestro modelo ha funcionado bastante bien con los hiperparámetros por defecto. 

Accuracy: 0.8484848484848485
F1 Score: 0.8491119695890328

Para visualizar la matriz de confusión, utilizaremos `confusion_matrix` para calcular los verdaderos positivos y los verdaderos negativos y `ConfusionMatrixDisplay` para mostrar la matriz de confusión con las etiquetas.

labels = [0,1,2]
cm = confusion_matrix(y_test, y_pred, labels=labels)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels)
disp.plot();

Nuestro modelo ha funcionado bastante bien, y podemos mejorar el rendimiento del modelo mediante escalado, validaciones cruzadas de preprocesamiento y optimización de hiperparámetros. 

Clasificador Naive Bayes con conjunto de datos de préstamos

Vamos a entrenar el Clasificador Naive Bayes en el conjunto de datos real. Repetiremos la mayoría de las tareas, excepto el preprocesamiento y la exploración de datos. 

Carga de datos

En este ejemplo, cargaremos Loan Data del DataCamp Workspace utilizando la función de pandas 'read_csv`

import pandas as pd


df = pd.read_csv('loan_data.csv')
df.head()

Exploración de datos

Para saber más sobre el conjunto de datos utilizaremos `.info()`.

  • El conjunto de datos consta de 14 columnas y 9578 filas.
  • Aparte de "purpose", las columnas son floats o integers. 
  • Nuestra columna objetivo es "not.fully.paid". 
df.info()
RangeIndex: 9578 entries, 0 to 9577
Data columns (total 14 columns):
#   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
0   credit.policy      9578 non-null   int64 
1   purpose            9578 non-null   object
2   int.rate           9578 non-null   float64
3   installment        9578 non-null   float64
4   log.annual.inc     9578 non-null   float64
5   dti                9578 non-null   float64
6   fico               9578 non-null   int64 
7   days.with.cr.line  9578 non-null   float64
8   revol.bal          9578 non-null   int64 
9   revol.util         9578 non-null   float64
10  inq.last.6mths     9578 non-null   int64 
11  delinq.2yrs        9578 non-null   int64 
12  pub.rec            9578 non-null   int64 
13  not.fully.paid     9578 non-null   int64 
dtypes: float64(6), int64(7), object(1)
memory usage: 1.0+ MB

En este ejemplo, desarrollaremos un modelo para predecir los clientes que no han pagado totalmente el préstamo. Exploremos el propósito y la columna objetivo utilizando el countplot de seaborn. 

import seaborn as sns
import matplotlib.pyplot as plt

sns.countplot(data=df,x='purpose',hue='not.fully.paid')
plt.xticks(rotation=45, ha='right');

Nuestro conjunto de datos presenta un desequilibrio que afectará al rendimiento del modelo. Puedes consultar el tutorial Volver a muestrear un conjunto de datos desequilibrado para obtener experiencia práctica en el manejo de conjuntos de datos desequilibrados.

Tratamiento de datos 

Ahora convertiremos la columna ‘purpose’ de categórica a entera utilizando la función de pandas `get_dummies`.

pre_df = pd.get_dummies(df,columns=['purpose'],drop_first=True)
pre_df.head()

Después, definiremos las variables característica (X) y objetivo (y), y dividiremos el conjunto de datos en conjuntos de entrenamiento y de prueba. 

from sklearn.model_selection import train_test_split

X = pre_df.drop('not.fully.paid', axis=1)
y = pre_df['not.fully.paid']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.33, random_state=125
)

Construcción de modelos y formación

La construcción y formación de modelos es bastante sencilla. Entrenaremos un modelo en un conjunto de datos de entrenamiento utilizando hiperparámetros por defecto. 

from sklearn.naive_bayes import GaussianNB

model = GaussianNB()

model.fit(X_train, y_train);

Evaluación del modelo

Utilizaremos la precisión y la puntuación f1 para determinar el rendimiento del modelo, y parece que el algoritmo gaussiano Naive Bayes ha funcionado bastante bien. 

from sklearn.metrics import (
    accuracy_score,
    confusion_matrix,
    ConfusionMatrixDisplay,
    f1_score,
    classification_report,
)

y_pred = model.predict(X_test)

accuray = accuracy_score(y_pred, y_test)
f1 = f1_score(y_pred, y_test, average="weighted")

print("Accuracy:", accuray)
print("F1 Score:", f1)
Accuracy: 0.8206263840556786
F1 Score: 0.8686606980013266

Debido a la naturaleza desequilibrada de los datos, podemos ver que la matriz de confusión cuenta una historia diferente. Sobre un objetivo minoritario: `not fully paid`, tenemos más errores de etiqueta. 

labels = ["Fully Paid", "Not fully Paid"]
cm = confusion_matrix(y_test, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels)
disp.plot();

Si tienes problemas durante el entrenamiento o la evaluación del modelo, puedes consultar el Tutorial de clasificación Naive Bayes utilizando el Workspace Scikit-learn. Incluye un conjunto de datos, el código fuente y los resultados. 

Problema de probabilidad cero

Supongamos que no hay ninguna tupla para un préstamo de riesgo en el conjunto de datos; en este caso, la probabilidad posterior será cero, y el modelo no podrá hacer una predicción. Este problema se conoce como Probabilidad Cero, porque la ocurrencia de la clase concreta es cero.

La solución para este problema es la corrección laplaciana o Transformación de Laplace. La corrección laplaciana es una de las técnicas de suavizado. Aquí, puedes suponer que el conjunto de datos es lo suficientemente grande como para que añadir una fila de cada clase no suponga una diferencia en la probabilidad estimada. Así se superará el problema de los valores de probabilidad a cero.

Por ejemplo: Supongamos que para la clase préstamo arriesgado, hay 1000 tuplas de entrenamiento en la base de datos. En esta base de datos, la columna ingresos tiene 0 tuplas para ingresos bajos, 990 tuplas para ingresos medios y 10 tuplas para ingresos altos. Las probabilidades de estos sucesos, sin la corrección laplaciana, son 0, 0,990 (de 990/1000) y 0,010 (de 10/1000)

Ahora, aplica la corrección laplaciana al conjunto de datos dado. Añadamos 1 tupla más por cada par ingresos-valores. Las probabilidades de estos acontecimientos:

Ventajas

  • No sólo es un planteamiento sencillo, sino también un método de predicción rápido y preciso.
  • Naive Bayes tiene un coste de cálculo muy bajo.
  • Puede trabajar eficazmente con un gran conjunto de datos.
  • Funciona bien en caso de variable de respuesta discreta en comparación con la variable continua.
  • Se puede utilizar con problemas de predicción de clases múltiples.
  • También funciona bien en el caso de los problemas de análisis de texto.
  • Cuando se cumple el supuesto de independencia, un clasificador Naive Bayes obtiene mejores resultados que otros modelos como la regresión logística.

Desventajas

  • La suposición de características independientes. En la práctica, es casi imposible que el modelo obtenga un conjunto de predictores totalmente independientes.
  • Si no hay ninguna tupla de entrenamiento de una clase concreta, la probabilidad posterior es cero. En este caso, el modelo es incapaz de hacer predicciones. Este problema se conoce como Problema de la Frecuencia/Probabilidad Cero.

Conclusión

Enhorabuena, ¡has llegado al final de este tutorial!

En este tutorial, has aprendido sobre el algoritmo Naive Bayes, su funcionamiento, el supuesto de Naive Bayes, problemas, implementación, ventajas y desventajas. Por el camino, también has aprendido la construcción y evaluación de modelos en scikit-learn para clases binarias y multinomiales.

Naive Bayes es el algoritmo más sencillo y potente. A pesar de los importantes avances del machine learning en los últimos dos años, ha demostrado su valía. Se ha implantado con éxito en muchas aplicaciones, desde análisis de texto hasta motores de recomendación.

Si quieres aprender más sobre scikit-learn en Python, sigue nuestro curso Aprendizaje supervisado con scikit-learn y consulta nuestro tutorial Tutorial Scikit-Learn: análisis de béisbol Pt 1.

Temas

Cursos de Python

curso

Introduction to Python

4 hr
5.6M
Master the basics of data analysis with Python in just four hours. This online course will introduce the Python interface and explore popular packages.
Ver detallesRight Arrow
Comienza El Curso
Ver másRight Arrow
Relacionado

tutorial

Tutorial de Clasificación en Árbol de Decisión en Python

En este tutorial, aprenderás Clasificación en Árbol de Decisión, medidas de selección de atributos y cómo construir y optimizar el Clasificador en Árbol de Decisión utilizando el paquete Python Scikit-learn.
Avinash Navlani's photo

Avinash Navlani

12 min

tutorial

Introducción a k-Means Clustering con scikit-learn en Python

En este tutorial, aprenda a aplicar k-Means Clustering con scikit-learn en Python

Kevin Babitz

21 min

tutorial

Aprendizaje automático de datos categóricos con el tutorial de Python

Aprenda los trucos más comunes para manejar datos categóricos y preprocesarlos para construir modelos de aprendizaje automático.
Moez Ali's photo

Moez Ali

28 min

tutorial

Clasificación de bosques aleatorios con Scikit-Learn

Este artículo trata de cómo y cuándo utilizar la clasificación Random Forest con scikit-learn. Centrado en conceptos, flujo de trabajo y ejemplos. También veremos cómo utilizar la matriz de confusión y las importancias de las características.
Adam Shafi's photo

Adam Shafi

14 min

tutorial

Tutorial sobre el uso de XGBoost en Python

Descubre la potencia de XGBoost, uno de los marcos de machine learning más populares entre los científicos de datos, con este tutorial paso a paso en Python.
Bekhruz Tuychiev's photo

Bekhruz Tuychiev

16 min

tutorial

Tutorial de análisis NLTK del sentimiento para principiantes

Tutorial de análisis del sentimiento NLTK (natural language toolkit) de Python. Aprende a crear y desarrollar análisis del sentimiento utilizando Python. Sigue pasos específicos para extraer y analizar texto para el procesamiento del lenguaje natural.
Moez Ali's photo

Moez Ali

13 min

See MoreSee More