2013-06-09 1 views
1

Как реализовать расстояние levenshtein на записях в таблице базы данных с помощью python? Я знаю, как подключать python с базой данных, кодирование в python может быть не проблемой, и у меня также есть записи в таблице базы данных. Я понимаю теорию и динамическое программирование левенштейновского расстояния. Проблема здесь в том, как написать коды таким образом, что после подключения к таблице базы данных я могу сравнить две записи, содержащие до трех полей и вывести их оценку подобия. Ниже snipet моей таблицы базы данных:Реализация Levenshtein на записи базы данных с использованием python

Запись 1:
Автор: Michael I Джеймс
Название: Продвижение в сети
Journal: ACM

Запись 2: Автор: Michael J Inse
Название: Продвижение в сети
Journal: ACM

Любые идеи приветствуются. Я новичок в этой области, попробуйте объяснить немного деталей. Спасибо.

+0

Некоторые базы данных предоставляют функцию 'levenshtein()', например [PostgreSQL fuzzystrmatch module] (http://www.postgresql.org/docs/9.2/static/fuzzystrmatch.html) – mvp

+0

@Korylprince, спасибо за ваш ответ . Мне удалось получить доступ и запросить записи базы данных из python. Я рассмотрел несколько кодов, написанных на python для вычисления расстояния levenshtein. Я не знаю, как применять код в записях и получить оценки подобия. Записи более 20 000 в числе Я также намерен загрузить расширение python-levenshtein distance C, которое я узнал, быстрее и проще реализовать , – Tiger1

+0

@ Tiger1 Этот сайт больше посвящен вопросам о конкретных проблемах с кодом, которые у вас возникают. Попробуйте использовать этот модуль и получите код. Если у вас есть проблемы с конкретным кодом, вы должны отправить его. – korylprince

ответ

1

Мое понимание проблемы заключается в том, что вам нужно идентифицировать очень похожие записи, которые потенциально дублируются. Я бы решил это в самой базе данных. Не нужно программировать. Если у вас нет функции Levenshtein, доступной в вашей БД, вы можете создать пользовательскую функцию.

Вот пример для MySQL:

CREATE FUNCTION `levenshtein`(s1 VARCHAR(255), s2 VARCHAR(255)) RETURNS int(11) DETERMINISTIC 
BEGIN  
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT; 
    DECLARE s1_char CHAR; 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 

Тогда вам нужно сравнить все записи друг друга. Это требует самостоятельного полного соединения, что, конечно, может быть немного тяжелым. Если вы слишком тяжелы, вам нужно будет идти по пути Python, что позволит вам избежать повторений (сравните разные времена с одними и теми же записями).

Вот что я хотел бы сделать. Обратите внимание, что я предпочел бы использовать идентификатор для облегчения идентификации:

SELECT a.ID AS IDa, 
    b.ID AS IDb, 
    a.Author AS AuthorA, 
    b.Author AS AuthorB, 
    ap.levenshtein(a.Author, b.Author) AS Lev_Aut, 
    a.Title AS TitleA, b.Title AS TitleB, ap.levenshtein(a.Title, b.Title) AS Lev_Title, 
    a.Journal AS JounalA , b.Journal AS JournalB, ap.levenshtein(a.Journal, b.Journal) AS Lev_Journal, 
    ap.levenshtein(a.Author, b.Author) + ap.levenshtein(a.Title, b.Title) + ap.levenshtein(a.Journal, b.Journal) AS Composite 
FROM test.zzz AS a, test.zzz AS b 
WHERE a.ID != b.ID 
ORDER BY 8; 

вернуться бы список значений Левенштейна заказанного из лучшего матча к худшей (композитной колонке). Условие позволяет избежать записи, которую нужно сравнить с самим собой.