Внедряване на Levenshtein върху записи на база данни с помощта на python

Как да внедря levenshtein разстояние върху записи в таблица на база данни с помощта на python? Знам как да свържа python с база данни, кодирането в python може да не е проблем и също така имам записите в таблица на база данни. Разбирам теорията и динамичното програмиране на разстоянието Левенщайн. Проблемът тук е как да напиша кодовете по такъв начин, че след като се свържа с таблицата на базата данни, да мога да сравня два записа с до три полета и да изведа техния резултат за сходство. По-долу е фрагмент от моята таблица с база данни:

Запис 1:
Автор: Michael I James
Заглавие: Напредък в мрежите
Журнал: ACM

Запис 2: Автор: Michael J Inse
Заглавие: Напредък в мрежите
Журнал: ACM

Всякакви идеи са добре дошли. Аз съм начинаещ в тази област, моля, опитайте се да обясните с малко подробности. Благодаря.


person Tiger1    schedule 09.06.2013    source източник
comment
някои бази данни осигуряват работеща levenshtein() функция, например PostgreSQL fuzzystrmatch модул   -  person mvp    schedule 09.06.2013
comment
@Korylprince, благодаря за отговора. Успях да осъществя достъп до записите в базата данни и да направя заявка от Python. Разгледах няколко кода, написани на python за изчисляване на разстоянието на левещайн. Това, което не знам, е как да приложа кода върху записите и да получа оценки за сходство.. Записите са над 20 000 на брой. Също така възнамерявам да изтегля разширение Python-levenshtein distance C, което научих, че е по-бързо и лесно за изпълнение.   -  person Tiger1    schedule 09.06.2013
comment
@Tiger1 този сайт е по-скоро за въпроси относно конкретни проблеми с кода, които имате. Опитайте да използвате този модул и вземете някакъв код. Ако имате проблем с конкретен код, трябва да публикувате тогава.   -  person korylprince    schedule 09.06.2013


Отговори (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, което ще ви позволи да избегнете повторения (сравнете различни пъти едни и същи записи).

Ето какво бих направил. Обърнете внимание, че предпочитам да използвам ID за по-лесна идентификация:

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;

Ще върне списък от стойности на Levenshtein, подредени от най-доброто съвпадение до най-лошото (съставната колона). Условието избягва сравняването на запис със себе си.

person Damien Goor    schedule 09.06.2013