2014-01-27 73 views
0

我一直在使用Stanford Parser进行CFG分析。我可以将输出显示为树状结构,但我真正想要的是标记的数量。斯坦福分析器 - 标记计数

这样我就可以出去,例如(从another query采取堆栈溢出):

(ROOT (S (NP (PRP$ My) (NN dog)) (ADVP (RB also)) (VP (VBZ likes) (NP (JJ eating) (NN sausage))) (. .))) 

但我真正想要的是一个CSV文件输出标签的计数:

PRP - 1 
JJ - 1 

斯坦福解析器可以这样做,特别是当我想处理几个文本文件,或者我应该使用不同的程序吗?

回答

1

是的,这很容易实现。

你将需要:

 
import java.util.HashMap; 
import edu.stanford.nlp.trees.Tree; 

我从你现有的树对象已经是其他问题的假设。 我怀疑你只想要一个带有离开节点的列表(在你的例子中是PRP,NN,RB ...),但是你可以为每个节点做一般的事情。

然后遍历所有节点,只计算叶子:

Tree tree = ... 
for (int i = 1; i < tree.size(); i++) { 
    Tree node = tree.getNodeNumber(i); 

    if (node.isLeaf()) { 
    // count here 
    } 
} 

计数是使用一个HashMap完成后,你会发现这里的计算器上的很多例子。 基本上从一个Hashmap开始,使用标记作为键和标记计数作为值。

编辑:对不起,纠正了代码中的否定错误。

1

上一个答案在正确的情况下迭代了解析树中的所有节点。

我使用番石榴的Function在代码中一点点额外的优雅,但:虽然是返回POS标签数没有现成的方法,你可以使用在edu.stanford.nlp.trees.Trees类方法叶节点如下直接得到一个简单的for循环将工作一样好。

Tree tree = sentence.get(TreeAnnotation.class); // parse tree of the sentence 
List<CoreLabel> labels = Trees.taggedLeafLabels(tree); // returns the labels of the leaves in a Tree, augmented with POS tags. 
List<String> tags = Lists.transform(labels, getPOSTag); 
for (String tag : tags) 
    Collections.frequency(tags, tag); 

其中

Function<CoreLabel, String> getPOSTag = new Function<CoreLabel, String>() { 
    public String apply(CoreLabel core_label) { return core_label.get(PartOfSpeechAnnotation.class); } 
}; 
+0

优雅的回答,真的! –

+0

感谢您的帮助。对不起,如果这是显而易见的,但这意味着创建一个Java模块呢?目前我刚刚在终端命令行中运行它(例如,java -mx200m edu.stanford.nlp.parser.lexparser.LexicalizedParser -retainTMPSubcategories -outputFormat“wordsAndTags,penn,typedDependencies”englishPCFG.ser.gz mumbai.txt) – JRUK

+0

是的,你需要你自己的代码。尽管斯坦福大学NLP的作者为CLI的使用提供了很大的灵活性,但除了解析结果的直接输出之外,您通常需要使用他们的API(顺便提一下,这是非常有用的) 。 –