多字符串上的序列

2024-10-05 14:26:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用Sequitur(特别是它在pythonscikit包中非常好的实现)从大量字符串(“句子”)推断CFG。Sequitur需要一个字符串作为条目。当然,我可以将字符串包含到开始和结束符号中,并将它们连接到一个长字符串中,而不会丢失任何信息。但在这种情况下,Sequitur将发现结构将跨越句子边界,这不是我想要的

我怎样才能使Sequeur只看句子内部,而不产生投影包括开始符号和结束符号的规则?(除第一条规则外,这将是所有句子的保护伞…)

例如:如果我有“男孩吃苹果”和“女孩睡觉”两个句子,我用它们的词性标签(“a”代表文章,“n”代表名词,“v”代表动词)替换单词,我会得到“anvan”和“anv”。如果我合并它们,包括B(开始)和E(结束)符号,我得到字符串“BanvanEBanvE”。当我把这个字符串提供给Sequitur时,我得到

0 → 1 2 E 1 E 
1 → B 2 v
2 → a n  

其中,第一个规则有E符号,但没有B符号,第二个规则有a B符号、中间符号(基本上是名词短语ART+名词)和v

我想要的是

0 → B 1 E B 2 E

等等,这样剩下的语法就只有句子内部的规则了。在我们简单的例子中,它是

0 → B 1 E B 2 E
1 → 3 v 3
2 → 3 v
3 → a n

有没有一种方法可以在不改变算法代码的情况下实现这一点?如果没有,是否有其他(已实现的)算法可以精确地获得该值


Tags: 字符串算法信息规则符号情况条目代表
2条回答

我可能有一个使用nltk的解决方案。我试过使用sksequitur,但没有成功。你可以试着把两者结合起来。 以下是我所拥有的:

import nltk

Corpus=['B','a','n','v','a','n','E','B','a','n','v','E','B','a','n','E']

nbSentences=Corpus.count('B')  # Counts the nb. if sentences (B for "BEGIN" and "E" for END)

print('Nb. of sentences: ',nbSentences)

C='C -> '+'T '*nbSentences  # The corpus C is made of nbSentences "Tokens" 

core_grammar=  """
 T -> BEGIN S END
 S -> NP VP | NP
 PP -> P NP
 NP -> A N
 VP -> V NP | V
 A -> 'a'
 N -> 'n'
 V -> 'v'
 BEGIN -> 'B'
 END -> 'E' 
"""

# Generate the grammar:
gramm_str=C+core_grammar
print('grammar string: \n',gramm_str)

# Parsing:
simple_grammar = nltk.CFG.fromstring(gramm_str)
parser = nltk.ChartParser(simple_grammar)
tree = parser.parse(Corpus)

#print(list(tree)[0]) # simple output
list(tree)[0].pretty_print() # for a pretty_print
#list(tree)[0].draw() # draw in w window
#list(tree)[0] # to draw tree in jupyter notebook

结果是:

enter image description here 如您所见,所有句子都经过处理,每个句子都生成自己的树(句子之间没有交叉) 现在,如果你有数百万个句子。。。这可能是个问题

致以最良好的祝愿, 圣菲

下面是一个新版本,它使用sksequitur生成语法,然后使用nltk对其进行解析。 注意使用Mark()特殊符号(参见sksequitur文档)“标记符号不能成为规则的一部分。”

代码如下:

import nltk
import sksequitur
from sksequitur import parse, Parser, Grammar, Mark, Production

Corpus='anvanBanvBanBv' # Note: "B" is for "BREAK"

# Length of the corpus
nbSentences=len(Corpus.split('B'))
print('Nb. of sentences in corpus: ',nbSentences)

corpus=[]
n=0
for c in Corpus:
    if c=="B":
        corpus.append([Mark()])
        n+=1
    else:
        corpus.append(c)
print("Corpus ready to feed:")
print(corpus)


# Parsing the corpus
parser=Parser()
for c in corpus:
    parser.feed(c)
grammar=Grammar(parser.tree)
print("grammar: ")
print(grammar)


# Create Corpus rule: C for nltk
C='C -> '+'0 '*nbSentences+'\n'  # The corpus C is made of nbSentences "Tokens" 
print("Corpus rule:")
print(C)


# Nb of rules in the grammar:
nbRules=len(grammar)
print('Nb of rules: ',nbRules)


# Identify "Atoms" in the grammar (e.g. "a","n","v")
# An atom is anything that is not a mark or a production

atoms=[]
for i in range(nbRules):
    name=str(i)
    rule=grammar[i]
    for a in rule:
        if not(isinstance(a,type(Mark()))) and not(str(a).isdigit()):
            atoms.append(a)
atoms=list(set(atoms))    


# Create "Atoms" rules for nltk:
Atoms=''
for atom in atoms:
    if not(type(atom))==type(Mark()):
        Atoms += atom+' -> '+'\''+atom+'\''+'\n'
# add "B as an atom
Atoms += 'B -> '+'\''+'B'+'\''
print("Atoms rules: ")
print(Atoms)

# Create Core grammar;
Core=''
for i in range(nbRules):
    rule=grammar[i]
    ruleName=str(i)
    if ruleName=="0":
        Core +='0 -> '
        for j in range(len(rule)):
            if not(type(rule[j]))==type(Mark()):
                Core+=' '+str(rule[j])
            else:
                Core+=' B'+'\n'
                Core+='0 -> '
    else:
        Core += ruleName+' ->'
        for j in range(len(rule)):
            Core += ' '+str(rule[j])
    Core += '\n'
print("Core:")
print(Core)


newGrammar=C+Core+Atoms
print("Grammar for nlkt:")
print(newGrammar)

simple_grammar = nltk.CFG.fromstring(newGrammar)
parser = nltk.ChartParser(simple_grammar)
tree = parser.parse(Corpus)


#print(list(tree)[0]) # simple output
#list(tree)[0].pretty_print() # for a pretty_print
#list(tree)[0] # to draw tree in jupyter notebook

list(tree)[0].draw() # draw in w window

结果是:

enter image description here

这就是你的想法吗

致以最良好的祝愿, 圣菲

相关问题 更多 >