如何使自定义RelationshipExtractor了解自定义实体?

时间:2016-01-21 11:18:30

标签: stanford-nlp

我为我的项目创建了一个新的NER,我在其中确定了其他单词和BusinessTerms。我合并了斯坦福提供的NER以及我创建的NER,然后获得了句子集的NER。然后我将这些句子转换成一种可以被RelationshipExtraction classifer理解的形式,如下所示:

5   O   0   O   DT  The O   O   O
5   O   1   O   NNP Balanced    O   O   O
5   BusinessTerm    2   O   NN  option  O   O   O
5   O   3   O   VBZ s   O   O   O
5   BusinessTerm    4   O   NN  return  O   O   O
5   O   5   O   IN  of  O   O   O
5   PERCENT 6   O   CD  13.88   O   O   O
5   PERCENT 7   O   NN  %   O   O   O
5   O   8   O   IN  for O   O   O
5   O   9   O   DT  the O   O   O
5   O   10  O   NN  year    O   O   O
5   O   11  O   TO  to  O   O   O
5   O   12  O   CD  30  O   O   O
5   DATE    13  O   NNP June    O   O   O
5   DATE    14  O   CD  2014    O   O   O
5   O   15  O   VBD was O   O   O
5   O   16  O   RB  well    O   O   O
5   O   17  O   RB  ahead   O   O   O
5   O   18  O   IN  of  O   O   O
5   O   19  O   DT  the O   O   O
5   O   20  O   JJ  median  O   O   O
5   BusinessTerm    21  O   NN  fund    O   O   O
5   O   22  O   ,   ,   O   O   O
5   O   23  O   WDT which   O   O   O
5   O   24  O   VBZ is  O   O   O
5   O   25  O   JJ  great   O   O   O
5   O   26  O   NN  news    O   O   O
5   O   27  O   .   .   O   O   O

现在,当我将此作为输入来创建关系提取分类器时,它会抛出一个异常

"Cannot normalize ner tag BusinessTerm."

我想我错过了这个过程的一些步骤。

如何让RelationshipExtraction classifer理解我的自定义NER分类器创建的这些术语(在RelationshipExtraction分类过程中)?

2 个答案:

答案 0 :(得分:2)

要解决此问题,您需要调整类getNormalizedNERTag中的方法edu.stanford.nlp.ie.machinereading.domains.roth.RothCONLL04Reader

例如:我需要添加3个新类(概念,实体和纸张),所以我在这个方法中添加了如下内容:

private static String getNormalizedNERTag(String ner){
  if(ner.equalsIgnoreCase("O"))
    return "O";
  else if(ner.equalsIgnoreCase("Peop"))
    return "PERSON";
  else if(ner.equalsIgnoreCase("Loc"))
    return "LOCATION";
  else if(ner.equalsIgnoreCase("Org"))
    return "ORGANIZATION";
  else if(ner.equalsIgnoreCase("Other"))
    return "OTHER";
  else if(ner.equalsIgnoreCase("Concept"))
    return "CONCEPT";
  else if(ner.equalsIgnoreCase("Entity"))
    return "ENTITY";
  else if(ner.equalsIgnoreCase("Paper"))
    return "PAPER";
  throw new RuntimeException("Cannot normalize ner tag " + ner);
}

一旦这样做,您需要从源代码重新编译CoreNLP。为此,请安装ant,然后将包含源代码的目录重命名为src。进入CoreNLP文件夹(build.xml文件和src目录所在的文件夹)并运行ant

可在此处找到更多说明:https://github.com/stanfordnlp/CoreNLP/wiki/Compilation-Instructions

在此之后,只需将类打包成jar,然后使用自己的类运行编译版本。

我不确定为什么这些类是硬编码的!如果有人有任何提示,请告知。

谢谢!

答案 1 :(得分:2)

对于那些不想从源代码重新编译默认CoreNLP的人。您可以简单地创建自己的类并从那里实现它。样本如下:

$destroy()

请记住在属性文件(roth.properties)中更改属性datasetReaderClass。

  

datasetReaderClass = test.TestReader