在 JAVA PlatoBlockchain 数据智能中开发朴素贝叶斯文本分类器。垂直搜索。人工智能。

在JAVA中开发Naive Bayes文本分类器

在先前的文章中,我们讨论了 朴素贝叶斯文本分类器 以及使用的重要性 特征选择技术 在文本分类中。 在本文中,我们将把所有内容放在一起,并在JAVA中构建Naive Bayes文本分类算法的简单实现。 分类器的代码是开源的(根据GPL v3许可),您可以从以下位置下载 Github上.

更新:Datumbox机器学习框架现在是开源的,免费提供给 下载。 检出com.datumbox.framework.machinelearning.classification包,以查看Naive Bayes分类器在Java中的实现。

朴素贝叶斯Java实现

该代码是用JAVA编写的,可以直接从以下位置下载 Github上。 它已获得GPLv3许可,因此可以随意使用,修改和自由分发。

文本分类器实现了 多项式朴素贝叶斯 模型以及 Chisquare特征选择 算法。 先前的文章中介绍了这两种技术如何工作的所有理论细节,有关Javadoc的详细注释可以在描述实现的源代码中找到。 因此,在这一部分中,我将重点介绍分类器的体系结构。

1. NaiveBayes类

这是文本分类器的主要部分。 它实现了诸如train()和predict()之类的方法,这些方法负责训练分类器并将其用于预测。 应该注意的是,该类还负责在训练/预测之前调用适当的外部方法对文档进行预处理和标记化。

2. NaiveBayesKnowledgeBase对象

训练的输出是NaiveBayesKnowledgeBase对象,该对象存储Naive Bayes分类器使用的所有必要信息和概率。

3.文件对象

实施中的训练文本和预测文本都在内部存储为文档对象。 文档对象存储文档的所有标记(单词),它们的统计信息和文档的目标分类。

4. FeatureStats对象

FeatureStats对象存储在特征提取阶段生成的若干统计信息。 这样的统计数据包括特征和类别的联合计数(从中估计联合概率和似然),类别计数(如果没有输入先验则从中进行评估)和用于训练的观察总数。

5. FeatureExtraction类

这是负责执行特征提取的类。 应该注意的是,由于此类在内部计算了分类算法在稍后阶段实际需要的一些统计信息,因此所有这些统计信息都会被缓存并返回到FeatureStats对象中,以避免重新计算它们。

6. TextTokenizer类

这是一个 简单 文本标记化类,负责预处理,清除和标记化原始文本并将其转换为Document对象。

使用NaiveBayes JAVA类

在NaiveBayesExample类中,您可以找到使用NaiveBayes类的示例。 示例代码的目标是提供一个示例,该示例训练一个简单的朴素贝叶斯分类器以检测文本的语言。 为了训练分类器,首先我们在HashMap中提供训练数据集的路径,然后加载它们的内容。

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

通过将数据传递给NaiveBayes分类器来对其进行训练。 训练完成后,将保存NaiveBayesKnowledgeBase对象以供以后使用。

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

最后,要使用分类器并预测新示例的类,您需要做的就是通过传递您先前通过培训获得的NaiveBayesKnowledgeBase Object来初始化新的分类器。 然后,通过简单地调用predict()方法,您可以获得文档的预测类。

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

必要的扩展

对于复杂的文本分类问题,不应将特定的JAVA实现视为完整的即用型解决方案。 以下是一些可以完成的重要扩展:

1.关键字提取:

即使使用单个关键字就足以解决诸如语言检测之类的简单问题,但其他更复杂的问题则需要提取n-gram。 因此,可以通过更新TextTokenizer.extractKeywords()方法来实现更复杂的文本提取算法,也可以使用Datumbox的 关键字提取API 函数获取文档的所有n-gram(关键字组合)。

2.文本预处理:

通常,在使用分类器之前,有必要对文档进行预处理,以删除不必要的字符/部分。 即使当前的实现通过使用TextTokenizer.preprocess()方法执行有限的预处理,但是在分析HTML页面时,事情仍然变得棘手。 您可以简单地修剪HTML标记,仅保留文档的纯文本,或者诉诸更复杂的机器学习技术,这些技术可以检测页面的主要文本并删除属于页脚,页眉,菜单等的内容。可以使用Datumbox的 文字提取API 功能。

3.其他朴素贝叶斯模型:

不过,正如我们在上一篇文章中讨论的那样,当前分类器实现了多项朴素贝叶斯分类器 情感分析,不同的分类问题需要不同的模型。 在某些情况下,该算法的二进制化版本会更合适,而在其他情况下,Bernoulli模型会提供更好的结果。 使用此实现作为起点,并按照 朴素贝叶斯教程 扩展模型。

4.其他功能选择方法:

此实现使用Chisquare特征选择算法为分类选择最合适的特征。 正如我们在上一篇文章中看到的 Chisquare功能选择 该方法是一种很好的技术,它可以根据统计数据来选择合适的特征,但是,对于仅出现在其中一个类别中的稀有特征,它往往会给出更高的分数。 在进行特征选择之前,或者通过实施其他方法(例如我们在上述文章中讨论的互信息),可以对消除嘈杂/稀有特征进行改进。

5.性能优化:

在特定的实现中,重要的是提高代码的可读性,而不是对代码进行微优化。 尽管这样的优化使代码更丑陋并且更难以阅读/维护,但由于在训练和测试过程中该算法中的许多循环执行了数百万次,因此它们经常是必需的。 此实现可能是开发自己的调整版本的一个很好的起点。

快到了……最后的笔记!

我听说他擅长编码l为了更好地了解此实现的工作原理,强烈建议您阅读前两篇有关 朴素贝叶斯分类器功能选择。 您将获得有关这些方法的理论背景的见解,并将使算法/代码的各个部分变得更加清晰。

我们应该注意的是,朴素贝叶斯尽管简单,快速并且在大多数情况下“相当准确”,但它也是“朴素”的,因为它假定了条件的条件独立性。 由于在文本分类问题中几乎从未满足过这种假设,因此朴素贝叶斯几乎从来不是性能最好的分类器。 在 数据框API,标准Naive Bayes分类器的某些扩展仅用于诸如语言检测之类的简单问题。 对于更复杂的文本分类问题,可以使用更高级的技术,例如 最大熵分类器 是必要的。

如果您在有趣的项目中使用实现 我们写信 我们将在我们的博客上介绍您的项目。 另外,如果您喜欢这篇文章,请花一点时间在Twitter或Facebook上分享。 🙂

时间戳记:

更多来自 基准框