【问题标题】:Stanford NLP named entities of more than one token斯坦福 NLP 命名了多个令牌的实体
【发布时间】:2016-11-16 18:26:29
【问题描述】:

我正在尝试使用斯坦福核心 NLP 进行命名实体识别。

一些命名实体包含多个标记,例如,Person:“Bill Smith”。我不知道使用什么 API 调用来确定何时应将“Bill”和“Smith”视为一个实体,以及何时应将它们视为两个不同的实体。

是否有一些像样的文档可以解释这一点?

这是我当前的代码:

    InputStream is = getClass().getResourceAsStream(MODEL_NAME);
    if (MODEL_NAME.endsWith(".gz")) {
        is = new GZIPInputStream(is);
    }
    is = new BufferedInputStream(is);

    Properties props = new Properties();
    props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");

    AbstractSequenceClassifier<CoreLabel> classifier = CRFClassifier.getClassifier(is);
    is.close();

    String text = "Hello, Bill Smith, how are you?";

    List<List<CoreLabel>> sentences = classifier.classify(text);
    for (List<CoreLabel> sentence: sentences) {
        for (CoreLabel word: sentence) {
            String type = word.get(CoreAnnotations.AnswerAnnotation.class);
            System.out.println(word + " is of type " + type);
        }
    }

另外,我不清楚为什么“PERSON”注释会以 AnswerAnnotation 的形式返回,而不是 CoreAnnotations.EntityClassAnnotation、EntityTypeAnnotation 或其他。

【问题讨论】:

    标签: stanford-nlp


    【解决方案1】:

    您应该使用“entitymentions”注释器,它将标记具有与实体相同的ner标签的连续令牌序列。每个句子的实体列表将存储在 CoreAnnotations.MentionsAnnotation.class 键下。每个实体提及本身都是一个 CoreMap。

    查看此代码可能会有所帮助:

    https://github.com/stanfordnlp/CoreNLP/blob/master/src/edu/stanford/nlp/pipeline/EntityMentionsAnnotator.java

    一些示例代码:

    import java.io.*;
    import java.util.*;
    import edu.stanford.nlp.ling.*;
    import edu.stanford.nlp.pipeline.*;
    import edu.stanford.nlp.util.*;
    
    
    
    public class EntityMentionsExample {
    
      public static void main (String[] args) throws IOException {
        Properties props = new Properties();
        props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner,entitymentions");
        StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
        String text = "Joe Smith is from Florida.";
        Annotation annotation = new Annotation(text);
        pipeline.annotate(annotation);
        System.out.println("---");
        System.out.println("text: " + text);
        for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) {
          for (CoreMap entityMention : sentence.get(CoreAnnotations.MentionsAnnotation.class)) {
            System.out.print(entityMention.get(CoreAnnotations.TextAnnotation.class));
            System.out.print("\t");
            System.out.print(
                    entityMention.get(CoreAnnotations.NamedEntityTagAnnotation.class));
            System.out.println();
          }
        }
      }
    }
    

    【讨论】:

    • 谢谢。三个快速问题:这段代码如何知道要加载哪些模型?这段代码的加载速度比我的原始代码慢得多;如何减少启动时间?哪里有更好的文档?
    • 它正在加载默认模型。您可以使用属性“ner.model”设置要加载的模型。一般来说,我会坚持我的代码并使用 StanfordCoreNLP 管道。独立分类器是一种使用 ner 东西的旧方式。这是文档站点:stanfordnlp.github.io/CoreNLP
    • 这里有一些关于 API 的更具体的评论:stanfordnlp.github.io/CoreNLP/api.html
    • 如果您想使用 Stanford CoreNLP 管道但又不必经常重新加载它,您可以构建您的代码以简单地调用 Stanford CoreNLP 服务器。这是有关服务器的文档:stanfordnlp.github.io/CoreNLP/corenlp-server.html
    • 但是,如果您只想要一个可以启动并运行的简单 Java 类,则无需在启动时加载模型。
    猜你喜欢
    • 2019-06-26
    • 2017-12-09
    • 2014-04-26
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2015-04-30
    相关资源
    最近更新 更多