Desarrollo de un clasificador de texto Naive Bayes en JAVA PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Desarrollo de un clasificador de texto Bayes ingenuo en JAVA

En artículos anteriores hemos discutido los antecedentes teóricos de Clasificador de texto Bayes ingenuo y la importancia de usar Técnicas de selección de características en la clasificación de texto. En este artículo, vamos a armar todo y construir una implementación simple del algoritmo de clasificación de texto Naive Bayes en JAVA. El código del clasificador es de código abierto (bajo licencia GPL v3) y puede descargarlo desde Github.

Actualización: el marco de aprendizaje automático de Datumbox ahora es de código abierto y gratuito para descargar. Consulte el paquete com.datumbox.framework.machinelearning.classification para ver la implementación de Naive Bayes Classifier en Java.

Implementación Java Naive Bayes

El código está escrito en JAVA y se puede descargar directamente desde Github. Está licenciado bajo GPLv3, así que siéntase libre de usarlo, modificarlo y redistribuirlo libremente.

El clasificador de texto implementa el Bayes ingenuos multinomiales modelo junto con el Selección de características chisquare algoritmo. Todos los detalles teóricos de cómo funcionan ambas técnicas están cubiertos en artículos anteriores y los comentarios detallados de javadoc se pueden encontrar en el código fuente que describe la implementación. Por lo tanto, en este segmento me centraré en una descripción de alto nivel de la arquitectura del clasificador.

1. Clase NaiveBayes

Esta es la parte principal del clasificador de texto. Implementa métodos como train () y predic () que son responsables de entrenar a un clasificador y usarlo para las predicciones. Cabe señalar que esta clase también es responsable de llamar a los métodos externos apropiados para preprocesar y tokenizar el documento antes del entrenamiento / predicción.

2. Objeto NaiveBayesKnowledgeBase

El resultado de la capacitación es un objeto NaiveBayesKnowledgeBase que almacena toda la información necesaria y las probabilidades que utiliza el clasificador Naive Bayes.

3. Objeto del documento

Tanto la capacitación como los textos de predicción en la implementación se almacenan internamente como objetos de documento. El objeto de documento almacena todos los tokens (palabras) del documento, sus estadísticas y la clasificación de destino del documento.

4. Objeto FeatureStats

El objeto FeatureStats almacena varias estadísticas que se generan durante la fase de extracción de características. Dichas estadísticas son los recuentos conjuntos de características y clase (a partir de los cuales se estiman las probabilidades y probabilidades conjuntas), los recuentos de clase (a partir de los cuales se evalúan los anteriores si no se da ninguno como entrada) y el número total de observaciones utilizadas para el entrenamiento.

5. Clase de extracción de características

Esta es la clase responsable de realizar la extracción de características. Cabe señalar que, dado que esta clase calcula internamente varias de las estadísticas que realmente requiere el algoritmo de clasificación en la etapa posterior, todas estas estadísticas se almacenan en caché y se devuelven en un objeto FeatureStats para evitar su recálculo.

6. Clase TextTokenizer

Esto es una simples clase de tokenización de texto, responsable de preprocesar, borrar y tokenizar los textos originales y convertirlos en objetos de documento.

Usando la clase NaiveBayes JAVA

En la clase NaiveBayesExample puede encontrar ejemplos del uso de la clase NaiveBayes. El objetivo del código de muestra es presentar un ejemplo que entrena un simple clasificador Naive Bayes para detectar el idioma de un texto. Para entrenar al clasificador, inicialmente proporcionamos las rutas de los conjuntos de datos de entrenamiento en un HashMap y luego cargamos sus contenidos.

   //map of dataset files
   Map<String, URL> trainingFiles = new HashMap<>();
   trainingFiles.put("English", NaiveBayesExample.class.getResource("/datasets/training.language.en.txt"));
   trainingFiles.put("French", NaiveBayesExample.class.getResource("/datasets/training.language.fr.txt"));
   trainingFiles.put("German", NaiveBayesExample.class.getResource("/datasets/training.language.de.txt"));

   //loading examples in memory
   Map<String, String[]> trainingExamples = new HashMap<>();
   for(Map.Entry<String, URL> entry : trainingFiles.entrySet()) {
      trainingExamples.put(entry.getKey(), readLines(entry.getValue()));
   }

El clasificador NaiveBayes se entrena pasándole los datos. Una vez que se completa la capacitación, el objeto NaiveBayesKnowledgeBase se almacena para su uso posterior.

   //train classifier
   NaiveBayes nb = new NaiveBayes();
   nb.setChisquareCriticalValue(6.63); //0.01 pvalue
   nb.train(trainingExamples);
      
   //get trained classifier
   NaiveBayesKnowledgeBase knowledgeBase = nb.getKnowledgeBase();

