汉字相似度的计算思路
汉字本身的结构非常的复杂,可以通过结构进行计算。
汉字的结构
相似度计算算法
实现方式
首先人工做基本的 level 相似度分组,然后在这个基础之上,进行全自动识别。
汉字的形式化描述
汉字部件
在国家颁发的 GB13000.1字符集汉字部首归部规范 , 列出了20902 个汉字的部件表 , 对这些汉字进行了逐个拆分 。
从 中选定了560 个基础部件, 基础部件间可通过位置相互组合生成汉字。
为了描述方便 , 对部件重新给出定义。
定义 1
原子部件表示不能再被分解的部 件, 如 “ 王”“ 一” “ 东” “日” 等。
显然 , 独体字符合原子部件定义。
特别地,用“ ’ 表示特殊的原子部件, 称之为空部件 , 它不代表任何具体的部件, 仅为了计算的方便。
本文选定的 560 个基础部件都属于原子部件。
定义 2
复合部件由原子部件组成的部件。
如“ 想” “ 箱”“ 厢” 中的“ 相” , “ 赢” 中的“ 月贝凡” 等。
本文对选定的原子部件进行了编号, 将原子部件集合表示 为A = ( w1, w2, w3 , ⋯, wn), 表示部件。
集合中各部件之间的相似度通过人工分类和定义, 由此构成了 m × m 的原子部件相似矩阵:
汉字表达式
对于左中右结构, 按“ 左” 和“ 中右” 进行划分, “ 中右” 又是一个左右结构 , 即左中右结构可看成由两个左右结构嵌套而成 ,
对于上中下结构 , 按先“ 上” 和“ 中下” 进行划分, “ 中下” 进一步划分为上下结构, 上下结构可看成 由两个上下结构嵌套而成。
对于汉字, 按二分法切分, 对每一类结构中的每一个成分又可以看做原子部件或这11种结构之一的复合字, 如此递归切分, 直至二分法的每个成分都是原子部件。
由结构操作符和切分所得部件构成的字符序列就成为了汉字表达式, 同数学表达式一样, 汉字表达式也可以表示为中缀式、 前缀式和后缀式三种。
中缀式符合人们的思维习惯, 但不利于算法实现, 本文采用前缀表达式表示汉字。
表 2 列出了一些汉字的前缀式汉字表达式。
汉字字形相似度计算模型
为量化两个汉字之间的相似度, 引入f(A, B)表示相似度计算函数, 定义为
其中: A1 、 A2 表示汉字A 按第一层结构划分得到的字首部件和字尾部件;
B1 和 B2 表示汉字 B 按第一层结构划分得到的字首部件和字尾部件;
Q(A , B )表示部件A 与部件 B 的首层结构约束函数,定义为:
对部件的笔画计算 , 需要在定义部件集时提供各部件的笔画信息 , 以便在统计笔画时直接引用。
对部件数的计算可以直接从部件字形表达式中统计得到, 规则为:
a)若字形表达式长度大于 1, 部件数等于非操作符字符数;
b)若字形表达式长度等于 1, 部件数等于0。
特别地 , 对于空部件, 笔画数为0 , 部件数为0,长度为1
从式(1)中看出, 相似性计算过程是一个递归过程。
显然, 相似度计算满足这样的结论 , 两个汉字的最大相似度为 1,两个汉字的最小相似度为 0, 即 0 ≤ f(A , B )≤1。
简单证 明一下, 当A 和 B 同为原子部件时, A 和 B 的相似性由已定义的部件相似矩阵决定, 相似矩阵任何元素的取值 Wq显示介于 O 和 1之间, 结论成立;
当 A 和 B 其一为原子部件, 其一为复合部件时, 由定义可知 , A 和 B 的相似度为0;
当 A 和 B 同时为复合部件时 f( A , B )最大取值 1。
此时 a/2 + b/2 = 1, 由于 Q (A , B) = 1, 固 max(f(A,B)) = 1, 同理, 不难求 出最小值 min(f( A , B))为 0。
汉字字形相似度算法
汉字相似度计算是一个逐渐细化 , 递归切分计算的过程。
重要操作是汉字表达式切分, 对于一个前缀表达式而言, 首先要从右至左扫描表达式 , 从右边第一个字符开始判断, 如果当前字符是部件利用栈记录下来 , 如果是结构操作符 , 则连接右 边离得最近的两个部件 , 以此作为一个新的部件并记录下来。
一直扫描到表达式的最左端结构操作符时终止, 最后栈中两个串就是切分后的两个子表达式。
算法 1
算法说明: Strlen 函数用于求取字符串长度, IsO per ator 函数实现判断给定字符是否为操作符, St ack 用于记录切分字符串, PUSH 和 POP 为人栈和出栈操作, St rcat函数实现字符串的连接 。
算法 2
算法说明: Similar 函数实现从相似矩阵中返回指定部件的相似系数, Q 函数实现判断两个部件的首层结构是否相似, S 函数实现子部件对父部件相似性的支持度。
为验证算法的有效性 , 本文挑选了 100 组形近字, 用本文算法计算并推荐出每组 中最相似的一对汉字。
同时, 随机请2O 个人分别对每组形近字挑选出最相似字, 对每组形近字取得票最多的一对汉字为最终人工推荐结果, 通过对比算法推荐和人工推荐结果, 吻合度达 98%。
数据的来源
爬虫获取百度字典
对应的人民日报词库
对应的搜狗输入法词库
其他常用各种 nlp 比赛的词库
这里推荐 新华字典
抓取信息
-
偏旁部首
-
汉字结构
-
笔画数
-
全码表
参考别人的算法
四码相似度
# 定义四码相似度
code_index = 0
# 四码分为四位计算,若相同则指数+1,不同为0,总权数除以4再加权
for _i in range(4):
if code1[_i] == code2[_i]:
code_index += 1
code_index /= 4
核心算法
# 笔画数利用相对偏差的方式进行计算
write_num_index = 1- abs((write_num1 - write_num2)/max(write_num1,write_num2))
# 四码权重、笔画权重和结构权重分别为为 0.4 0.3 0.3
write_index = code_index * 0.4 + write_num_index * 0.3 + structure_index * 0.3
similarity_index_ = write_index * 0.5 + voice_index * 0.5
- 偏旁部首
引入偏旁部首,权重最高。
- 权重建议
偏旁部首 0.4
四码权重 0.4
结构权重 0.3
笔画权重 0.3
读音权重 0.2
这里还考虑了读音,本实现决定不考虑读音,只看外形。
(还是加上,相同外形,读音相似的优先级更高。)
读音相同
相同读音 && 外形 > 0.6
外形 > 0.9
四码说明
四角号码在线查询(四角号码查字法)收录了2万多个汉字的四角号码,支持汉字查询四角号码或通过四角号码反查汉字。
比如你不知道“四角号码”这几个汉字的四角号码是多少,在查询框中输入“四角号码”后按回车即可,即可查得这几个汉字分别的四角号码。
如果查询的字串中包含了非汉字字符,系统会自动将其滤掉,只列出其中包含的汉字的四角号码,非常方便实用。
四角号码,汉语词典常用检字方法之一,用最多5个阿拉伯数字来对汉字进行归类。
四角号码检字法由王云五发明,并在1925年5月著《号码检字法》由商务印书馆出版。四角号码检字法用数字0到9表示一个汉字四角的十种笔形,有时在最后增加一位补码。
四角号码检字法歌谣:横一垂二三点捺,叉四插五方框六;七角八八九是小,点下有横变零头。
取码规则
号码 | 名称 | 笔形 |
---|---|---|
0 | 头 | 亠(独立的点横组合,横笔带折钩者不算。) |
1 | 横 | 一乚(横、挑、右钩) |
2 | 垂 | 丨丿亅(直、撇、左钩) |
3 | 点 | 丶(点、捺) |
4 | 叉 | 十乂(两笔相交叉) |
5 | 插 | 扌(一笔插入两笔以上,被插的笔画不算) |
6 | 方 | 口(四边齐整,笔端不外伸。) |
7 | 角 | ﹁「」﹂(横与垂相接处,但其两端不作角。) |
8 | 八 | 八丷人(两笔成八形,且不与他笔交叉。) |
9 | 小 | 小忄⺌(两笔中隔一笔成小形。中间有两笔,或有一旁有两笔不作小。) |
源码参考
参考资料
paper
Blogs
http://www.wanfangdata.com.cn/details/detail.do?_type=conference&id=6345830
https://www.cnblogs.com/xyqiu90-365/p/9702349.html
http://ling.whu.edu.cn/law/002/index_3.html