修复自定义 OpenNLP NER 模型

Fixing a custom OpenNLP NER model

我们有一个报告编写工具,我们正在尝试向其添加搜索功能。本质上,用户将能够输入问题并根据句子中的标准返回报告。我们尽量保持开放式,不需要特定的句子结构,这就是我们考虑尝试 OpenNLP NER 的原因。

例如:

"what was Arts attendance last quarter"

标记为:

what was <START:dept> Arts <END> <START:filter> attendance <END> last <START:calc> quarter <END>

我们已经尝试针对不同的部门、过滤器等提出许多不同的问题变体。我们仍然没有达到 15k,只有 14.6k,所以仍在努力实现这一目标。

就分析问题而言,这是它的开始:

InputStream tokenStream = getClass().getResourceAsStream("/en-token.bin"); //$NON-NLS
            TokenizerModel tokenModel = new TokenizerModel(tokenStream);
            Tokenizer tokenizer = new TokenizerME(tokenModel);
            for (String name : modelNames) {
                tokenizedQuestion = tokenizer.tokenize(question);

                String alteredQuestion = question;

                TokenNameFinderModel entityModel = new TokenNameFinderModel(getClass().getResourceAsStream(name));
                NameFinderME nameFinder = new NameFinderME(entityModel);
                Span[] nameSpans = nameFinder.find(tokenizedQuestion);
                for (Span span : nameSpans) {
                    if (span.getType().equals("dept")) { 
                        deptList.add(span);
                    } else if (span.getType().equals("filter")) { 
                        filterList.add(span);
                    } else if (span.getType().equals("calculation"){ 
                        calculationList.add(span);
                    }
                }

现在的问题是如果你输入 "what was Bugs Bunny last cartoon" 你得到 'Bugs' 作为部门,'Bunny' 作为过滤器,'cartoon' 作为计算。

我猜我们的训练问题彼此相似,现在假设 "what was" 后面的是一个部门。
1. 这是一个正确的假设吗?是否有更好的方法来训练这些模型?
2. 将每个实体分解成它自己的模型是最好的选择吗?
我确实尝试过这个并且有 105 个单元测试后来失败了所以,希望先尝试一些更简单的东西,哈哈。

此外,我在这里阅读了多个关于自定义 NER 模型的话题,但我发现的大部分内容是如何开始一个。还有一个关于多个实体模型如何不起作用的话题。我忘记了 post 在哪里我发现将 null 放入类型允许您在同一模型中标记多个类型并且它似乎工作得很好。

 tokenNameFinderModel = NameFinderME.train("en", null, sampleStream, TrainingParameters.defaultParams(), new TokenNameFinderFactory()); 
 tokenNameFinderModel.serialize(modelOut);

在此先感谢您的帮助!!

我们的最终目标是能够在我们分类的某些单词上训练一个模型,并且必须正确地对每个单词进行分类,而不管句子结构如何。在 OpenNLP 中,我们无法做到这一点。

I'm guessing our training questions are to similar to each other and now it's assuming whatever follows "what was" is a department.
1. Is that a correct assumption and is there a better way of training these models?

根据我的测试和结果,我得出的结论是,单词的顺序和模式起了一定作用。我没有任何文件来支持这一点。我也找不到任何可以用 OpenNLP 解决这个问题的方法。

  1. Is the best bet to break each entity into it's own model?

根据经验和测试,我认为尽可能多地分离模型是最好的训练方式。不幸的是,即使采用这种方法,我们仍然无法实现我们的目标。

最终我们完成了切换到 StanfordNLP NER 模型的工作。您仍然可以围绕领域特定语言进行自定义实现,并可以选择在属性文件中关闭排序:

usePrev=false
useNext=false
useDisjunctive=false
useSequences=false
usePrevSequences=false

StanfordNLP 中自定义 NER 的参考资料: Stanford CoreNLP: Training your own custom NER tagger