斯坦福核心NLP - 理解共指解析

时间:2011-07-04 13:32:20

标签: java nlp stanford-nlp

我在理解上一版斯坦福NLP工具中对coref解析器所做的更改时遇到了一些麻烦。 例如,下面是一个句子和相应的CorefChainAnnotation:

The atom is a basic unit of matter, it consists of a dense central nucleus surrounded by a cloud of negatively charged electrons.

{1=[1 1, 1 2], 5=[1 3], 7=[1 4], 9=[1 5]}

我不确定我理解这些数字的含义。查看源代码也无济于事。

谢谢

3 个答案:

答案 0 :(得分:17)

我一直在使用coreference依赖关系图,我开始使用这个问题的另一个答案。过了一会儿,虽然我意识到上面这个算法并不完全正确。它产生的输出甚至没有接近我修改过的版本。

对于使用这篇文章的任何人来说,这里是我最终得到的算法,它也过滤掉了自我引用,因为每个代表性的注意事项也提到自己,很多提及只引用自己。

Map<Integer, CorefChain> coref = document.get(CorefChainAnnotation.class);

for(Map.Entry<Integer, CorefChain> entry : coref.entrySet()) {
    CorefChain c = entry.getValue();

    //this is because it prints out a lot of self references which aren't that useful
    if(c.getCorefMentions().size() <= 1)
        continue;

    CorefMention cm = c.getRepresentativeMention();
    String clust = "";
    List<CoreLabel> tks = document.get(SentencesAnnotation.class).get(cm.sentNum-1).get(TokensAnnotation.class);
    for(int i = cm.startIndex-1; i < cm.endIndex-1; i++)
        clust += tks.get(i).get(TextAnnotation.class) + " ";
    clust = clust.trim();
    System.out.println("representative mention: \"" + clust + "\" is mentioned by:");

    for(CorefMention m : c.getCorefMentions()){
        String clust2 = "";
        tks = document.get(SentencesAnnotation.class).get(m.sentNum-1).get(TokensAnnotation.class);
        for(int i = m.startIndex-1; i < m.endIndex-1; i++)
            clust2 += tks.get(i).get(TextAnnotation.class) + " ";
        clust2 = clust2.trim();
        //don't need the self mention
        if(clust.equals(clust2))
            continue;

        System.out.println("\t" + clust2);
    }
}

您的例句的最终输出如下:

representative mention: "a basic unit of matter" is mentioned by:
The atom
it

通常“原子”最终成为代表性的提及,但在这种情况下并不令人惊讶。输出稍微更精确的另一个例子是以下句子:

革命战争发生在18世纪,这是美国的第一场战争。

产生以下输出:

representative mention: "The Revolutionary War" is mentioned by:
it
the first war in the United States

答案 1 :(得分:8)

第一个数字是一个集群ID(代表标记,代表同一个实体),请参阅SieveCoreferenceSystem#coref(Document)的源代码。对数不包括CorefChain#toString():

public String toString(){
    return position.toString();
}

其中position是一组提及实体的位置对(让他们使用CorefChain.getCorefMentions())。以下是完整代码的示例(在groovy中),其中显示了如何从位置到令牌:

class Example {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
        props.put("dcoref.score", true);
        pipeline = new StanfordCoreNLP(props);
        Annotation document = new Annotation("The atom is a basic unit of matter, it   consists of a dense central nucleus surrounded by a cloud of negatively charged electrons.");

        pipeline.annotate(document);
        Map<Integer, CorefChain> graph = document.get(CorefChainAnnotation.class);

        println aText

        for(Map.Entry<Integer, CorefChain> entry : graph) {
          CorefChain c =   entry.getValue();                
          println "ClusterId: " + entry.getKey();
          CorefMention cm = c.getRepresentativeMention();
          println "Representative Mention: " + aText.subSequence(cm.startIndex, cm.endIndex);

          List<CorefMention> cms = c.getCorefMentions();
          println  "Mentions:  ";
          cms.each { it -> 
              print aText.subSequence(it.startIndex, it.endIndex) + "|"; 
          }         
        }
    }
}

输出(我不明白's'来自哪里):

The atom is a basic unit of matter, it consists of a dense central nucleus surrounded by a cloud of negatively charged electrons.
ClusterId: 1
Representative Mention: he
Mentions: he|atom |s|
ClusterId: 6
Representative Mention:  basic unit 
Mentions:  basic unit |
ClusterId: 8
Representative Mention:  unit 
Mentions:  unit |
ClusterId: 10
Representative Mention: it 
Mentions: it |

答案 2 :(得分:0)

这些是注释者最近的结果。

  1. [1,1] 1原子
  2. [1,2] 1一个基本的物质单位
  3. [1,3] 1
  4. [1,6] 6个带负电的电子
  5. [1,5] 5带负电的电子云
  6. 标记如下:

    [Sentence number,'id']  Cluster_no  Text_Associated
    

    属于同一群集的文本引用相同的上下文。