#tree #plot #parsed #string #input #math-expressions #drawing

parsed_to_plot

根据字符串给出的字符串绘制词法树和依存树

3 个不稳定版本

0.2.0 2023年5月12日
0.1.1 2023年4月11日
0.1.0 2023年4月10日

#110 in 可视化

MIT 许可证

94KB
1.5K SLoC

parsed_to_plot

example workflow rust version crates.io

根据字符串绘制词法树和依存树。

概述

主要用于处理解析后的句法树输入,但也支持其他输入,如数学表达式等。程序首先将输入转换为 conll / tree 格式,然后递归地绘制结构。它主要适用于长度不超过15-20个标记的短解析序列。程序是一个简单的绘图程序,绘制已解析的字符串。这不是一个解析器!我写这个是为了熟悉 Rust,如果它能帮助到其他人,我就上传它。代码使用了 id-treeplotters 这两个 crate。

当前内容

  • String2Tree + Tree2Plot 将输入的词法字符串转换为图形(API 或通过命令行)。
  • String2Conll + Conll2Plot 将输入的依存字符串转换为图形(API 或通过命令行)。
  • 从版本 0.2.0 开始 - Tree2String / Conll2String 将构建的结构转换回原始输入 ()。

输入-输出

  • API 预期字符串输入。多个字符串输入可以通过文件或命令行传递。
  • 对于词法树,程序接收一行中给出的解析字符串。字符串可以是句法的,例如表示短语和词性的结构(如 Python 中的 Berkeley Neural Parser 的结构)。这样的字符串将有“双重叶子”(见下面的示例)。或者,字符串可以有单叶,表示例如数学表达式。
  • 对于依存树,程序接收 conll 格式,其中每个标记有10个字段,用制表符分隔,每行一个。句子之间用空行分隔。(见下面的示例,使用 Python 中的 spaCy 的输出)。
  • 对于同一类型的多个输入,程序期望命令行中的3个参数
    • 输入类型 ("c" = 词法 / "d" = 依存),字符串
    • 输入文件路径,字符串
    • 输出路径,字符串

见下面的示例。

使用示例

选民团

如何使用API从单个解析的选民团字符串中生成png图像

// Example parsed sentence:
// (S (NP (det The) (N people)) (VP (V watch) (NP (det the) (N game))))

use parsed_to_plot::Config;
use parsed_to_plot::String2Tree;
use parsed_to_plot::Tree2Plot;
use parsed_to_plot::String2StructureBuilder;
use parsed_to_plot::Structure2PlotBuilder;
 
let mut constituency = String::from("(S (NP (det The) (N people)) (VP (V watch) (NP (det the) (N game))))");
let mut string2tree: String2Tree = String2StructureBuilder::new();
string2tree.build(&mut constituency).unwrap(); // build the tree from the string
let tree = string2tree.get_structure();

// build plot from tree and save
Config::make_out_dir(&"Output".to_string()).unwrap();
let save_to: &str = "Output/constituency_plot.png";
let mut tree2plot: Tree2Plot = Structure2PlotBuilder::new(tree);
tree2plot.build(save_to).unwrap();

依赖

如何使用API从单个conll格式生成png图像

// Example conll:
//  0   The the det _   _   1   det   _   _
//  1	people	people	NOUN	_	_	2	nsubj	_	_
//  2	watch	watch	VERB	_	_	2	ROOT	_	_
//  3	the	the	DET	_	_	4	det	_	_
//  4	game	game	NOUN	_	_	2	dobj	_	_
 
use parsed_to_plot::Config;
use parsed_to_plot::String2Conll;
use parsed_to_plot::Conll2Plot;
use parsed_to_plot::String2StructureBuilder;
use parsed_to_plot::Structure2PlotBuilder;
 
let mut dependency = [
    "0	The	the	DET	_	_	1	det	_	_",
    "1	people	people	NOUN	_	_	2	nsubj	_	_",
    "2	watch	watch	VERB	_	_	2	ROOT	_	_",
    "3	the	the	DET	_	_	4	det	_	_",
    "4	game	game	NOUN	_	_	2	dobj	_	_"
].map(|x| x.to_string()).to_vec();
 
let mut string2conll: String2Conll = String2StructureBuilder::new();
string2conll.build(&mut dependency).unwrap(); // build the conll from the vector of strings
let conll = string2conll.get_structure();

