1. 程式人生 > 其它 >關於文字糾錯之編輯距離

關於文字糾錯之編輯距離

技術標籤:NLP編輯距離文字相似MySQL演算法Levenshtein

一 編輯距離

目的糾錯。以下為百科介紹

Levenshtein 距離,又稱編輯距離,指的是兩個字串之間,由一個轉換成另一個所需的最少編輯操作次數。

許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。

編輯距離的演算法是首先由俄國科學家Levenshtein提出的,故又叫Levenshtein Distance。

演算法也是比較經典的,https://leetcode-cn.com/problems/edit-distance/

還是動態規劃實現。

理論部分到此結束

二落地

如果MYSQL資料量少,可以使用自定義的函式。程式碼如下:

DELIMITER $$
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
    RETURNS INT
    DETERMINISTIC
    BEGIN
        DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
        DECLARE s1_char CHAR;
        -- max strlen=255
        DECLARE cv0, cv1 VARBINARY(256);

        SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;

        IF s1 = s2 THEN
            RETURN 0;
        ELSEIF s1_len = 0 THEN
            RETURN s2_len;
        ELSEIF s2_len = 0 THEN
            RETURN s1_len;
        ELSE
            WHILE j <= s2_len DO
                SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
            END WHILE;
            WHILE i <= s1_len DO
                SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
                WHILE j <= s2_len DO
                    SET c = c + 1;
                    IF s1_char = SUBSTRING(s2, j, 1) THEN
                        SET cost = 0; ELSE SET cost = 1;
                    END IF;
                    SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
                    IF c > c_temp THEN SET c = c_temp; END IF;
                    SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
                    IF c > c_temp THEN
                        SET c = c_temp;
                    END IF;
                    SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
                END WHILE;
                SET cv1 = cv0, i = i + 1;
            END WHILE;
        END IF;
        RETURN c;
    END$$
DELIMITER ;

使用語法:SELECT * from test where levenshtein('品他病損害',name) BETWEEN 0 AND 3

可見這種模糊查詢的效果是like實現不了的。

但是能否線上落地,需要自己評估數量。因為畢竟是自定義函式。資料量少幾百條几千條OK,要是幾萬條得驗證下,很可能就是一個SQL10秒了。

我不推薦這種方式。資料庫掛了就因小失大了。

自己寫OK。也可以偷懶找個三方的庫。

推薦用apache的

這裡的quer就是查詢的,target就是字典的。假設無序的前提下暴力迴圈就好

          int sdistance = LevenshteinDistance.getDefaultInstance().apply(query, target);

具體distance的範圍,需要根據業務去做取捨。如果》3我覺得就偏差太多,難以起到糾錯的目的。

我們以醫院為例:假設目標有

首都兒科研究所

北京佑安醫院

String query = "首度兒科研究所";
System.out.println(EditDistanceUtil.match(query, str));

就能找到:首都兒科研究所

三 HammingDistance

漢明距離,提一下也不展開。在包括資訊理論、編碼理論、密碼學等領域都有應用。我理解是偏2個二進位制碼字之間的相似程度的。

我目前的感覺是,編輯距離是硬匹配。怎麼解釋下呢?就是沒有業界那種考慮上下文的好。

***************************

看到這裡了,如果對你有所幫助,就點個贊吧。