두 문자열 사이의 유사성 메트릭 찾기


284

파이썬에서 문자열이 다른 문자열과 비슷할 확률을 어떻게 얻습니까?

0.9 (90 %를 의미하는) 등의 10 진수 값을 얻고 싶습니다. 표준 Python 및 라이브러리를 사용하는 것이 좋습니다.

예 :

similar("Apple","Appel") #would have a high prob.

similar("Apple","Mango") #would have a lower prob.

6
나는 "확률"이 여기서 올바른 용어라고 생각하지 않습니다. 어쨌든 stackoverflow.com/questions/682367/…
NPE

1
찾고있는 단어는 확률이 아니라 비율입니다.
인바 로즈

1
해밍 거리를 살펴보십시오 .
다이아나

2
문구는 '유사성 메트릭' 이지만 여러 유사성 메트릭 (Jaccard, Cosine, Hamming, Levenshein 등)이 있으므로 어느 것을 지정해야한다고 말했습니다. 특히 문자열 간의 유사성 메트릭을 원합니다. @hbprotoss는 여러 개를 나열했습니다.
smci

답변:


544

내장되어 있습니다.

from difflib import SequenceMatcher

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

그것을 사용 :

>>> similar("Apple","Appel")
0.8
>>> similar("Apple","Mango")
0.0

43
비교하는이 위대한 답변을 참조 SequenceMatcherpython-Levenshtein모듈을. stackoverflow.com/questions/6690739/…
ssoler

1
흥미로운 기사와 도구 : chairnerd.seatgeek.com/…
Anthony Perot

7
내가보기 엔 전체 difflib의 문서를 체크 아웃하는 것이 좋습니다 docs.python.org/2/library/difflib.html 거기 get_close_matches내가 발견하지만, 내장을 sorted(... key=lambda x: difflib.SequenceMatcher(None, x, search).ratio(), ...)더 신뢰할 수있는 사용자 정의와 sorted(... .get_matching_blocks())[-1] > min_match검사
ThorSummoner

2
@ThorSummoner는 매우 유용한 기능 ( get_closest_matches)에 주목합니다 . 그것은 당신이 찾고있는 편의 기능입니다. AKA는 문서를 읽었습니다! 내 특정 응용 프로그램에서 나는 잘못된 입력을 제공하는 사용자에게 기본적인 오류 확인 /보고를하고 있었고이 답변을 통해 잠재적 인 일치 "유사성"이 무엇인지 보고 할 수 있습니다 . 당신이 유사성을 표시 할 필요가없는 경우,하지만 확실히 체크 아웃get_closest_matches
svenevs

이것은 완벽하게 작동했습니다. 간단하고 효과적입니다. 감사합니다 :)
Karthic Srinivasan


46

솔루션 # 1 : 파이썬 내장

difflib 에서 SequenceMatcher 사용

장점 : 네이티브 파이썬 라이브러리, 별도의 패키지가 필요 없습니다.
단점 : 너무 제한적이며 문자열 유사성을위한 다른 좋은 알고리즘이 많이 있습니다.

:
>>> from difflib import SequenceMatcher
>>> s = SequenceMatcher(None, "abcd", "bcde")
>>> s.ratio()
0.75

솔루션 # 2 : 해파리 라이브러리

적용 범위가 좋고 문제가 거의없는 매우 훌륭한 라이브러리입니다. 그것은 지원
- Levenshtein 거리
- Damerau - Levenshtein 거리
- JARO의 거리
- JARO - 윈 클러 거리
- 경기 평가 접근법 비교
- 해밍 거리

장점 : 사용하기 쉽고 지원되는 알고리즘의 범위가 테스트되었습니다.
단점 : 네이티브 라이브러리가 아닙니다.

:

>>> import jellyfish
>>> jellyfish.levenshtein_distance(u'jellyfish', u'smellyfish')
2
>>> jellyfish.jaro_distance(u'jellyfish', u'smellyfish')
0.89629629629629637
>>> jellyfish.damerau_levenshtein_distance(u'jellyfish', u'jellyfihs')
1

26

