浏览Stanford CoreNLP解析结果

时间:2017-06-21 02:07:16

标签: python parsing stanford-nlp

Stanford Core NLP解析器为句子生成以下输出:

"He didn't get a reply" 

(ROOT
(S
(NP (PRP He))
(VP (VBD did) (RB n’t)
(VP (VB get)
(NP (DT a) (NN reply))))
(. .)))

我需要一种方法来导航它,即额外的标签很容易找到孩子和父母。目前我手动完成(计算括号)。我想知道是否有一个Python库可以为我做括号计数,或者甚至更好像Beautiful Soup或Scrapy让我使用对象。

如果没有工具,遍历句子并获取所有标签的最佳方法是什么?我猜我需要用包含子标签对象的列表创建某种标签对象。

3 个答案:

答案 0 :(得分:1)

这看起来像LISP。编写一个Lisp程序来遍历它并提取你想要的东西似乎很容易。

您还可以将其转换为python中的列表并在python中进行处理:

from pyparsing import OneOrMore, nestedExpr
nlpdata = '(ROOT (S (NP (PRP He)) (VP (VBD did) (RB n\'t) (VP (VB get) (NP (DT a) (NN reply)))) (. .)))'
data = OneOrMore(nestedExpr()).parseString(nlpdata)
print data
# [['ROOT', ['S', ['NP', ['PRP', 'He']], ['VP', ['VBD', 'did'], ['RB', "n't"], ['VP', ['VB', 'get'], ['NP', ['DT', 'a'], ['NN', 'reply']]]], ['.', '.']]]]

请注意,我必须在“不”

中转义引号

答案 1 :(得分:1)

我导出输出的方法不是尝试解析字符串,而是构建对象并反序列化。然后,您可以原生使用该对象。

问题中显示的输出是使用名为" prettyPrint"的管道上的选项生成的。我将其更改为" jsonPrint"改为获得JSON输出。然后我就可以获取输出并从中生成一个类(VS可以执行Paste-Special选项以从JSON生成类,或者有像http://json2csharp.com/这样的在线资源)。结果类看起来像这样:

public class BasicDependency
    {
        public string dep { get; set; }
        public int governor { get; set; }
        public string governorGloss { get; set; }
        public int dependent { get; set; }
        public string dependentGloss { get; set; }
    }

    public class EnhancedDependency
    {
        public string dep { get; set; }
        public int governor { get; set; }
        public string governorGloss { get; set; }
        public int dependent { get; set; }
        public string dependentGloss { get; set; }
    }

    public class EnhancedPlusPlusDependency
    {
        public string dep { get; set; }
        public int governor { get; set; }
        public string governorGloss { get; set; }
        public int dependent { get; set; }
        public string dependentGloss { get; set; }
    }

    public class Token
    {
        public int index { get; set; }
        public string word { get; set; }
        public string originalText { get; set; }
        public string lemma { get; set; }
        public int characterOffsetBegin { get; set; }
        public int characterOffsetEnd { get; set; }
        public string pos { get; set; }
        public string ner { get; set; }
        public string speaker { get; set; }
        public string before { get; set; }
        public string after { get; set; }
        public string normalizedNER { get; set; }
    }

    public class Sentence
    {
        public int index { get; set; }
        public string parse { get; set; }
        public List<BasicDependency> basicDependencies { get; set; }
        public List<EnhancedDependency> enhancedDependencies { get; set; }
        public List<EnhancedPlusPlusDependency> enhancedPlusPlusDependencies { get; set; }
        public List<Token> tokens { get; set; }
    }

    public class RootObject
    {
        public List<Sentence> sentences { get; set; }
    }

*注意:不幸的是,这种技术对于coref注释并不奏效。 JSON没有正确转换为类。我现在正在努力。这个模型是使用注释器&#34; tokenize,ssplit,pos,lemma,ner,parse&#34;从输出构建的。

我的代码,只是从示例代码略有变化,看起来像这样(注意&#34; pipeline.jsonPrint&#34;):

public static string LanguageAnalysis(string sourceText)
        {
            string json = "";
            // Path to the folder with models extracted from stanford-corenlp-3.7.0-models.jar
            var jarRoot = @"..\..\..\..\packages\Stanford.NLP.CoreNLP.3.7.0.1\";

            // Annotation pipeline configuration
            var props = new Properties();
            props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse");
            props.setProperty("ner.useSUTime", "0");

            // We should change current directory, so StanfordCoreNLP could find all the model files automatically
            var curDir = Environment.CurrentDirectory;
            Directory.SetCurrentDirectory(jarRoot);
            var pipeline = new StanfordCoreNLP(props);
            Directory.SetCurrentDirectory(curDir);

            // Annotation
            var annotation = new Annotation(sourceText);
            pipeline.annotate(annotation);

            // Result - JSON Print
            using (var stream = new ByteArrayOutputStream())
            {
                pipeline.jsonPrint(annotation, new PrintWriter(stream));
                json = stream.toString();
                stream.close();
            }

            return json;
        }

它似乎很好地反编译了这样的代码:

using Newtonsoft.Json;
string sourceText = "My text document to parse.";
string json = Analysis.LanguageAnalysis(sourceText);
RootObject document = JsonConvert.DeserializeObject<RootObject>(json);

答案 2 :(得分:1)

我使用this python script来成功解决问题。

该脚本可用于将Stanford Core NLP的类似Lisp的解析树格式转换为嵌套的python列表结构。

您还可以使用类似Anytree之类的内容将嵌套列表转换为更易于导航的Python数据结构,这也允许您以文本或图像的形式打印出树。