两类解析树之间的转换

2024-09-28 21:07:46 发布

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

我有一个训练集包含两种类型的NLP解析树(PSGCCG),它们有一个公共的源语句。我的目标是给出一个只有一种类型解析树的句子,使用从训练数据中学习的一组规则,将给定的类型转换成另一种类型的解析树。你知道吗

例如,给定两种类型的解析树i和ii,例如:

i: (S (N John) (VP (V hit) (NP (D the) (N ball) ) ) )

ii: (S (NP John) (S\NP ((S\NP)/NP hit) (NP (NP/NP the) (NP ball) ) ) )

它们都具有相同的叶节点,但具有不同的语法标记(POS标记和CCG标记)。你知道吗

我的方法是在每个树的相应节点之间创建映射:

pos_cat_map = defaultdict(int)  # A map from (POS tags, CCG tags) to their counts
cat_map = defaultdict(int)  # A map from CCG tags to its counts

# Generate a hierarchical tree structure,  
# @para: psg_sent is the sentence i, ccg_sent is ii. 
psg_tree = generate_psg_tree(psg_sent)  
ccg_tree = generate_ccg_tree(ccg_sent)

# Updating the container iteratively.
update_mapping(psg_tree, ccg_tree, pos_cat_map, cat_map) 

函数update_mapping定义如下:

def update_mapping(psg_tree, ccg_tree, pos_cat_map, cat_map):
    ...
    if isinstance(psg_tree, PSGTree):
        # Update the root node
        pos_cat_map[(psg_tree.root, ccg_tree.cat)] += 1
        cat_map[ccg_tree.cat] += 1
        if ...
            update_mapping(psg_tree.left_child, ccg_tree.head, pos_cat_map, cat_map)
            update_mapping(psg_tree.right_child, ccg_tree.sister, pos_cat_map, cat_map)
        ...
    elif isinstance(psg_tree, PSGLeafNode):
        # Update the leaf node
        ...
        try:
            if psg_tree.word == ccg_tree.word:
                pos_cat_map[(psg_tree.syn, ccg_tree.cat)] += 1
                cat_map[ccg_tree.cat] += 1
            else:
                raise TransException("Two types of words are not matching: %s %s" % (tct_tree.word, ccg_tree.word))
        ...
    ...

完成此操作后,我得到了一个包含从PSG叶节点到CCG叶节点的映射的映射,例如:

==============
== p(pos|cat)
==============
v|S{sub}\NP 0.341598
vN|SP/SP 0.034783
a|[S/S]/[S/S] 0.014184
vN|NP 0.041867
p|[S/S]/[S{obj}\NP] 1.000000
...

然后我需要使用这个规则将PSG树转换为CCG树(或相反),但是我发现这可能是不可能的,因为对于每个POS标记,都有许多可能的CCG标记从中生成。可能的CCG树的数量是巨大的。如何限制CCG树的空间以找到有效的CCG树?你知道吗


Tags: the标记postree类型map节点np