HanLP — 汉字转拼音,简繁转换 -- JAVA
HanLP 在汉字转拼音时,可以解决多音字问题,显示输出声调,声母、韵母,通过训练语料库,
本文代码为《自然语言处理入门》配套版本 HanLP-1.7.5
HanLP 里,汉字转简单,简体繁体转换,都用到了 双数组字典树 (Double-array Trie)、Aho-Corasick DoubleArrayTire 算法 ACDAT - 基于双数组字典树的AC自动机 需要先熟悉
对重载不是重任进行转拼音,效果如下:
原文:重载不是重任
拼音(数字音调):chong2,zai3,bu2,shi4,zhong4,ren4,
拼音(符号音调):chóng,zǎi,bú,shì,zhòng,rèn,
拼音(无音调):chong,zai,bu,shi,zhong,ren,
声调:2,3,2,4,4,4,
声母:ch,z,b,sh,zh,r,
韵母:ong,ai,u,i,ong,en,
输入法头:ch,z,b,sh,zh,r,
语料库
pinyin.txt
一丁点儿=yi1,ding1,dian3,er5
一不小心=yi1,bu4,xiao3,xin1
一丘之貉=yi1,qiu1,zhi1,he2
一丝不差=yi4,si1,bu4,cha1
一丝不苟=yi1,si1,bu4,gou3
一个=yi1,ge4
一个半个=yi1,ge4,ban4,ge4
一个巴掌拍不响=yi1,ge4,ba1,zhang3,pai1,bu4,xiang3
一个萝卜一个坑=yi1,ge4,luo2,bo5,yi1,ge4,keng1
一举两得=yi1,ju3,liang3,de2
一之为甚=yi1,zhi1,wei2,shen4

训练
训练,生成 pinyin.txt.bin
加载语料库
HanLP-1.7.5\src\main\java\com\hankcs\hanlp\corpus\dictionary\SimpleDictionary.java
加载语料库,每行读取,按 = 分隔,放入字典 trie 中

根据 = 右边每个字的拼音,通过 Pinyin.valueOf("yi1") 得到枚举中声母、韵母、音调、包含音调的字符串形式、不含音调的字符串形式

