斯坦福命名实体识别(NER)系统是否可以被训练来识别更多类型的命名实体?

28

我现在正在使用一些自然语言处理库,包括Stanford和nltk。我看了Stanford的演示部分,但我想问一下是否有可能使用它识别更多类型的实体。

目前,Stanford NER系统(如演示所示)可以将实体识别为人(姓名)、组织或位置。但识别的组织仅限于大学或某些大型组织。我想知道是否可以使用其API编写更多类型实体的程序,例如如果我的输入是“苹果”或“广场”,它就能将其识别为公司。

我需要制作自己的训练数据集吗?

此外,如果我想提取实体及其之间的关系,我觉得我应该使用Stanford依赖解析器。也就是说,首先提取命名实体和其他标记为“名词”的部分,并找到它们之间的关系。

我的理解正确吗?

谢谢。

3个回答

13

是的,你需要自己的训练数据集。预先训练好的斯坦福模型只能识别“斯坦福”这个命名实体,因为它们是通过标记了该词语(或根据特征集使用非常相似的词语,我不知道是什么)作为命名实体的数据进行训练的。

一旦你拥有更多的数据,你需要按照这个问题和斯坦福教程中描述的正确格式放置数据。


1
谢谢。那么,在我训练好识别命名实体之后,是否可以提取它们呢?比如,“Microsoft的产品”,我能否将“Microsoft”识别为一个组织,而“产品”则是另一件事,并将它们结合在一起呢? - JudyJiang
你知道预训练模型是否可以用额外的示例进行训练吗? - bones.felipe
根据常见问题解答,你无法实现。https://nlp.stanford.edu/software/crf-faq.shtml#extend - JamesFrost
预先训练的斯坦福模型只能识别单词 "斯坦福" 吗? :-) - matanster

10

您可以轻松地训练自己的数据语料库。

在斯坦福实体识别器(NER)FAQ中,第一个问题是如何为NER训练我们自己的模型。

链接是http://nlp.stanford.edu/software/crf-faq.shtml

例如,您可以提供像这样的训练数据

产品 OBJ
的 O
微软 ORG

同样,您可以构建自己的训练数据集并创建模型,然后使用它来获得所需的输出。


6

看起来您想训练自己的 NER 模型。

以下是一份详细的教程,包含完整的代码:

https://dataturks.com/blog/stanford-core-nlp-ner-training-java-example.php?s=so

训练数据格式

训练数据以文本文件形式传递,其中每一行都是一个单词-标签对。每行中的单词应以“word\tLABEL”格式进行标记,单词和标签名称之间用制表符“\t”隔开。对于文本句子,我们应该将其分解为单词,并在训练文件中为每个单词添加一行。为了标记下一行的开始,我们在训练文件中添加一个空行。

以下是输入训练文件的示例:

hp  Brand
spectre ModelName
x360    ModelName

home    Category
theater Category
system  0

horizon ModelName
zero    ModelName
dawn    ModelName
ps4 0

根据您的领域,可以自动或手动构建这样的数据集。手动构建这样的数据集可能会非常痛苦,使用命名实体识别 (NER) 注释工具等工具可以帮助简化该过程。
训练模型。
public void trainAndWrite(String modelOutPath, String prop, String trainingFilepath) {
   Properties props = StringUtils.propFileToProperties(prop);
   props.setProperty("serializeTo", modelOutPath);

   //if input use that, else use from properties file.
   if (trainingFilepath != null) {
       props.setProperty("trainFile", trainingFilepath);
   }

   SeqClassifierFlags flags = new SeqClassifierFlags(props);
   CRFClassifier<CoreLabel> crf = new CRFClassifier<>(flags);
   crf.train();

   crf.serializeClassifier(modelOutPath);
}

使用模型生成标签:
public void doTagging(CRFClassifier model, String input) {
    input = input.trim();
    System.out.println(input + "=>"  +  model.classifyToString(input));
}  

希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接