Високопродуктивне порівняння нечітких рядків у Python, використовуйте Левенштейн або дифліб [закрито]


128

Я роблю нормалізацію клінічного повідомлення (перевірку орфографії), в якій перевіряю кожне задане слово проти медичного словника 900 000 слів. Мене більше хвилює складність часу / продуктивність.

Я хочу зробити нечітке порівняння рядків, але я не впевнений, яку бібліотеку використовувати.

Варіант 1:

import Levenshtein
Levenshtein.ratio('hello world', 'hello')

Result: 0.625

Варіант 2:

import difflib
difflib.SequenceMatcher(None, 'hello world', 'hello').ratio()

Result: 0.625

У цьому прикладі обидва дають однакову відповідь. Як ви думаєте, обидва в цій справі працюють однаково?

Відповіді:


152

Якщо ви зацікавлені у швидкому візуальному порівнянні подібності Левенштейна та Діфліба, я підрахував обидві для ~ 2,3 мільйона назв книг:

import codecs, difflib, Levenshtein, distance

with codecs.open("titles.tsv","r","utf-8") as f:
    title_list = f.read().split("\n")[:-1]

    for row in title_list:

        sr      = row.lower().split("\t")

        diffl   = difflib.SequenceMatcher(None, sr[3], sr[4]).ratio()
        lev     = Levenshtein.ratio(sr[3], sr[4]) 
        sor     = 1 - distance.sorensen(sr[3], sr[4])
        jac     = 1 - distance.jaccard(sr[3], sr[4])

        print diffl, lev, sor, jac

Потім я побудував результати з R:

введіть тут опис зображення

Суворо для допитливих я також порівняв значення подібності Діфліба, Левенштайна, Соренсена та Жакарда:

library(ggplot2)
require(GGally)

difflib <- read.table("similarity_measures.txt", sep = " ")
colnames(difflib) <- c("difflib", "levenshtein", "sorensen", "jaccard")

ggpairs(difflib)

Результат: введіть тут опис зображення

Подібність Діфліба / Левенштайна справді є досить цікавою.

Редагування 2018 року: Якщо ви працюєте над визначенням схожих рядків, ви також можете перевірити міншашінг - тут чудовий огляд . Minhashing є дивовижним у знаходженні подібностей у великих колекціях тексту за лінійним часом. Моя лабораторія створила додаток, який виявляє та візуалізує повторне використання тексту за допомогою minhashing тут: https://github.com/YaleDHLab/intertext


2
Це супер круто! Що ви тоді ставитесь до цього? Невже Левенштейн поганий для рядків довжини заголовка?
Ульф Аслак

3
Це дійсно залежить від того, що ти намагаєшся зафіксувати у своїй метриці подібності ...
duhaime

2
Я думаю, що деякі розбіжності між дифлібом та левенштейном можуть бути пояснені через евристику аутодзюків, яку використовує дифліб. Що станеться, якщо ви відключите його?
Майкл

2
Це гарне запитання. Автоматичний фільтр набирає чинності лише в тому випадку, якщо кількість спостережень становить> 200, тому я не впевнений, чи вплинув би цей конкретний набір даних (назви книг), але варто розслідувати ...
duhaime

2
@duhaime, дякую за цей детальний аналіз. Я новачок у подібних сюжетах і не знаю, як їх інтерпретувати. Як називаються сюжети, щоб я міг їх переглянути і дізнатися про них?
Zach Young

104
  • difflib.SequenceMatcher використовує алгоритм Ratcliff / Obershelp , він обчислює подвоєну кількість відповідних символів, поділену на загальну кількість символів у двох рядках.

  • Левенштейн використовує алгоритм Левенштейна, він обчислює мінімальну кількість правок, необхідних для перетворення однієї рядки в іншу

Складність

SequenceMatcher - це квадратичний час для найгіршого випадку, і поведінка у очікуваному випадку складно залежить від того, скільки елементів мають послідовності. ( звідси )

Левенштейн - O (m * n), де n і m - довжина двох вхідних рядків.

Продуктивність

Відповідно до вихідного коду модуля Левенштейна: Левенштейн має деяке перекриття з дифлібом (SequenceMatcher). Він підтримує лише рядки, а не довільні типи послідовностей, але з іншого боку, це набагато швидше.


Дякую багато за інформацію. Я додав більше деталей. ось так: I am doing clinical message normalization (spell check) in which I check each given word against 900,000 word medical dictionary. I am more concern about the time complexity/performance.чи вважаєте ви, що обидва в цій справі працюють однаково.
Меггі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.