如何在 SyntaxNet 中获取 JSON 格式的依赖树?
How to get Dependency Tree in JSON format in SyntaxNet?
我正在尝试从 SyntaxNet 获取 JSON 格式的依赖关系树,但我从示例中得到的只是一个句子对象,它没有提供访问器来访问已解析的对象,甚至遍历列出的项目.
当我运行使用TensorFlow/SyntaxNet提供的docker文件中的例子时,得到的结果如下
text: "Alex saw Bob"
token {
word: "Alex"
start: 0
end: 3
head: 1
tag: "attribute { name: \"Number\" value: \"Sing\" } attribute { name: \"fPOS\" value: \"PROPN++NNP\" } "
category: ""
label: "nsubj"
break_level: NO_BREAK
}
token {
word: "saw"
start: 5
end: 7
tag: "attribute { name: \"Mood\" value: \"Ind\" } attribute { name: \"Tense\" value: \"Past\" } attribute { name: \"VerbForm\" value: \"Fin\" } attribute { name: \"fPOS\" value: \"VERB++VBD\" } "
category: ""
label: "root"
break_level: SPACE_BREAK
}
token {
word: "Bob"
start: 9
end: 11
head: 1
tag: "attribute { name: \"Number\" value: \"Sing\" } attribute { name: \"fPOS\" value: \"PROPN++NNP\" } "
category: ""
label: "parataxis"
break_level: SPACE_BREAK
}
这个对象的class类型是class'syntaxnet.sentence_pb2.Sentence',它本身没有任何文档。
我需要能够以编程方式访问上述输出。
正如在此 中所见,它以字符串格式打印 table 并且不给我编程响应。
我怎样才能得到响应而不是打印输出。或者我应该为这个输出写一个解析器..?
TL;博士
代码在最后...
Sentence 对象是 sentence_pb2.Setnence class 的一个实例,它是从 protobuf 定义文件生成的,特别是 sentence.proto。这意味着如果您查看 sentence.proto,您将看到为 class 定义的字段及其类型。所以你有一个名为 "tag" 的字段,它是一个字符串,一个名为 "label" 的字段,它是一个字符串,一个名为 head 的字段,它是一个整数等等。理论上,如果您只是使用 python 的内置函数转换为 json,它应该可以工作,但是由于 protobuf classes 是运行时生成的元 classes,它们可能产生一些不希望的结果。
所以我首先创建了一个包含我想要的所有信息的地图对象,然后将其转换为 json:
def parse_attributes(attributes):
matches = attribute_expression.findall(attributes)
return {k: v for k, v in matches}
def token_to_dict(token):
def extract_pos(fpos):
i = fpos.find("++")
if i == -1:
return fpos, "<error>"
else:
return fpos[:i], fpos[i + 2:]
attributes = parse_attributes(token.tag)
if "fPOS" not in attributes:
logging.warn("token {} has no fPos attribute".format(token.word))
logging.warn("attributes are: {}".format(attributes))
fpos = ""
else:
fpos = attributes["fPOS"]
upos, xpos = extract_pos(fpos)
return {
'word': token.word,
'start': token.start,
'end': token.end,
'head': token.head,
'features': parse_attributes(token.tag),
'tag': token.tag,
'deprel': token.label,
'upos': upos,
'xpos': xpos
}
def sentence_to_dict(anno):
return {
'text': anno.text,
'tokens': [token_to_dict(token) for token in anno.token]
}
如果你在句子对象上调用 sentence_to_dict,你会得到一个漂亮的地图,然后可以将其序列化为 json。
我正在尝试从 SyntaxNet 获取 JSON 格式的依赖关系树,但我从示例中得到的只是一个句子对象,它没有提供访问器来访问已解析的对象,甚至遍历列出的项目.
当我运行使用TensorFlow/SyntaxNet提供的docker文件中的例子时,得到的结果如下
text: "Alex saw Bob"
token {
word: "Alex"
start: 0
end: 3
head: 1
tag: "attribute { name: \"Number\" value: \"Sing\" } attribute { name: \"fPOS\" value: \"PROPN++NNP\" } "
category: ""
label: "nsubj"
break_level: NO_BREAK
}
token {
word: "saw"
start: 5
end: 7
tag: "attribute { name: \"Mood\" value: \"Ind\" } attribute { name: \"Tense\" value: \"Past\" } attribute { name: \"VerbForm\" value: \"Fin\" } attribute { name: \"fPOS\" value: \"VERB++VBD\" } "
category: ""
label: "root"
break_level: SPACE_BREAK
}
token {
word: "Bob"
start: 9
end: 11
head: 1
tag: "attribute { name: \"Number\" value: \"Sing\" } attribute { name: \"fPOS\" value: \"PROPN++NNP\" } "
category: ""
label: "parataxis"
break_level: SPACE_BREAK
}
这个对象的class类型是class'syntaxnet.sentence_pb2.Sentence',它本身没有任何文档。
我需要能够以编程方式访问上述输出。
正如在此
我怎样才能得到响应而不是打印输出。或者我应该为这个输出写一个解析器..?
TL;博士 代码在最后...
Sentence 对象是 sentence_pb2.Setnence class 的一个实例,它是从 protobuf 定义文件生成的,特别是 sentence.proto。这意味着如果您查看 sentence.proto,您将看到为 class 定义的字段及其类型。所以你有一个名为 "tag" 的字段,它是一个字符串,一个名为 "label" 的字段,它是一个字符串,一个名为 head 的字段,它是一个整数等等。理论上,如果您只是使用 python 的内置函数转换为 json,它应该可以工作,但是由于 protobuf classes 是运行时生成的元 classes,它们可能产生一些不希望的结果。
所以我首先创建了一个包含我想要的所有信息的地图对象,然后将其转换为 json:
def parse_attributes(attributes):
matches = attribute_expression.findall(attributes)
return {k: v for k, v in matches}
def token_to_dict(token):
def extract_pos(fpos):
i = fpos.find("++")
if i == -1:
return fpos, "<error>"
else:
return fpos[:i], fpos[i + 2:]
attributes = parse_attributes(token.tag)
if "fPOS" not in attributes:
logging.warn("token {} has no fPos attribute".format(token.word))
logging.warn("attributes are: {}".format(attributes))
fpos = ""
else:
fpos = attributes["fPOS"]
upos, xpos = extract_pos(fpos)
return {
'word': token.word,
'start': token.start,
'end': token.end,
'head': token.head,
'features': parse_attributes(token.tag),
'tag': token.tag,
'deprel': token.label,
'upos': upos,
'xpos': xpos
}
def sentence_to_dict(anno):
return {
'text': anno.text,
'tokens': [token_to_dict(token) for token in anno.token]
}
如果你在句子对象上调用 sentence_to_dict,你会得到一个漂亮的地图,然后可以将其序列化为 json。