public enum Pinyin
{
a1(Shengmu.none, Yunmu.a, 1, "ā", "a", Head.a, 'a'),
a2(Shengmu.none, Yunmu.a, 2, "á", "a", Head.a, 'a'),
a3(Shengmu.none, Yunmu.a, 3, "ǎ", "a", Head.a, 'a'),
a4(Shengmu.none, Yunmu.a, 4, "à", "a", Head.a, 'a'),
a5(Shengmu.none, Yunmu.a, 5, "a", "a", Head.a, 'a'),
ai1(Shengmu.none, Yunmu.ai, 1, "āi", "ai", Head.a, 'a'),
ai2(Shengmu.none, Yunmu.ai, 2, "ái", "ai", Head.a, 'a'),
ai3(Shengmu.none, Yunmu.ai, 3, "ǎi", "ai", Head.a, 'a'),
ai4(Shengmu.none, Yunmu.ai, 4, "ài", "ai", Head.a, 'a'),
......
}
训练模型
将Map构建成双数组树`trie.build(map)``,可查看:HanLP — 双数组字典树 (Double-array Trie) 实现原理 -- 代码 + 图文,看不懂你来打我
public void build(TreeMap<String, V> map)
{
// 把值保存下来
v = (V[]) map.values().toArray();
l = new int[v.length];
Set<String> keySet = map.keySet();
// 构建二分trie树
addAllKeyword(keySet);
// 在二分trie树的基础上构建双数组trie树
buildDoubleArrayTrie(keySet);
used = null;
// 构建failure表并且合并output表
constructFailureStates();
rootState = null;
loseWeight();
}
保存模型
通过 saveDat(path, trie, map.entrySet()); 生成模型文件
static boolean saveDat(String path, AhoCorasickDoubleArrayTrie<Pinyin[]> trie, Set<Map.Entry<String, Pinyin[]>> entrySet)
{
try
{
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(IOUtil.newOutputStream(path + Predefine.BIN_EXT)));
out.writeInt(entrySet.size());
for (Map.Entry<String, Pinyin[]> entry : entrySet)
{
Pinyin[] value = entry.getValue();
out.writeInt(value.length);
for (Pinyin pinyin : value)
{
out.writeInt(pinyin.ordinal());
}
}
trie.save(out);
out.close();
}
catch (Exception e)
{
logger.warning("缓存值dat" + path + "失败");
return false;
}
return true;
}
/**
* 持久化
*
* @param out 一个DataOutputStream
* @throws Exception 可能的IO异常等
*/
public void save(DataOutputStream out) throws Exception
{
out.writeInt(size);
for (int i = 0; i < size; i++)
{
out.writeInt(base[i]);
out.writeInt(check[i]);
out.writeInt(fail[i]);
int output[] = this.output[i];
if (output == null)
{
out.writeInt(0);
}
else
{
out.writeInt(output.length);
for (int o : output)
{
out.writeInt(o);
}
}
}
out.writeInt(l.length);
for (int length : l)
{
out.writeInt(length);
}
}
加载模型
// path = data/dictionary/pinyin/pinyin.txt
static boolean loadDat(String path)
{
ByteArray byteArray = ByteArray.createByteArray(path + Predefine.BIN_EXT);
if (byteArray == null) return false;
int size = byteArray.nextInt();
Pinyin[][] valueArray = new Pinyin[size][];
for (int i = 0; i < valueArray.length; ++i)
{
int length = byteArray.nextInt();
valueArray[i] = new Pinyin[length];
for (int j = 0; j < length; ++j)
{
valueArray[i][j] = pinyins[byteArray.nextInt()];
}
}
if (!trie.load(byteArray, valueArray)) return false;
return true;
}
public boolean load(ByteArray byteArray, V[] value)
{
if (byteArray == null) return false;
size = byteArray.nextInt();
base = new int[size + 65535]; // 多留一些,防止越界
check = new int[size + 65535];
fail = new int[size + 65535];
output = new int[size + 65535][];
int length;
for (int i = 0; i < size; ++i)
{
base[i] = byteArray.nextInt();
check[i] = byteArray.nextInt();
fail[i] = byteArray.nextInt();
length = byteArray.nextInt();
if (length == 0) continue;
output[i] = new int[length];
for (int j = 0; j < output[i].length; ++j)
{
output[i][j] = byteArray.nextInt();
}
}
length = byteArray.nextInt();
l = new int[length];
for (int i = 0; i < l.length; ++i)
{
l[i] = byteArray.nextInt();
}
v = value;
return true;
}
计算
通过 HanLP — Aho-Corasick DoubleArrayTire 算法 ACDAT - 基于双数组字典树的AC自动机 找出汉字的拼音


调用
public static void main(String[] args)
{
String text = "重载不是重任";
List<Pinyin> pinyinList = HanLP.convertToPinyinList(text);
System.out.print("原文:");
for (char c : text.toCharArray())
{
System.out.printf("%c", c);
}
System.out.println();
System.out.print("拼音(数字音调):");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin);
}
System.out.println();
System.out.print("拼音(符号音调):");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getPinyinWithToneMark());
}
System.out.println();
System.out.print("拼音(无音调):");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getPinyinWithoutTone());
}
System.out.println();
System.out.print("声调:");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getTone());
}
System.out.println();
System.out.print("声母:");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getShengmu());
}
System.out.println();
System.out.print("韵母:");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getYunmu());
}
System.out.println();
System.out.print("输入法头:");
for (Pinyin pinyin : pinyinList)
{
System.out.printf("%s,", pinyin.getHead());
}
System.out.println();
}
输出:
原文:重载不是重任
拼音(数字音调):chong2,zai3,bu2,shi4,zhong4,ren4,
拼音(符号音调):chóng,zǎi,bú,shì,zhòng,rèn,
拼音(无音调):chong,zai,bu,shi,zhong,ren,
声调:2,3,2,4,4,4,
声母:ch,z,b,sh,zh,r,
韵母:ong,ai,u,i,ong,en,
输入法头:ch,z,b,sh,zh,r,
数据下载:http://download.hanlp.com/data-for-1.7.5.zip
HanLP — 汉字转拼音,简繁转换 -- JAVA的更多相关文章
- Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)
一.先摆需求: 1.中文搜索.英文搜索.中英混搜 如:"南京东路","cafe 南京东路店" 2.全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜 如 ...
- HanLP极致简繁转换详细讲解
HanLP极致简繁转换详细讲解 作者: hankcs(大快高级研究员 hanlp项目负责人) 谈起简繁转换,许多人以为是小意思,按字转换就行了.事实上,汉语历史悠久,地域复杂,发展至今在字符级别存在“ ...
- 汉语言处理工具pyhanlp的简繁转换
繁简转换 HanLP几乎实现了所有我们需要的繁简转换方式,并且已经封装到了HanLP中,使得我们可以轻松的使用,而分词器中已经默认支持多种繁简格式或者混合.这里我们不再做过多描述. 说明: ·Ha ...
- [原创]使用OPENCC库进行简繁转换(C++代码)
最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...
- SQL简繁转换函数
declare @jall nvarchar(4000),@fall nvarchar(4000) select @jall=N'啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊 ...
- javascript 简繁转换
js 简繁转换 function copy(ob) { var obj=findObj(ob); if (obj) { obj.select();js=obj.createTextRange();js ...
- JavaScript 使用穷举方式实现内容简繁转换
场景: 在Web开发中,有时存在对内容进行简体和繁体互相转换的需求,这时我们可以参考以下做法. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 ...
- js搞定网页的简繁转换
对网页进行简繁字体转换的方法一般有两种:一是使用<简繁通>这样的专业软件,另外一种是制作两套版本的网页.显然,这两种方法都较为麻烦,而且专业软件一般不能用于免费的空间.笔者在这里给大家提供 ...
- Python 轻量化简繁转换
最近项目中用到了简单的简繁转换,如果用OpenCC太重了,于是搜到了 zhconv 这个库. zhconv 提供基于 MediaWiki 词汇表的最大正向匹配简繁转换,Python 2, 3 通用. ...
- Office WORD如何简繁转换
选中要转换的文字,工具-语言,中文简繁转换.
随机推荐
- springboot实现反向代理,动态代理目标地址
网上找了很多文章,各种照搬,只能自己实现 基于开源项目HTTP-Proxy-Servlet实现 开源项目地址:https://github.com/mitre/HTTP-Proxy-Servlet 1 ...
- oracle、达梦数据库、MySQL数据创建表与字段注释
/**1.oracle注释*//*表本身注释*/comment on table 表名 is '注释信息';/*字段注释*/comment on column 表名.字段名 is '注释信息';/*实 ...
- 数据库同步工具,PanguSync后起之秀
随着数字化时代的快速发展,数据已经成为企业运营的核心.为了确保数据的准确性和一致性,数据库同步工具成为了企业不可或缺的工具.而在众多数据库同步工具中,PanguSync以其卓越的性能和强大的功能,逐渐 ...
- LeetCode15:三数之和(双指针)
解题思路:常规解法很容易想到O(n^3)的解法,但是,n最大为1000,很显然会超时. 如何优化到O(n^2),a+b+c =0,我们只需要判断 a+b的相反数是否在数组中出现,而且元素的取值范围在 ...
- Mongodb数据增删改查
RDB:数据库 → 表(列) → 行 Mongo:数据库 → 集合 → 文档 SQL和Mongodb的关系映射表(里面还有一些增删改查等等操作与SQL的对应的语句): https://www.mong ...
- python操作mongodb实现读写分离
读写分离 默认情况下,MongoClient 实例将查询发送到副本集的主要成员. 要使用副节点作为查询,以实现读写分离,我们必须更改读取首选项: 读取首选项在模块pymongo.ReadPrefere ...
- 安装华企盾DSC防泄密软件造成CAD2012卡住怎么办?
将下图目录的.exe程序删除或者重命名
- npm 发布流程
登录npm 查看本地是否登录 # 全局配置源 npm who am i # 官方源 npm who am i --registry https://registry.npmjs.org 注: npm源 ...
- UE5: 探究Actor Tick的注册与执行
1. 前情提要 因工作需要,有在编辑器模式下执行Actor的Tick函数的需求.经过查阅资料,了解到重载Actor::ShouldTickIfViewportOnly函数可以实现在编辑器视口下也可以执 ...
- 创建傀儡进程svchost.exe并注入DLL文件(Shellcode)
本文主要利用 SetThreadContext 修改进程中的线程上下文来实现Dll注入(ShellCode). 实现原理 首先,使用 CreateProcess 函数创建svchost.exe进程,并 ...