修复自定义 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 解决这个问题的方法。
- 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
我们有一个报告编写工具,我们正在尝试向其添加搜索功能。本质上,用户将能够输入问题并根据句子中的标准返回报告。我们尽量保持开放式,不需要特定的句子结构,这就是我们考虑尝试 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 解决这个问题的方法。
- 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