【问题标题】:OCR: weighted Levenshtein distanceOCR:加权 Levenshtein 距离
【发布时间】:2011-05-21 09:51:24
【问题描述】:

我正在尝试用字典创建一个光学字符识别系统。

事实上我还没有实现字典=)

我听说有一些基于 Levenstein 距离的简单指标,它考虑了不同符号之间的不同距离。例如。 'N' 和 'H' 彼此非常接近,并且 d("THEATRE", "TNEATRE") 应该小于 d("THEATRE", "TOEATRE") 使用基本 Levenstein 距离是不可能的。

您能帮我找到这样的指标吗?

【问题讨论】:

    标签: ocr metrics levenshtein-distance


    【解决方案1】:

    这可能是您正在寻找的内容:http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance(请在链接中包含一些工作代码)

    更新:

    http://nlp.stanford.edu/IR-book/html/htmledition/edit-distance-1.html

    【讨论】:

    • 不幸的是,这不是我想要的。无论如何,我已经以优异的成绩毕业了——我不再需要解决方案了=)
    • 这很奇怪,因为它的目的正是您所要求的。
    • hmmm.. 我浏览了你的链接。但我的理解是,他们只是增加了一项操作:转置。换位是指更改两个相邻符号时。如果我错了,您能否在维基页面上指定他们谈论不同字母之间不同距离的位置?
    • 不好意思那天看了很多链接,第二个需要结合看。
    【解决方案2】:

    这是一个示例 (C#),其中“替换字符”操作的权重取决于字符代码之间的距离:

          static double WeightedLevenshtein(string b1, string b2) {
            b1 = b1.ToUpper();
            b2 = b2.ToUpper();
    
            double[,] matrix = new double[b1.Length + 1, b2.Length + 1];
    
            for (int i = 1; i <= b1.Length; i++) {
                matrix[i, 0] = i;
            }
    
            for (int i = 1; i <= b2.Length; i++) {
                matrix[0, i] = i;
            }
    
            for (int i = 1; i <= b1.Length; i++) {
                for (int j = 1; j <= b2.Length; j++) {
                    double distance_replace = matrix[(i - 1), (j - 1)];
                    if (b1[i - 1] != b2[j - 1]) {
                        // Cost of replace
                        distance_replace += Math.Abs((float)(b1[i - 1]) - b2[j - 1]) / ('Z'-'A');
                    }
    
                    // Cost of remove = 1 
                    double distance_remove = matrix[(i - 1), j] + 1;
                    // Cost of add = 1
                    double distance_add = matrix[i, (j - 1)] + 1;
    
                    matrix[i, j] = Math.Min(distance_replace, 
                                        Math.Min(distance_add, distance_remove));
                }
            }
    
            return matrix[b1.Length, b2.Length] ;
        }
    

    你在这里看到它是如何工作的:http://ideone.com/RblFK

    【讨论】:

      【解决方案3】:

      晚了几年,但以下 python 包(我不隶属于它)允许对所有 Levenshtein 编辑操作和 ASCII 字符映射等进行任意加权。

      https://github.com/infoscout/weighted-levenshtein

      pip install weighted-levenshtein
      

      还有这个(也不是附属的):

      https://github.com/luozhouyang/python-string-similarity
      

      【讨论】:

      • 是否需要您创建完整的权重矩阵?有谁知道例如基本的ascii字符是否有任何合理的权重矩阵?不需要是完美的,但是对于诸如 [o O 0] 或 [i l 1] 之类的东西基本上具有较低的权重,而对于诸如 [o x] 之类的东西则具有更高的权重。
      • 您需要用 something 填充矩阵的每个元素,甚至是一些默认值。您的示例是特定于 OCR 的;键盘输入的元素会有所不同。问题是需要真实数据,即标记数据,这是劳动密集型的,因此公司不愿共享。 reCAPTCHA 就是一个例子。
      • 嗯,有很多开源资源,例如 Tesseract,它是一个完全开源的 OCR 引擎,具有经过训练的数据。它甚至还有一个模棱两可的字符列表:github.com/tesseract-ocr/langdata/blob/master/eng/… 不过,由于 OCR 的应用如此广泛,我仍然对 OSS 社区中不存在这样的事情感到惊讶。