Desenvolvendo um classificador de texto Naive Bayes em JAVA PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Desenvolvendo um Classificador de Texto Naive Bayes em JAVA

Em artigos anteriores, discutimos a base teórica da Classificador de texto Naive Bayes e a importância de usar Técnicas de seleção de recursos na classificação de texto. Neste artigo, vamos colocar tudo junto e construir uma implementação simples do algoritmo de classificação de texto Naive Bayes em JAVA. O código do classificador é de código aberto (sob licença GPL v3) e você pode baixá-lo em Github.

Atualização: O Datumbox Machine Learning Framework agora é de código aberto e gratuito para download. Verifique o pacote com.datumbox.framework.machinelearning.classification para ver a implementação do Classificador Naive Bayes em Java.

Implementação Java Naive Bayes

O código é escrito em JAVA e pode ser baixado diretamente de Github. Ele é licenciado sob a GPLv3, então fique à vontade para usá-lo, modificá-lo e redistribuí-lo livremente.

O Text Classifier implementa o Multinomial Ingênuo Bayes modelo junto com o Seleção de recursos do Chisquare algoritmo. Todos os detalhes teóricos de como ambas as técnicas funcionam são cobertos em artigos anteriores e comentários detalhados do javadoc podem ser encontrados no código-fonte que descreve a implementação. Portanto, neste segmento, vou me concentrar em uma descrição de alto nível da arquitetura do classificador.

1. Classe NaiveBayes

Esta é a parte principal do Classificador de Texto. Ele implementa métodos como train () e predict (), que são responsáveis ​​por treinar um classificador e usá-lo para previsões. Deve-se observar que essa classe também é responsável por chamar os métodos externos apropriados para pré-processar e tokenizar o documento antes do treinamento / previsão.

2. Objeto NaiveBayesKnowledgeBase

A saída do treinamento é um objeto NaiveBayesKnowledgeBase que armazena todas as informações e probabilidades necessárias que são usadas pelo Classificador Naive Bayes.

3. Objeto do documento

Os textos de treinamento e de previsão na implementação são armazenados internamente como Objetos de Documento. O objeto de documento armazena todos os tokens (palavras) do documento, suas estatísticas e a classificação de destino do documento.

4. Objeto FeatureStats

O Objeto FeatureStats armazena várias estatísticas que são geradas durante a fase de Extração de Recurso. Essas estatísticas são as contagens conjuntas de características e classe (a partir das quais as probabilidades e probabilidades conjuntas são estimadas), as contagens de classe (a partir das quais as anteriores são avaliadas se nenhuma for fornecida como entrada) e o número total de observações usadas para o treinamento.

5. Classe FeatureExtraction

Esta é a classe responsável por realizar a extração de recursos. Deve-se observar que, como essa classe calcula internamente várias estatísticas que são realmente exigidas pelo algoritmo de classificação no estágio posterior, todas essas estatísticas são armazenadas em cache e retornadas em um objeto FeatureStats para evitar seu recálculo.

6. Classe TextTokenizer

Isto é um simples classe de tokenização de texto, responsável por pré-processar, limpar e tokenizar os textos originais e convertê-los em objetos de Documento.

Usando a classe JAVA NaiveBayes

Na classe NaiveBayesExample, você pode encontrar exemplos de como usar a classe NaiveBayes. O objetivo do código de amostra é apresentar um exemplo que treina um classificador Naive Bayes simples para detectar a linguagem de um texto. Para treinar o classificador, inicialmente fornecemos os caminhos dos conjuntos de dados de treinamento em um HashMap e depois carregamos seus conteúdos.

   //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()));
   }

O classificador NaiveBayes é treinado passando os dados para ele. Depois que o treinamento é concluído, o objeto NaiveBayesKnowledgeBase é armazenado para 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 o classificador e prever as classes de novos exemplos, tudo o que você precisa fazer é inicializar um novo classificador passando o objeto NaiveBayesKnowledgeBase que você adquiriu anteriormente por treinamento. Então, chamando simplesmente o método predict (), você obtém a classe prevista do 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);   

Expansões Necessárias

