如何使用NLTK从诱导语法中生成句子?

ste*_*hom 15 python nlp nltk

我有一个(大)解析句子列表(使用斯坦福解析器解析),例如,句子"现在你可以被娱乐"有以下树:

(ROOT
  (S
    (ADVP (RB Now))
    (, ,)
    (NP (PRP you))
    (VP (MD can)
      (VP (VB be)
        (VP (VBN entertained))))
    (. .)))
Run Code Online (Sandbox Code Playgroud)

我正在使用句子树集来使用nltk来引导语法:

import nltk

# ... for each sentence tree t, add its production to allProductions
allProductions += t.productions()

# Induce the grammar
S = nltk.Nonterminal('S')
grammar = nltk.induce_pcfg(S, allProductions)
Run Code Online (Sandbox Code Playgroud)

现在我想grammar用来生成新的随机句子.我的希望是,由于语法是从一组特定的输入示例中学习的,因此生成的句子在语义上是相似的.我可以在nltk中这样做吗?

如果我不能使用nltk这样做,是否存在任何其他可以采用(可能重新格式化)grammar并生成句子的工具?

dmh*_*dmh 13

在NLTK 2.0中,您可以使用nltk.parse.generate生成给定语法的所有可能句子.

此代码定义了一个函数,该函数应根据(P)CFG中的生成规则生成单个句子.

# This example uses choice to choose from possible expansions
from random import choice
# This function is based on _generate_all() in nltk.parse.generate
# It therefore assumes the same import environment otherwise.
def generate_sample(grammar, items=["S"]):
    frags = []
    if len(items) == 1:
        if isinstance(items[0], Nonterminal):
            for prod in grammar.productions(lhs=items[0]):
                frags.append(generate_sample(grammar, prod.rhs()))
        else:
            frags.append(items[0])
    else:
        # This is where we need to make our changes
        chosen_expansion = choice(items)
        frags.append(generate_sample,chosen_expansion)
    return frags
Run Code Online (Sandbox Code Playgroud)

要在PCFG中使用权重,您显然希望使用更好的采样方法choice(),这隐含地假设当前节点的所有扩展都是等概率的.


For*_*gic 4

首先,如果你生成随机句子,它们在语义上可能是正确的,但它们可能会失去意义。

(在我看来,这有点像麻省理工学院的学生使用他们的SCIgen 程序所做的,该程序是自动生成科学论文。顺便说一句,非常有趣。)

不管怎样,我自己从来没有这样做过,但使用 nltk.bigrams 似乎是可能的,您可以在“使用 Bigrams 生成随机文本”下查看

您还可以生成当前树的所有子树,我不确定这是否是您想要的。