如何使用 Stanford NLP Tregex 获取其中包含多个单词的名词短语?
How to get noun phrase with multiple words inside it using 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,其中包含在函数参数中指定的标签,例如对于输入 ["controlled", "asthma"] 它应该 return
(NP (ADJP (RB Poorly) (VBN controlled)) (NN asthma))
但是当输入为 ["injection"、"controlled"、"asthma"] 时,它应该 return 没有。
如您所见,如果其中一个输入字符串是 "multiple words",程序会将其拆分为单词。我认为应该有更好的解决方案,但我不知道它应该如何工作。
我认为你只需要稍微调整一下你的模式。你并没有真正给出你想要什么的完整规范,但据我所知 ["controlled", "asthma"]
应该会产生像 (NP << (controlled .. asthma ))
这样的模式,这意味着 "Noun Phrase containing 'controlled' followed by 'asthma'"。我不确定您希望 "phrases" 如何工作;您是否希望 ["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();
}
此函数给出您在示例中指定的输出。
我想弄清楚是否可以使用多个单词的条件有效地提取 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,其中包含在函数参数中指定的标签,例如对于输入 ["controlled", "asthma"] 它应该 return
(NP (ADJP (RB Poorly) (VBN controlled)) (NN asthma))
但是当输入为 ["injection"、"controlled"、"asthma"] 时,它应该 return 没有。
如您所见,如果其中一个输入字符串是 "multiple words",程序会将其拆分为单词。我认为应该有更好的解决方案,但我不知道它应该如何工作。
我认为你只需要稍微调整一下你的模式。你并没有真正给出你想要什么的完整规范,但据我所知 ["controlled", "asthma"]
应该会产生像 (NP << (controlled .. asthma ))
这样的模式,这意味着 "Noun Phrase containing 'controlled' followed by 'asthma'"。我不确定您希望 "phrases" 如何工作;您是否希望 ["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();
}
此函数给出您在示例中指定的输出。