Python에서 고성능 퍼지 문자열 비교, Levenshtein 또는 difflib 사용 [닫기]


128

주어진 단어를 90 만 단어의 의학 사전과 비교하는 임상 메시지 정규화 (맞춤법 검사)를하고 있습니다. 나는 시간의 복잡성 / 성능에 대해 더 걱정합니다.

퍼지 문자열 비교를하고 싶지만 어떤 라이브러리를 사용해야할지 모르겠습니다.

옵션 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

Levenshtein과 Difflib 유사성에 대한 빠른 시각적 비교에 관심이있는 경우 두 가지 모두 230 만 권의 책 제목에 대해 계산했습니다.

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로 결과를 플로팅했습니다.

여기에 이미지 설명 입력

호기심을 자극하기 위해 Difflib, Levenshtein, Sørensen 및 Jaccard 유사성 값도 비교했습니다.

library(ggplot2)
require(GGally)

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

ggpairs(difflib)

결과: 여기에 이미지 설명 입력

Difflib / Levenshtein 유사성은 정말 흥미 롭습니다.

2018 편집 : 유사한 문자열을 식별하는 작업을하는 경우 minhashing을 확인할 수도 있습니다 . 여기에 훌륭한 개요가 있습니다 . Minhashing은 선형 시간에 큰 텍스트 컬렉션에서 유사점을 찾는 데 놀랍습니다. 내 연구실은 여기에 minhashing을 사용하여 텍스트 재사용을 감지하고 시각화하는 앱을 구성했습니다. https://github.com/YaleDHLab/intertext


2
이것은 매우 멋지다! 그렇다면 이것에 대해 어떻게 생각하십니까? Levenshtein은 제목 길이 문자열에 좋지 않습니까?
Ulf Aslak 2015

3
유사성 메트릭에서 캡처하려는 내용에 따라 다릅니다.
duhaime

2
difflib에서 사용하는 autojunk 휴리스틱 때문에 difflib와 levenshtein 사이의 일부 불일치가 설명 될 수 있다고 생각합니다. 비활성화하면 어떻게됩니까?
Michael

2
그건 좋은 질문이야. 관찰의 수> 200이면 난 그래서 autojunk 필터 만 적용됩니다하지 않도록이 특정 데이터 세트 (책 제목)를 크게 영향을받은 것인지, 그러나 그것의 가치 조사 ...
duhaime

2
@duhaime,이 상세한 분석에 감사드립니다. 나는 이런 종류의 플롯에 익숙하지 않으며 어떻게 해석해야할지 모릅니다. 플롯은 무엇이라고 불리며, 내가 찾아보고 배울 수 있습니까?
Zach Young

104
  • difflib.SequenceMatcher는 Ratcliff / Obershelp 알고리즘을 사용하여 일치하는 문자의 두 배를 두 문자열의 총 문자 수로 나눈 값을 계산합니다.

  • Levenshtein은 Levenshtein 알고리즘을 사용 하여 한 문자열을 다른 문자열로 변환하는 데 필요한 최소 편집 수를 계산합니다.

복잡성

SequenceMatcher는 최악의 경우에 대한 2 차 시간이며 시퀀스에 공통 요소가 몇 개 있는지에 따라 복잡한 방식으로 예상되는 경우 동작이 다릅니다. ( 여기에서 )

Levenshtein은 O (m * n)이며, 여기서 n과 m은 두 입력 문자열의 길이입니다.

공연

Levenshtein 모듈 의 소스 코드 에 따르면 Levenshtein은 difflib (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.이 경우 둘 다 똑같이 수행한다고 생각하십니까?
Maggie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.