Skip to content

ixmoyren/pinyinchch

Repository files navigation

pinyinchch

一个拼音转汉字的工具库。

介绍

这是一个用 Rust 重写的 Pinyin2Hanzi 库,或者说是将 Pinyin2Hanzi 库从 Python 移植到 Rust,支持两种模型:

  • HMM (隐马尔可夫模型):使用 Viterbi 算法进行拼音转汉字
  • DAG (有向无环图):使用动态规划算法进行拼音转汉字

Note

本项目只实现了 Pinyin2Hanzi 中模型推理的部分,即实现拼音到汉字的转换,并未实现使用 Rust 训练 HMM 和 DAG 模型。

本项目中将 Pinyin2Hanzi 提供的 HMM 和 DAG 模型封装成不同的 crate,按需引入。也可以通过实现 pingyinchch-type 中定义的 trait Hmmtrait Dag,来导入自行训练的 HMM 和 DAG 模型

安装

  • 如果使用 hmm 的 Viterbi 算法进行拼音到汉字的转换,那么需要启用 hmm 功能。

    cargo add pinyinchch -F hmm

    如果使用默认提供的 hmm 模型,则需要引入 pinyinchch-model-hmm

    cargo add pinyinchch-model-hmm

    如果想自己实现一个拼音到汉字的 hmm 模型,那么需要引入 pinyinchch-type, 并且实现 Hmm trait

    cargo add pinyinchch-type
  • 如果使用 dag 的动态规划算法进行拼音到汉字的转换,那么需要启用 dag 功能。

    cargo add pinyinchch -F dag

    如果需要使用默认提供的 dag 模型,则需要引入 pinyinchch-model-dag

    cargo add pinyinchch-model-dag

    如果想自己实现一个拼音到汉字的 dag 模型,那么需要引入 pinyinchch-type, 并且实现 dag trait

    cargo add pinyinchch-type

使用示例

使用默认 HMM 模型将拼音转换成汉字

use pinyinchch::hmm::viterbi;
use pinyinchch::pinyin::pinyin_split_by_trie_tokenizer;
use pinyinchch_model_hmm::DefaultHmm;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建 HMM 实例
    let hmm = DefaultHmm::default();

    let pinyin = "nihao";

    // 对拼音字符串进行拆分
    let pinyin_split_str = pinyin_split_by_trie_tokenizer(pinyin);

    let pinyin_seq = pinyin_split_str.split(" ").collect::<Vec<_>>();

    // 使用 Viterbi 算法,返回 2 个候选结果,不使用对数概率
    let result = viterbi(&hmm, &pinyin_seq, 2, false, 3.14e-200);

    println!("HMM结果:");
    for item in &result {
        println!("分数: {}, 路径: {:?}", item.score(), item.path());
    }

    // 使用对数概率
    let result_log = viterbi(&hmm, &pinyin_seq, 2, true, 3.14e-200);

    println!("\nHMM结果 (对数概率):");
    for item in &result_log {
        println!("分数: {}, 路径: {:?}", item.score(), item.path());
    }

    Ok(())
}

输出

HMM结果:
分数: 0.00006800447668424451, 路径: ['', '']
分数: 0.000000006323093325525867, 路径: ['', '']

HMM结果 (对数概率):
分数: -9.595937021363273, 路径: ['', '']
分数: -18.87905729828791, 路径: ['', '']

使用默认的 DAG 模型将拼音转换成汉字

use pinyinchch::dag::dispatch;
use pinyinchch_model_dag::DefaultDag;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建DAG参数实例
    let dag_params = DefaultDag::default();

    // 测试拼音转汉字
    let pinyin_list = vec!["ni", "hao"];

    // 使用DAG算法,返回2个候选结果,不使用对数概率
    let result = dispatch(&dag_params, &pinyin_list, 2, false);

    println!("DAG结果:");
    for item in &result {
        println!("分数: {}, 路径: {:?}", item.score(), item.path());
    }

    // 使用对数概率
    let result_log = dispatch(&dag_params, &pinyin_list, 2, true);

    println!("\nDAG结果 (对数概率):");
    for item in &result_log {
        println!("分数: {}, 路径: {:?}", item.score(), item.path());
    }

    Ok(())
}

输出

DAG结果:
分数: 0.21953546530016635, 路径: ["你好"]
分数: 0.015182124223139684, 路径: ["", ""]

DAG结果 (对数概率):
分数: -1.516241486396955, 路径: ["你好"]
分数: -4.187636581156532, 路径: ["", ""]

特性

  • 支持 HMM 和 DAG 两种转换算法,提供对数概率和线性概率两种评分方式
  • 支持自定义 HMM 和 DAG 实现
  • 提供将拼音字符串拆分的方法

数据文件

本库使用预训练的模型数据,包括:

  • hmm_py2hz.json: 拼音到汉字的映射
  • hmm_start.json: 起始概率
  • hmm_emission.json: 发射概率
  • hmm_transition.json: 状态转移概率
  • dag_char.json: 单字拼音数据
  • dag_phrase.json: 词组拼音数据

测试

运行测试:

cargo test

xtask 脚本

该脚本负责将原本以 json 格式保存的模型转换成以 rkyv 格式保存

在 workspace 中执行 cargo xtask convert-to-rkyv 即可将 data 目录下的模型转换到对应 crate 中

许可

许可任你喜欢选择下面任一种,或者两种都选

贡献

除非您另有明确说明,否则任何您提交的代码许可应按上述 Apache 和 MIT 双重许可,并没有任何附加条款或条件。

About

一个拼音转汉字工具库

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Contributors

Languages