如何确定字符相似度?

时间:2012-05-03 14:38:12

标签: algorithm pattern-matching levenshtein-distance similarity

我使用Levenshtein距离在OCR之后找到类似的字符串。但是,对于某些字符串,编辑距离是相同的,尽管视觉外观明显不同。

例如,字符串Co将返回以下匹配项:

CY (1)
CZ (1)
Ca (1)

考虑到Co是来自OCR引擎的结果,Ca将比那些更可能匹配。因此,在计算Levenshtein距离之后,我想通过视觉相似性排序来改进查询结果。为了计算这种相似性,我想使用标准的sans-serif字体,比如Arial。

我是否有可以用于此目的的库,或者我如何自己实现?或者,是否有任何字符串相似性算法比Levenshtein距离更准确,我还可以使用它?

3 个答案:

答案 0 :(得分:5)

如果你正在寻找一张可以让你根据视觉相似度来计算各种“替换成本”的表格,我一直在寻找这样的东西,但收效甚微,所以我开始研究它作为一个新问题。我没有使用OCR,但我正在寻找一种方法来限制搜索参数的概率搜索 mis-typed 字符。由于他们是错误输入的,因为人类在视觉上混淆了角色,所以同样的原则应该适用于你。

我的方法是根据8位字段中的笔画成分对字母进行分类。这些位是从左到右:

7: Left Vertical
6: Center Vertical
5: Right Vertical
4: Top Horizontal
3: Middle Horizontal
2: Bottom Horizontal
1: Top-left to bottom-right stroke
0: Bottom-left to top-right stroke

对于小写字符,左侧的下行部分记录在第1位,而在第0位右侧的下行部分记录为对角线。

通过该方案,我想出了以下值,这些值试图根据视觉相似性对字符进行排名。

m:               11110000: F0
g:               10111101: BD
S,B,G,a,e,s:     10111100: BC
R,p:             10111010: BA
q:               10111001: B9
P:               10111000: B8
Q:               10110110: B6
D,O,o:           10110100: B4
n:               10110000: B0
b,h,d:           10101100: AC
H:               10101000: A8
U,u:             10100100: A4
M,W,w:           10100011: A3
N:               10100010: A2
E:               10011100: 9C
F,f:             10011000: 98
C,c:             10010100: 94
r:               10010000: 90
L:               10000100: 84
K,k:             10000011: 83
T:               01010000: 50
t:               01001000: 48
J,j:             01000100: 44
Y:               01000011: 43
I,l,i:           01000000: 40
Z,z:             00010101: 15
A:               00001011: 0B
y:               00000101: 05
V,v,X,x:         00000011: 03

就目前而言,这对我的目的而言过于原始,需要更多的工作。但是,您可以使用它,或者根据您的目的调整它。该计划相当简单。此排名适用于单声道空间字体。如果您使用的是无衬线字体,那么您可能需要重新处理这些值。

这个表是一个混合表,包括所有字符,小写和大写,但是如果你把它分成大写而小写只有它可能证明更有效,这也可以允许应用特定的大小写处罚。

请记住,这是早期的实验。如果您看到一种改进方法(例如通过更改位排序),请务必随意这样做。

答案 1 :(得分:2)

因此,在您的距离函数中,替换不同的字符对只需要不同的成本。

也就是说,而不是替换添加一个或两个设置成本而不考虑所涉及的字符 - 而是具有替换成本函数,其返回介于0.0和2.0之间的内容以替换成本在某些情况下的某些特征。

在记忆的每一步,只需调用此成本函数:

cost[x][y] = min(
    cost[x-1][y] + 1, // insert
    cost[x][y-1] + 1, // delete,
    cost[x-1][y-1] + cost_to_replace(a[x],b[y]) // replace
);

这是我的完整编辑距离实现,只需将replace_cost常量替换为replace_cost函数,如下所示:

https://codereview.stackexchange.com/questions/10130/edit-distance-between-two-strings

在实现cost_to_replace函数方面,您需要一个字符矩阵,其成本取决于字符的相似程度。可能会有这样的桌子浮动,或者您可以通过将每对字符写入一对图像然后使用标准视觉技术比较图像以获得相似性来自己实现它。

或者,您可以使用监督方法来纠正多个OCR误读,并记下表格中出现的情况,然后表格将成为上述成本表格。 (即如果OCR错误,则字符必须类似)。

答案 2 :(得分:2)

一般来说,我看到Damerau-LevenshteinLevenshtein更频繁地使用,它基本上添加了转置操作。它应该占人类拼写错误的80%以上,所以你当然应该考虑这一点。

至于你的具体问题,你可以很容易地修改算法,以便用非大写字母替换大写字母来增加成本,而相反的方法可以获得类似的东西:

dist(Co, CY) = 2
dist(Co, CZ) = 2
dist(Co, Ca) = 1
相关问题