A implementação particular de JAVA não deve ser considerada uma solução completa pronta para uso para problemas sofisticados de classificação de texto. Aqui estão algumas das expansões importantes que podem ser feitas:

1. Extração de palavras-chave:

Embora o uso de palavras-chave únicas possa ser suficiente para problemas simples, como detecção de idioma, outros problemas mais complicados exigem a extração de n-gramas. Assim, pode-se implementar um algoritmo de extração de texto mais sofisticado atualizando o método TextTokenizer.extractKeywords () ou usar o Datumbox's API de extração de palavra-chave função para obter todos os n-gramas (combinações de palavras-chave) do documento.

2. Pré-processamento de texto:

Antes de usar um classificador geralmente é necessário pré-processar o documento para remover caracteres / partes desnecessários. Embora a implementação atual execute um pré-processamento limitado usando o método TextTokenizer.preprocess (), quando se trata de analisar páginas HTML, as coisas se tornam mais complicadas. Pode-se simplesmente cortar as tags HTML e manter apenas o texto simples do documento ou recorrer a técnicas de Aprendizado de Máquina mais sofisticadas que detectam o texto principal da página e removem o conteúdo que pertence ao rodapé, cabeçalhos, menus etc. pode usar Datumbox's API de extração de texto função.

3. Modelos Naive Bayes Adicionais:

O classificador atual implementa o classificador Multinomial Naive Bayes, no entanto, como discutimos em um artigo anterior sobre Análise de Sentimentos, problemas de classificação diferentes requerem modelos diferentes. Em alguns, uma versão binarizada do algoritmo seria mais apropriada, enquanto em outros o modelo de Bernoulli fornecerá resultados muito melhores. Use esta implementação como ponto de partida e siga as instruções do Tutorial Naive Bayes para expandir o modelo.

4. Métodos de seleção de recursos adicionais:

Esta implementação usa o algoritmo de seleção de recursos Chisquare para selecionar os recursos mais apropriados para a classificação. Como vimos em um artigo anterior, o Seleção de recursos do Chisquare O método é uma boa técnica que se baseia em estatísticas para selecionar as características apropriadas; no entanto, tende a dar pontuações mais altas em características raras que só aparecem em uma das categorias. Melhorias podem ser feitas removendo recursos ruidosos / raros antes de prosseguir para a seleção de recursos ou implementando métodos adicionais, como as Informações Mútuas que discutimos no artigo acima mencionado.

5. Otimização de desempenho:

Na implementação específica, era importante melhorar a legibilidade do código em vez de realizar micro-otimizações no código. Apesar do fato de que tais otimizações tornam o código mais feio e difícil de ler / manter, elas são freqüentemente necessárias, pois muitos loops neste algoritmo são executados milhões de vezes durante o treinamento e teste. Essa implementação pode ser um ótimo ponto de partida para desenvolver sua própria versão ajustada.

Quase lá ... Notas finais!

Eu-ouvi-ele-é-bom-em-codificação-lPara obter uma boa compreensão de como essa implementação funciona, é altamente recomendável ler os dois artigos anteriores sobre Classificador Naive Bayes e Seleção de Recursos. Você obterá insights sobre a base teórica dos métodos e tornará partes do algoritmo / código mais claras.

Devemos observar que o Naive Bayes apesar de ser um método fácil, rápido e na maioria das vezes “bastante preciso”, também é “Naive” porque faz a suposição de independência condicional dos recursos. Como essa suposição quase nunca é atendida em problemas de Classificação de Texto, o Naive Bayes quase nunca é o classificador de melhor desempenho. No API Datumbox, algumas expansões do classificador Naive Bayes padrão são usadas apenas para problemas simples, como detecção de linguagem. Para problemas de classificação de texto mais complicados, técnicas mais avançadas, como o Classificador de Entropia Máxima são necessários.

Se você usar a implementação em um projeto interessante -nos uma linha cair e apresentaremos seu projeto em nosso blog. Além disso, se você gostar do artigo, reserve um momento e compartilhe no Twitter ou Facebook. 🙂

Carimbo de hora:

Mais de Caixa de dados