如何使用Stanford NLP Tregex获取其中包含多个单词的名词短语?

时间:2015-07-10 09:43:20

标签: java nlp stanford-nlp

我试图弄清楚是否有可能使用多个单词的条件有效地提取NP。这是我目前的代码:

public static List<Tree> getNounPhrasesWithMultipleKeywords(Annotation doc,
        List<String> tags) {
    StringBuilder sb = new StringBuilder();
    boolean firstWord = true;

    for (int i = 0; i < tags.size(); i++) {
        String word = tags.get(i);
        String[] splitted = word.split(" ");
        for (String splitWord : splitted) {
            if (!firstWord) {
                sb.append(" &");
            }
            sb.append(" << " + splitWord);
            firstWord = false;
        }

    }
    // sb.append(")");

    TregexPattern pattern = TregexPattern.compile("NP < (__"
            + sb.toString() + ")");

    return getTreeWithPattern(doc, pattern);
}

现在,让我们说输入短语有这个树:

(ROOT (S (NP (ADJP (RB Poorly) (VBN controlled)) (NN asthma)) (VP (VBZ is) (NP (DT a) (JJ vicious) (NN disease))) (. .)))

我想只获得那些包含在函数参数中指定的标签的NP,例如输入[&#34;控制&#34;,&#34;哮喘&#34;]它应该返回

(NP (ADJP (RB Poorly) (VBN controlled)) (NN asthma))

但是当输入是[&#34;注射&#34;,&#34;控制&#34;,&#34;哮喘&#34;]时,它应该什么都不返回。

正如您所看到的,如果输入字符串之一是&#34;多个单词&#34;,则程序将其拆分为单词。我认为应该有更好的解决方案,但我不知道它应该如何运作。

1 个答案:

答案 0 :(得分:1)

我认为你只需稍微调整你的模式。你并没有真正完整地说明你想要的内容,但从我所知道的["controlled", "asthma"]应该会产生类似(NP << (controlled .. asthma ))的模式,这意味着&#34;名词短语包含&# 39;控制&#39;其次是哮喘&#39;&#34;我不确定你到底想要什么&#34;短语&#34;上班;您希望["controlled asthma"]表示&#34;&#39;控制&#39;紧接着是哮喘&#34;&#34;,即(NP << (controlled . asthma))

这是您创建这些模式的新功能版本:

  public static List<Tree> getNounPhrasesWithMultipleKeywords(Annotation doc,
                                                              List<String> tags) {
    List<String> phrases = new ArrayList<String>();

    for (int i = 0; i < tags.size(); i++) {
      String word = tags.get(i);
      String[] splitted = word.split(" ");
      phrases.add(join(" . ", Arrays.asList(splitted)));
    }
    String pattern_str = join(" .. ", phrases);
    TregexPattern pattern = TregexPattern.compile(
      "NP << (" + pattern_str + ")");
    return getTreeWithPattern(doc, pattern);
  }

  // In Java 8 use String.join.
  public static String join(String sep, Collection<String> strs) {
    System.out.println(strs);
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (String s : strs) {
      if (!first) {
        sb.append(sep);
      }
      sb.append(s);
      first = false;
    }
    return sb.toString();
  }

此函数提供您在示例中指定的输出。