OpenNLP doccat 培训师总是导致“1 个结果模式”

OpenNLP doccat trainer always results in "1 outcome patterns"

我正在评估 OpenNLP 是否用作文档分类器。我有一个经过净化的训练语料库,其中包含大约 4k 个文件,大约有 150 个类别。这些文档有许多共享的、大部分不相关的词——但其中许多词在 n-gram 中变得相关,所以我使用以下参数:

        TrainingParameters params = new TrainingParameters();
        params.put(TrainingParameters.ITERATIONS_PARAM, 20000);
        params.put(TrainingParameters.CUTOFF_PARAM, 10);
        DoccatFactory dcFactory = new DoccatFactory(new FeatureGenerator[] { new NGramFeatureGenerator(3, 10) });
        params.put(AbstractTrainer.ALGORITHM_PARAM, NaiveBayesTrainer.NAIVE_BAYES_VALUE);

其中一些类别适用于几乎完全相同的文档(想想样板法律文档,文档实例之间可能只有名称和地址不同)- 并且与测试集中的文档大部分相同。但是,无论我如何调整这些参数,我都无法摆脱“1 结果模式”的结果。当 运行 测试时,测试集中的每个文档都被标记为“类别 A”。

我确实设法实现了输出中的一个小变化,从之前使用的 BagOfWordsFeatureGenerator 转移到 NGramFeatureGenerator,从 maxent 转移到朴素贝叶斯;更改前,测试集中的每个文档都被分配为“A 类”,但更改后,所有文档现在都被分配为“B 类”。但除此之外,我似乎根本无法移动表盘。

我试过摆弄迭代、截止、ngram 大小、使用 maxent 而不是贝叶斯等;但都无济于事。

我在网上找到的教程示例代码使用了更小的训练集和更少的迭代,并且至少能够执行一些基本的微分。

通常在这种情况下——令人困惑的缺乏预期的行为——工程师忘记了按下一些简单的开关,或者严重缺乏基本的理解。我非常有能力应对这两种失败。此外,我没有接受过数据科学培训,尽管我读过几本关于该主题的 O'Reilly 书籍。所以问题可能是程序性的。训练集是不是太小了?迭代次数是否相差一个数量级?不同的算法会更合适吗?我非常惊讶没有任何调整甚至稍微将表盘从“1 个结果”结果移开。

感谢任何回复。

好吧,这个问题的答案不是来自提问的方向。事实证明,OpenNLP 文档中有一个代码示例是错误的,再多的参数调整也无法解决它。我已经向该项目提交了一个 jira,因此它应该得到解决;但对于那些在那之前来到这里的人来说,这里是 运行down:

文档(错误):

String inputText = ...
DocumentCategorizerME myCategorizer = new DocumentCategorizerME(m);
double[] outcomes = myCategorizer.categorize(inputText);
String category = myCategorizer.getBestCategory(outcomes);

应该是这样的:

String inputText = ... // sanitized document to be classified
DocumentCategorizerME myCategorizer = new DocumentCategorizerME(m);
double[] outcomes = myCategorizer.categorize(inputText.split(" "));
String category = myCategorizer.getBestCategory(outcomes);

DocumentCategorizerME.categorize() 需要一个数组;因为这是一个明显的 self-documenting 错误,第二个你 运行 代码,我假设必要的数组参数应该是字符串形式的文档数组;相反,它需要 来自单个文档的标记数组。