关于python:如何在NLTK中解析依赖项?

How do I do dependency parsing in NLTK?

遍历NLTK书,目前尚不清楚如何从给定的句子生成依赖树。

该书的相关部分:依赖语法的第二章给出了一个示例图,但是它没有显示如何解析一个句子以解决这些关系-也许我在NLP中缺少一些基本知识?

编辑:
我想要类似于斯坦福解析器的功能:
给定一句"我在睡眠中射杀了大象",它应该返回如下内容:

1
2
3
4
5
6
nsubj(shot-2, I-1)
det(elephant-4, an-3)
dobj(shot-2, elephant-4)
prep(shot-2, in-5)
poss(sleep-7, my-6)
pobj(in-5, sleep-7)


我们可以使用NLTK的Stanford Parser。

要求

您需要从他们的网站下载两件事:

  • Stanford CoreNLP解析器。
  • 所需语言的语言模型(例如英语语言模型)
  • 警告!

    确保您的语言模型版本与您的Stanford CoreNLP解析器版本匹配!

    截至2018年5月22日,当前的CoreNLP版本为3.9.1。

    下载两个文件后,将zip文件解压缩到您喜欢的任何位置。

    Python代码

    接下来,加载模型并通过NLTK使用它

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from nltk.parse.stanford import StanfordDependencyParser

    path_to_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser.jar'
    path_to_models_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser-3.4.1-models.jar'

    dependency_parser = StanfordDependencyParser(path_to_jar=path_to_jar, path_to_models_jar=path_to_models_jar)

    result = dependency_parser.raw_parse('I shot an elephant in my sleep')
    dep = result.next()

    list(dep.triples())

    输出量

    最后一行的输出是:

    1
    2
    3
    4
    5
    6
    [((u'shot', u'VBD'), u'nsubj', (u'I', u'PRP')),
     ((u'shot', u'VBD'), u'dobj', (u'elephant', u'NN')),
     ((u'elephant', u'NN'), u'det', (u'an', u'DT')),
     ((u'shot', u'VBD'), u'prep', (u'in', u'IN')),
     ((u'in', u'IN'), u'pobj', (u'sleep', u'NN')),
     ((u'sleep', u'NN'), u'poss', (u'my', u'PRP$'))]

    我想这就是你想要的。


    如果您需要更好的性能,那么spacy(https://spacy.io/)是最佳选择。用法很简单:

    1
    2
    3
    4
    import spacy

    nlp = spacy.load('en')
    sents = nlp(u'A woman is walking through the door.')

    您将获得一个依赖关系树作为输出,并且可以非常轻松地挖掘出所需的每条信息。您还可以定义自己的自定义管道。在他们的网站上查看更多。

    https://spacy.io/docs/usage/


    我认为您可以使用基于语料库的依赖解析器,而不是NLTK提供的基于语法的解析器。

    在Python中,即使对少量文本进行基于语料库的依存关系解析也不是理想的性能。因此,在NLTK中,它们确实为基于语料库的依赖项解析器MaltParser提供了包装。

    您可能会发现有关句子的RDF表示的其他问题。


    如果您想认真对待依赖关系解析,请不要使用NLTK,因为所有算法都是过时且缓慢的。尝试这样的事情:https://spacy.io/


    要使用NLTK的Stanford Parser

    1)在本地主机上运行CoreNLP Server
    在此处下载Stanford CoreNLP(以及适用于您的语言的模型文件)。
    可以通过运行以下命令来启动服务器(此处有更多详细信息)

    1
    2
    # Run the server using all jars in the current directory (e.g., the CoreNLP home directory)
    java -mx4g -cp"*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -port 9000 -timeout 15000

    或通过NLTK API(需要先配置CORENLP_HOME环境变量)

    1
    2
    3
    4
    os.environ["CORENLP_HOME"] ="dir"
    client = corenlp.CoreNLPClient()
    # do something
    client.stop()

    2)从NLTK调用依赖性解析器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    >>> from nltk.parse.corenlp import CoreNLPDependencyParser
    >>> dep_parser = CoreNLPDependencyParser(url='http://localhost:9000')
    >>> parse, = dep_parser.raw_parse(
    ...     'The quick brown fox jumps over the lazy dog.'
    ... )
    >>> print(parse.to_conll(4))  
    The     DT      4       det
    quick   JJ      4       amod
    brown   JJ      4       amod
    fox     NN      5       nsubj
    jumps   VBZ     0       ROOT
    over    IN      9       case
    the     DT      9       det
    lazy    JJ      9       amod
    dog     NN      5       nmod
    .       .       5       punct

    请参阅此处的详细文档以及这个问题。NLTK CoreNLPDependencyParser:无法建立连接。


    从斯坦福解析器文档中:"可以使用解析器包中提供的EnglishGrammaticalStructure类,使用我们的软件在短语结构树上获得依赖关系。 http://nlp.stanford.edu/software/stanford-dependencies.shtml

    依赖关系手册还提到:"或者我们的转换工具可以将
    其他选区解析器的输出到Stanford Dependencies表示。" http://nlp.stanford.edu/software/dependencies_manual.pdf

    目前,NLTK中似乎都未实现任何功能。


    晚会晚了一点,但我想在SpaCy中添加一些示例代码,以获取所需的输出:

    1
    2
    3
    4
    5
    import spacy
    nlp = spacy.load("en_core_web_sm")
    doc = nlp("I shot an elephant in my sleep")
    for token in doc:
        print("{2}({3}-{6}, {0}-{5})".format(token.text, token.tag_, token.dep_, token.head.text, token.head.tag_, token.i+1, token.head.i+1))

    这是输出,非常类似于您想要的输出:

    1
    2
    3
    4
    5
    6
    7
    nsubj(shot-2, I-1)
    ROOT(shot-2, shot-2)
    det(elephant-4, an-3)
    dobj(shot-2, elephant-4)
    prep(shot-2, in-5)
    poss(sleep-7, my-6)
    pobj(in-5, sleep-7)

    希望有帮助!