// build plot from conll and save
Config::make_out_dir(&"Output".to_string()).unwrap();
let save_to: &str = "Output/dependency_plot.png";
let mut conll2plot: Conll2Plot = Structure2PlotBuilder::new(conll);
conll2plot.build(save_to).unwrap();

通过文件的多重输入

您可以使用API和命令行的组合来通过文件处理同一类型的多个输入。命令行格式如下:

cargo run INPUT_TYPE INPUT_FILE OUTPUT_PATH

when

  • INPUT_TYPE应替换为“c”表示选民团或“d”表示依赖。
  • INPUT_FILE应替换为包含输入的txt文件路径。
  • OUTPUT_PATH应替换为目标输出目录的路径。

例如,您可以使用以下命令输入多个选民团:

cargo run c constituencies.txt Output 

用法如下:

use parsed_to_plot::Config;
use parsed_to_plot::String2Tree;
use parsed_to_plot::Tree2Plot;
use parsed_to_plot::String2StructureBuilder;
use parsed_to_plot::Structure2PlotBuilder;
use std::env;
 
// collect arguments from command line 
let args: Vec<String> = env::args().collect();
// note: your command line args should translate to something similar to the following:
let args: Vec<String> = ["PROGRAM_NAME", "c", "Input/constituencies.txt", "Output"].map(|x| x.to_string()).to_vec();
 
// run configuration protocol and inspectations
let sequences = match Config::new(&args) {
    Ok(sequences) => Vec::<String>::try_from(sequences).unwrap(),
    Err(config) => panic!("{}", config) 
};
 
for (i, mut constituency) in sequences.into_iter().enumerate() {
            
     println!("working on input number {} ...", i);
     let save_to = &Config::get_out_file(&args[3], i.to_string().as_str());
     
     // build tree from consituency
     let mut string2tree: String2Tree = String2StructureBuilder::new();
     string2tree.build(&mut constituency).unwrap();
     let tree = string2tree.get_structure();
     
     // build plot from tree
     let mut tree2plot: Tree2Plot = Structure2PlotBuilder::new(tree);
     tree2plot.build(save_to).unwrap();
}

这些命令将在Output目录下保存为constituencies.txt中输入的选民团的png图像。依赖的等效操作类似。

字符串重建

从版本0.2.0开始,您可以从构建的结构、树或Vec创建字符串。例如,可以通过确保x = Structure2String(String2Structure(x))来断言由字符串x构建的树。例如,对于依赖字符串(选民团的等效操作类似)

//  0   The the det _   _   1   det   _   _
//  1	people	people	NOUN	_	_	2	nsubj	_	_
//  2	watch	watch	VERB	_	_	2	ROOT	_	_
//  3	the	the	DET	_	_	4	det	_	_
//  4	game	game	NOUN	_	_	2	dobj	_	_

use parsed_to_plot::Config;
use parsed_to_plot::String2Conll;
use parsed_to_plot::Conll2String;
use parsed_to_plot::String2StructureBuilder;
use parsed_to_plot::Structure2PlotBuilder;
 
let example = [
    "0	The	the	DET	_	_	1	det	_	_",
    "1	people	people	NOUN	_	_	2	nsubj	_	_",
    "2	watch	watch	VERB	_	_	2	ROOT	_	_",
    "3	the	the	DET	_	_	4	det	_	_",
    "4	game	game	NOUN	_	_	2	dobj	_	_"
].map(|x| x.to_string()).to_vec();
let mut dependency = example.clone();
 
let mut string2conll: String2Conll = String2StructureBuilder::new();
string2conll.build(&mut dependency).unwrap(); // build the conll from the vector of strings
let conll = string2conll.get_structure();

// from v0.2.0 - reconstruction of the original dependency from the built conll
Config::make_out_dir(&"Output".to_string()).unwrap();
let save_to: &str = "Output/dependency_reconstruction.txt";
let mut conll2string: Conll2String = Structure2PlotBuilder::new(conll);
conll2string.build(save_to).unwrap();
let dependency_reproduction = conll2string.get_conll();
assert_eq!(dependency_reproduction, example);

参考

  • 我使用了以下crates: id-treeplotters
  • 我使用了spaCy创建了一些依赖解析示例以供说明。

许可证

在MIT许可证下。

依赖

~14MB
~107K SLoC