如何获取无POS标签的括号格式二元解析(SNLI语料库格式)
生成SNLI风格无POS标签二元句法解析的方案
我之前刚好折腾过类似的需求,给你几个能直接生成SNLI那种无POS标签二元括号解析的可行方案,专门针对你提到的「无POS标签」和「严格二元结构」两个核心要求:
方案一:用Stanford Parser直接生成(最省心)
Stanford Parser本身支持定制输出格式,刚好能匹配你的需求:
- 先下载Stanford Parser的最新版本,运行时指定以下参数:
输入你的示例句子后,就能直接得到和SNLI格式完全一致的结果:java -cp "*" edu.stanford.nlp.parser.lexparser.LexicalizedParser -outputFormat "penn" -outputFormatOptions "binary,stripTags" englishPCFG.ser.gz( ( ( A person ) ( on ( a horse ) ) ) ( ( jumps ( over ( a ( broken ( down airplane ) ) ) ) ) . ) )
- 如果要在Python里调用,不用额外装复杂的库,直接用
subprocess模块调用上述命令行即可,把输入句子通过管道传进去,再捕获输出结果。
方案二:用spaCy+Stanza手动转换(Python友好)
如果你习惯用Python代码处理,可以通过spaCy结合Stanza来实现:
- 先安装依赖:
pip install spacy spacy-stanza stanza python -m stanza download en - 写一个递归函数,把Stanza生成的 constituency 树转换成二元结构,并剥离POS标签:
运行这段代码就能输出你想要的SNLI格式解析结果,完全没有POS标签。import stanza from spacy_stanza import StanzaLanguage # 初始化模型 snlp = stanza.Pipeline(lang="en", processors="tokenize,pos,constituency") nlp = StanzaLanguage(snlp) def convert_to_snli_binary(node): # 叶子节点直接返回带括号的文本 if node.is_leaf(): return f"( {node.text} )" # 处理多分支节点:拆成二元结构(左子树 + 剩余子树合并) if len(node.children) == 1: return convert_to_snli_binary(node.children[0]) # 取第一个孩子作为左分支,剩下的所有孩子合并成右分支节点 left_child = node.children[0] right_children = node.children[1:] right_node = type(node)(node.label, right_children) # 递归拼接 return f"( {convert_to_snli_binary(left_child)} {convert_to_snli_binary(right_node)} )" # 测试示例句子 doc = nlp("A person on a horse jumps over a broken down airplane.") constituency_tree = doc.sentences[0].constituency print(convert_to_snli_binary(constituency_tree))
方案三:用预训练的SNLI专用解析模型
如果你需要更高的准确率(贴合SNLI的标注风格),可以用专门针对SNLI训练的 constituency 解析模型:
- 找到支持输出 constituency 树的预训练模型后,只需要在输出时过滤掉POS标签,再把多分支结构强制转换成二元结构即可,逻辑和方案二里的递归函数类似。
之前你看到的Stack Overflow答案没用,大概率是因为没针对性处理「剥离POS标签」和「强制二元拆分」这两个细节,上面的方案都是围绕这两点设计的,应该能帮到你。
内容的提问来源于stack exchange,提问作者Rajeshree Kathariya
相关产品推荐
相关产品推荐