Finalmente, para usar el clasificador y predecir las clases de nuevos ejemplos, todo lo que necesita hacer es inicializar un nuevo clasificador pasando el objeto NaiveBayesKnowledgeBase que adquirió anteriormente mediante entrenamiento. Luego, al llamar simplemente al método predict (), obtienes la clase predicha del documento.

   //Test classifier
   nb = new NaiveBayes(knowledgeBase);
   String exampleEn = "I am English";
   String outputEn = nb.predict(exampleEn);
   System.out.format("The sentense "%s" was classified as "%s".%n", exampleEn, outputEn);   

Expansiones necesarias

La implementación particular de JAVA no debe considerarse una solución completa lista para usar para problemas sofisticados de clasificación de texto. Estas son algunas de las expansiones importantes que podrían hacerse:

1. Extracción de palabras clave:

Aunque el uso de palabras clave individuales puede ser suficiente para problemas simples como la detección de idioma, otros problemas más complicados requieren la extracción de n-gramos. Por lo tanto, uno puede implementar un algoritmo de extracción de texto más sofisticado actualizando el método TextTokenizer.extractKeywords () o usar Datumbox's API de extracción de palabras clave función para obtener todos los n-gramas (combinaciones de palabras clave) del documento.

2. Preprocesamiento de texto:

Antes de usar un clasificador, generalmente es necesario preprocesar el documento para eliminar caracteres / partes innecesarios. Aunque la implementación actual realiza un preprocesamiento limitado utilizando el método TextTokenizer.preprocess (), cuando se trata de analizar páginas HTML, las cosas se vuelven más complicadas. Simplemente puede recortar las etiquetas HTML y conservar solo el texto sin formato del documento o recurrir a técnicas de aprendizaje automático más sofisticadas que detecten el texto principal de la página y eliminen el contenido que pertenece al pie de página, encabezados, menús, etc. puede usar Datumbox's API de extracción de texto función.

3. Modelos adicionales ingenuos de Bayes:

El clasificador actual implementa el clasificador Multinomial Naive Bayes, sin embargo, como discutimos en un artículo anterior sobre Análisis de los sentimientos, diferentes problemas de clasificación requieren diferentes modelos. En algunos, una versión Binarizada del algoritmo sería más apropiada, mientras que en otros el Modelo de Bernoulli proporcionará resultados mucho mejores. Use esta implementación como punto de partida y siga las instrucciones de Tutorial ingenuo de Bayes para expandir el modelo.

4. Métodos de selección de características adicionales:

Esta implementación utiliza el algoritmo de selección de características Chisquare para seleccionar las características más apropiadas para la clasificación. Como vimos en un artículo anterior, el Selección de características chisquare El método es una buena técnica que se basa en estadísticas para seleccionar las características apropiadas, sin embargo, tiende a dar puntajes más altos en características raras que solo aparecen en una de las categorías. Se pueden realizar mejoras eliminando las características ruidosas / raras antes de proceder a la selección de características o mediante la implementación de métodos adicionales como la información mutua que discutimos en el artículo mencionado anteriormente.

5. Optimización del rendimiento:

En la implementación particular, era importante mejorar la legibilidad del código en lugar de realizar micro optimizaciones en el código. A pesar del hecho de que tales optimizaciones hacen que el código sea más feo y más difícil de leer / mantener, a menudo son necesarias ya que muchos bucles en este algoritmo se ejecutan millones de veces durante el entrenamiento y las pruebas. Esta implementación puede ser un excelente punto de partida para desarrollar su propia versión ajustada.

Casi allí ... ¡Notas finales!

Escuché que es bueno codificandoPara obtener una buena comprensión de cómo funciona esta implementación, le recomendamos encarecidamente que lea los dos artículos anteriores sobre Clasificador ingenuo de Bayes y Selección de características. Obtendrá información sobre los antecedentes teóricos de los métodos y aclarará partes del algoritmo / código.

Debemos tener en cuenta que Naive Bayes, a pesar de ser un sistema fácil, rápido y la mayoría de las veces "bastante preciso", también es "ingenuo" porque supone la independencia condicional de las características. Dado que este supuesto casi nunca se cumple en los problemas de clasificación de texto, Naive Bayes casi nunca es el mejor clasificador. En API de Datumbox, algunas expansiones del clasificador Naive Bayes estándar se usan solo para problemas simples como la detección de idioma. Para problemas de clasificación de texto más complicados, técnicas más avanzadas como el Clasificador de máxima entropía son necesarios.

Si usas la implementación en un proyecto interesante nos deje caer una línea y presentaremos su proyecto en nuestro blog. Además, si te gusta el artículo, tómate un momento y compártelo en Twitter o Facebook. 🙂

Sello de tiempo:

Mas de Caja de datos