Naps Tecnología y educación

Naive Bayes en Python: Ejemplo explicado

En éste artículo se desarrolla un clasificador Naive Bayes en Python, al que, una vez entrenado, podemos pasarle un titular de noticias y deducirá a qué categoría (ocio, tecnología, cultura) pertenece la noticia.

Los clasificadores Naive Bayes son ampliamente usados en machine learning debido a su eficiencia y capacidad para analizar datos con una gran cantidad de características (Manning, 1999).

A continuación crearemos un modelo que utilice Naive Bayes en Python para aprender a clasificar noticias. Se le proporciona un dataset con noticias ya clasificadas en tres categorías: ocio, tecnología y cultura.

Realizaremos éste modelo en tres pasos: 1) obtención de datos, filtrado y vectorización. 2) Implementar un transformador, para convertir a array los datos. 3) Crear el modelo de clasificador Naive Bayes en Python con distribución Gaussiana y guardarlo en formato Pickle para su posterior uso.

Teniendo ya nuestro modelo entrenado podremos hacer pruebas con cualquier noticia.

Naive Bayes en Python: Paso 1.

Obtención de datos, filtrado y vectorización

Vamos a utilizar un dataset disponible en: https://drive.google.com/file/d/1v8VgIp5Dbhz0f_-aPfA4DELz7ru1LwQI/view?usp=sharing

Consiste en noticias clasificadas que nos servirán para entrenar nuestro modelo.

También vamos a utilizar un listado de palabras que deseamos eliminar pues aportan poco o ningún significado a la interpretación de las noticias. Esas palabras, conocidas como stop-words, están disponibles en el siguiente archivo:

https://drive.google.com/file/d/1bL46-MfwN0nKqfL8fRNqQ-aAjqYCuz5a/view?usp=sharing

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
import json

noticias = pd.read_csv("noticias.csv")

# Eliminar stopwords: palabras cuyo contenido no es muy relevante
with open("stopwords-es.json") as fname:
    stopwords_es = json.load(fname)

# Debido a que trabajamos con texto, tenemos que vectorizar, usaremos Tf-idf
vectorizador = 	TfidfVectorizer(stop_words=stopwords_es, max_features=50000)

# La transformamos en una matriz dispersa
vectorizador.fit_transform(noticias.descripcion)

Explicación: Utilizamos pandas para la obtención de datos, y json para cargar las stopwords. Se crea un vectorizador utilizando un algoritmo Tfidf. Posteriormente se le pasa al vectorizador los datos con los que deseamos trabajar. Ésto nos creará una matriz dispersa. Según la cantidad escrita en max_features es la cantidad de palabras que puede registrar lo que repercute en el tiempo de procesamiento.

Naive Bayes en Python: Paso 2.

Convertir una matriz dispersa en array

Creamos una clase DenseTransformer, que nos permite convertir una matriz dispersa en un array.

from sklearn.base import BaseEstimator
from scipy.sparse import issparse

# http://rasbt.github.io/mlxtend/
class DenseTransformer(BaseEstimator):
    def __init__(self, return_copy=True):
        self.return_copy = return_copy
        self.is_fitted = False

    def transform(self, X, y=None):
        if issparse(X):
            return X.toarray()
        elif self.return_copy:
            return X.copy()
        else:
            return X

    def fit(self, X, y=None):
        self.is_fitted = True
        return self

    def fit_transform(self, X, y=None):
        return self.transform(X=X, y=y)

Naive Bayes en Python: Paso 3.

Crear un pipeline que utilice los pasos anteriores, e incluya un clasificador Naive Bayes con distribución Gaussiana.

# Importamos el clasificador naive bayes, este tiene tres distribuciones Gausiano, Bernoulli, Multinomial
from sklearn.naive_bayes import GaussianNB
# Un pipeline es un conjunto de tuberias o flujos que parten de una entrada (datos) 
# hacia una salida (modelo)
from sklearn.pipeline import make_pipeline
pipeline_gaussiano = make_pipeline(
    vectorizador,
    DenseTransformer(),
    GaussianNB()
)
pipeline_gaussiano.fit(X=noticias.descripcion, y=noticias.categoria)
import pickle
pickle.dump(pipeline_gaussiano, open("naive_noticias_model.pickle", "wb"))
print ("Modelo Creado")

Explicación: En éste paso se crea un pipeline. Lo primero que recibe es el vectorizador que contiene una matriz dispersa que representa cada palabra asignada a cada noticia. Ésta matriz es pasada a DenseTransformer que la convierte a un array. Éste array es pasado a GaussianNB con lo que se crea un clasificador Naive Bayes. Se ajusta el modelo pasando como X (dato de entrada) la descripción de la noticia, y como y (dato de salida) la categoría. Utilizando pickle se guarda el modelo en un archivo que se puede utilizar más adelante. Éste proceso puede tardar varios minutos.

Uso del modelo creado

Una vez creado nuestro modelo, podemos utilizarlo para clasificar una o miles de noticias.

import pickle
from sklearn.base import BaseEstimator
from scipy.sparse import issparse


class DenseTransformer(BaseEstimator):
    def __init__(self, return_copy=True):
        self.return_copy = return_copy
        self.is_fitted = False

    def transform(self, X, y=None):
        if issparse(X):
            return X.toarray()
        elif self.return_copy:
            return X.copy()
        else:
            return X

    def fit(self, X, y=None):
        self.is_fitted = True
        return self

    def fit_transform(self, X, y=None):
        return self.transform(X=X, y=y)


pipeline_gaussiano = pickle.load(open("naive_noticias_model.pickle", "rb"))

n1 = ["¿Cansado de que te roben Internet? Aqui puedes darte cuenta de quienes tienen tu wifi"]
n2 = ["Los cineastas mexicanos se unen para crear un fondo de emergencia ante la contingencia sanitaria"]
n3 = ["10 películas y series de terror en Netflix para ver este fin de semana"]
r1=pipeline_gaussiano.predict(n1)
r2=pipeline_gaussiano.predict(n2)
r3=pipeline_gaussiano.predict(n3)
print ("=====================")
print ("Noticia: " + str(n1))
print ("Categoría probable: " + str(r1))
print ("Noticia: " + str(n2))
print ("Categoría probable: " + str(r2))
print ("Noticia: " + str(n3))
print ("Categoría probable: " + str(r3))

Lo probamos cargando el modelo creado en archivo pickle y dandole una noticia. El resultado es la categoría en la que el clasificador pone a la noticia que introducimos.

Referencias:

1. Manning (1999). Foundations of Statistical Natural Language Processing. 

Te puede servir:

¿Qué te pareció este artículo?
  • Regular ()
  • Interesante ()
  • Poco informativo ()
  • No era lo que buscaba ()
  • Excelente ()
(Visto 9.826 veces)

Tu comentario

opiniones