Fuzzy Wuzzy파이썬에서 Levenshtein 거리를 구현 하는 패키지 이며, 두 가지 별개의 문자열을 동일하게 고려하려는 특정 상황에서 도움이되는 도우미 함수가 있습니다. 예를 들면 다음과 같습니다.

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    91
>>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    100

9

다음과 같은 함수를 만들 수 있습니다.

def similar(w1, w2):
    w1 = w1 + ' ' * (len(w2) - len(w1))
    w2 = w2 + ' ' * (len(w1) - len(w2))
    return sum(1 if i == j else 0 for i, j in zip(w1, w2)) / float(len(w1))

하지만 비슷한 ( 'appel', 'apple')이 비슷한 ( 'appel', 'ape')보다 높습니다
tenstar

1
함수는 주어진 문자열을 다른 찌르기와 비교합니다. 가장 높은 유사성 비율로 문자열을 반환하는 방법을 원합니다
answerSeeker

1
@SaulloCastro if self.similar(search_string, item.text()) > 0.80:는 지금 작동합니다. 감사합니다
answerSeeker


6

내장 SequenceMatcher은 큰 입력에서 매우 느립니다. diff-match-patch 로 수행하는 방법은 다음과 같습니다.

from diff_match_patch import diff_match_patch

def compute_similarity_and_diff(text1, text2):
    dmp = diff_match_patch()
    dmp.Diff_Timeout = 0.0
    diff = dmp.diff_main(text1, text2, False)

    # similarity
    common_text = sum([len(txt) for op, txt in diff if op == 0])
    text_length = max(len(text1), len(text2))
    sim = common_text / text_length

    return sim, diff

5

참고 difflib.SequenceMatcher 이 예를 들어, 요구되는없는 것을 종종 가장 긴 연속 일치하는 시퀀스를 찾습니다

>>> a1 = "Apple"
>>> a2 = "Appel"
>>> a1 *= 50
>>> a2 *= 50
>>> SequenceMatcher(None, a1, a2).ratio()
0.012  # very low
>>> SequenceMatcher(None, a1, a2).get_matching_blocks()
[Match(a=0, b=0, size=3), Match(a=250, b=250, size=0)]  # only the first block is recorded

두 스트링 사이의 유사성을 찾는 것은 생물 정보학에서의 쌍별 서열 정렬 개념과 밀접한 관련이있다. biopython을 포함하여 이것에 대한 많은 전용 라이브러리가 있습니다 . 이 예제는 Needleman Wunsch 알고리즘을 구현합니다 .

>>> from Bio.Align import PairwiseAligner
>>> aligner = PairwiseAligner()
>>> aligner.score(a1, a2)
200.0
>>> aligner.algorithm
'Needleman-Wunsch'

다양한 점수 체계와 알고리즘을 사용할 수 있으므로 biopython 또는 다른 생물 정보학 패키지를 사용하는 것이 Python 표준 라이브러리의 어느 부분보다 융통성이 있습니다. 또한 실제로 일어나는 일을 시각화하기 위해 일치하는 시퀀스를 얻을 수 있습니다.

>>> alignment = next(aligner.align(a1, a2))
>>> alignment.score
200.0
>>> print(alignment)
Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-
|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-
App-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-el

0

이 링크에서 대부분의 텍스트 유사성 방법과 계산 방법을 찾을 수 있습니다. https://github.com/luozhouyang/python-string-similarity#python-string-similarity 여기에 몇 가지 예가 있습니다.

  • 정규화, 메트릭, 유사성 및 거리

  • (정규화 된) 유사성과 거리

  • 미터 거리

  • 대상 포진 (n- 그램) 기반 유사성 및 거리
  • 레 벤슈 테인
  • 정규화 된 레 벤슈 테인
  • 가중 레 벤슈 테인
  • Damerau-Levenshtein
  • 최적의 문자열 정렬
  • 야로-윙클러
  • 가장 긴 공통 서브 시퀀스
  • 메트릭 가장 긴 공통 서브 시퀀스
  • N- 그램
  • 지붕 널 (n-gram) 기반 알고리즘
  • Q- 그램
  • 코사인 유사성
  • 자카드 색인
  • 소렌센 주사위 계수
  • 중복 계수 (Szymkiewicz-Simpson)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.