问题 如何确定普通话的Levenshtein距离?


我们正在开发一种系统,使用UTF-8,UTF-16和UTF-32 Unicode字符标准对50多种国际语言进行模糊匹配。到目前为止,我们已经能够使用Levenshtein距离来检测德语Unicode扩展字符单词的拼写错误。

我们希望扩展这个系统来处理用Unicode表示的普通话中文表意文字。我们如何在相似的汉字之间进行Levenshtein距离计算?


7954
2017-09-12 02:56


起源

是的 - 汉字存储在Basic Multilingual Plane中,所以只需使用 char16_t 它应该足够大以适应它们。 - oldrinb
虽然,请注意它不会让你'相似的字符',只是'类似的短语'。 - nneonneo
@OP你确定'c ++'标签是正确的吗? - jogojapan
@oldrind,谢谢你的回复。我们将尝试char16_t。 - Frank
为了最大限度的正确性:汉字不是由基本多语言平面表示的(即它们必须被编码为UCS-4,或者被编码为UTF-16中的两个16位字符的序列)。它们很少见,即使是中文,但它们确实存在。有一个与此相关的漂亮问题: stackoverflow.com/questions/5567249/... - jogojapan


答案:


首先,只是为了澄清:汉字并不等同于德语或英语 。大多数你认为是单词的东西(使用“单词”的语义或句法定义)由1-3个字符组成。通过将Levenshtein距离表示为UCS-2或UCS-4代码点的序列,可以直接将Levenshtein距离应用于这些字符序列。由于大多数单词很短(特别是长度为1或2个字符的单词),但它的用途可能有限。

但是,正如你的问题具体是关于 编辑之间的距离 个性人物,我认为需要采用不同的方法,确实可能非常困难。

首先,您必须将每个字符表示为它所包含的组件/笔画的序列。有两个问题:

  • 有些组件本身甚至更小 组件,所以如何将一个字符分解为“原子”组件并不是唯一定义的。如果你做到了个人的水平 ,你需要描述每一个笔画(角色,形状,方向等位置)。我不认为每个人都这样做(如果有人告诉我,我会感兴趣)。

  • 你需要将笔画或组件放入 订购。明显的候选者是角色的规范笔画顺序,在lexica中有描述,甚至还有带有动画笔画顺序图的字典网站。但是,我所知道的数据源(日语)生成这些动画作为位图图形的序列;我从未见过以适合编辑距离计算的形式表示笔画序列(甚至是单个笔画名称)的人或机器可读代码。

但是,你可以尝试的最后一件事就是渲染角色 字形 并根据计算编辑距离 多少像素 (或向量)需要更改为将一个字符转换为另一个字符。我曾经在OCR后期校正的背景下对拉丁字符和字符组合(以像素为基础)这样做,结果非常令人鼓舞。


快速回答larsmans评论如下:Unicode标准定义了两个相关的概念(在下面我指的是 6.0版,第12章):

  1. 基于部首和中风计数的指数。每个汉字都由几个部分组成,  其中激进的。基础/笔划计数索引是按部首排序的字符列表(即,共享同一基团的所有字符组合在一起),并且每个基础特定组在内部按字符的其余部分中使用的笔划数排序。不幸的是,即使这不是唯一的定义 - 有些字符的根本由不同的传统词汇定义不同,并且笔画计数也可能很难。以下是Unicode标准所说的内容:

    为了加快在代码表中定位特定的汉字表意字符,Unicode网站上提供了基本笔画索引。 [...]   对激进中风信息最有影响力的权威是十八世纪   康熙字典,其中包含214个激进分子。今天使用康熙激进派的主要问题是许多简化字符很难在214中的任何一个下进行分类   康熙激进分子。结果,引入了各种现代激进集。然而,没有一个是普遍使用的,214康熙的激进分子仍然是最知名的。 [...]   Unicode激进笔画图基于康熙激进派。 Unicode标准   遵循许多不同来源进行根治性卒中分类。两个来源   对于给定角色的激进或笔画计数存在争议,角色在激进笔画图中的两个位置都显示出来。

    请注意,即使我们假设激进/笔划索引是明确和正确的,它也不足以作为将字符转换为组件序列的信息源,因为完全描述的字符的唯一组成部分是激进。

  2. 表意描述序列(第12.2节):Unicode定义了字符基本组件的代码点(大多数字符本身可以用作独立字符),并且有一些代码点用于将这些代码点粘合在一起形成一系列描述构成一个更复杂的角色。所以这种方式类似于 结合人物,但有重要的区别:

    1. 组件的顺序不是唯一定义的
    2. 对于这样的序列没有定义渲染机制
    3. 没有从普通字符到相应的表意描述序列的映射(尽管标准提到这种映射在某种程度上存在于它们用于编译汉字符集的源中)。

    标准建议使用表意描述序列来描述任何现有代码点都没有表示的复杂或罕见的特征;但它明确地不鼓励使用描述序列代替普通字符:

    特别是,表意文字描述序列不应用于提供替代方案   数据交换中编码的表意文字的图形表示。搜索,整理,   然后,其他基于内容的文本操作将失败。


16
2017-09-12 03:20



jogojapan,谢谢你的回复。我接受了你的回答。 - Frank
(亚洲语言noob在这里,好奇心问)没有任何Unicode规范化可以给出某种角色的基线分解吗? - Fred Foo
@larsmans有趣的一点。我添加了一些我知道的参考文献。 - jogojapan
迷人!我可以看到为什么定义编辑距离对中国人来说很难。但是,通过强加任意一个,例如,例如,订单问题不是很容易解决的。基于代码点? - Fred Foo
@larsmans嗯...如果我们假设每个组件实际上都有一个代码点(如果我们下降到可能不是这种情况的笔划级别),那么,基于代码点的顺序可能反映得不够好字符看起来像(我认为我们的编辑距离测量应考虑到这一点,我猜)。例如坂和板是相似的(它们的右边是相同的),但如果我们分别将它们分解为土+反和木+反,那么那应该是顺序。但是基于代码点的顺序可能会将第二个顺序更改为反+木,从而不必要地增加编辑距离。 - jogojapan