有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我试图弄清楚是否有可能使用多个单词的条件有效地提取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,它包含函数参数中指定的标记,例如,对于输入[“受控”,“哮喘”],它应该返回

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

但当输入为[“注射”、“控制”、“哮喘”时,它不应返回任何内容

如您所见,若其中一个输入字符串是“多个单词”,那个么程序会将其拆分为多个单词。我认为应该有更好的解决方案,但我不知道它应该如何工作


共 (1) 个答案

  1. # 1 楼答案

    我认为你只需要稍微调整一下你的模式。您并没有真正给出您想要的内容的完整说明,但是从我所能知道的情况来看["controlled", "asthma"]应该会产生类似(NP << (controlled .. asthma ))的模式,这意味着“包含‘受控’的名词短语,后跟‘哮喘’”。我不确定你到底想让“短语”如何运作;你想让["controlled asthma"]的意思是“控制”紧接着“哮喘”,即(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();
      }
    

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