Python에서 퍼지 문자열 일치

Salman Mehmood 2023년10월10일
  1. thefuzz 모듈을 사용하여 Python에서 퍼지 문자열 일치
  2. process 모듈을 사용하여 퍼지 문자열 일치를 효율적으로 사용
Python에서 퍼지 문자열 일치

오늘은 파이썬에서 퍼지 문자열 매칭을 할 수 있게 해주는 thefuzz 라이브러리를 사용하는 방법에 대해 알아보겠습니다. 또한 퍼지 문자열 논리의 도움으로 문자열을 효율적으로 일치시키거나 추출할 수 있는 프로세스 모듈을 사용하는 방법을 배웁니다.

thefuzz 모듈을 사용하여 Python에서 퍼지 문자열 일치

이 라이브러리는 이름이 변경된 특정 이름을 가지고 있기 때문에 이전 버전과 함께 재미있는 이름을 가지고 있습니다. 이제 유지 관리되는 다른 저장소입니다. 그러나 현재 버전은 thefuzz이므로 아래 명령에 따라 설치할 수 있습니다.

pip install thefuzz

그러나 온라인에서 예제를 보면 fuzzywuzzy 라는 이전 이름을 가진 몇 가지 예제를 찾을 수 있습니다. 따라서 더 이상 유지 관리되지 않고 구식이지만 해당 이름을 가진 몇 가지 예를 찾을 수 있습니다.

thefuzz 라이브러리는 python-Levenshtei를 기반으로 하므로 이 명령을 사용하여 설치해야 합니다.

pip install python-Levenshtein

그리고 설치 중 문제가 발생하면 다음 명령을 사용할 수 있으며, 다시 오류가 발생하면 Google에서 검색하여 관련 솔루션을 찾을 수 있습니다.

pip install python-Levenshtein-wheels

정규식을 사용하거나 두 문자열을 따라 문자열을 비교하는 것과 같이 본질적으로 퍼지 일치하는 문자열입니다. 퍼지 논리의 경우 조건의 진리값은 01 사이의 실수가 될 수 있습니다.

따라서 기본적으로 True 또는 False라고 말하는 대신 0에서 1 사이의 값을 지정하는 것입니다. 거리 메트릭을 사용하여 거리라는 값의 형태로 두 문자열 간의 비유사도를 계산하여 계산됩니다.

주어진 문자열을 사용하여 일부 알고리즘을 사용하여 두 문자열 사이의 거리를 찾습니다. 설치 프로세스를 완료하면 thefuzz 모듈에서 fuzzprocess를 가져와야 합니다.

from thefuzz import fuzz, process

fuzz를 사용하기 전에 두 문자열 간의 차이점을 수동으로 확인합니다.

ST1 = "Just a test"
ST2 = "just a test"
print(ST1 == ST2)
print(ST1 != ST2)

부울 값을 반환하지만 퍼지 방식으로 이러한 문자열이 얼마나 유사한지에 대한 백분위수를 얻습니다.

False
True

퍼지 문자열 일치를 사용하면 퍼지 방식으로 보다 효율적이고 빠르게 이 작업을 수행할 수 있습니다. 두 개의 문자열이 있는 하나의 예제가 있고 하나의 문자열이 대문자 J와 동일하지 않다고 가정합니다(위에 제공된 대로).

이제 유사성에 대한 메트릭을 제공하는 ratio() 함수를 호출하면 10091이라는 매우 높은 비율을 제공합니다.

from thefuzz import fuzz, process

print(fuzz.ratio(ST1, ST2))

출력:

91

예를 들어 문자열이 더 긴 경우, 예를 들어 한 문자만 변경하는 것이 아니라 완전히 다른 문자열을 변경하면 반환되는 내용을 확인하고 살펴보십시오.

ST1 = "This is a test string for test"
ST2 = "There aresome test string for testing"
print(fuzz.ratio(ST1, ST2))

이제 아마도 약간의 유사성이 있을 것입니다. 그러나 상당히 75일 것입니다. 이것은 단순한 비율일 뿐이며 복잡하지 않습니다.

75

계속해서 부분 비율과 같은 것을 시도할 수도 있습니다. 예를 들어 점수를 결정하려는 두 개의 문자열이 있습니다.

ST1 = "There are test"
ST2 = "There are test string for testing"
print(fuzz.partial_ratio(ST1, ST2))

partial_ratio()를 사용하면 이 두 문자열이 동일한 하위 문자열(There are test)을 가지기 때문에 100%를 얻습니다.

ST2에서는 몇 가지 다른 단어(문자열)가 있지만 부분 비율 또는 개별 부분을 보는 것이기 때문에 중요하지 않지만 간단한 비율은 유사하게 작동하지 않습니다.

100

비슷하지만 순서가 다른 문자열이 있다고 가정해 보겠습니다. 그런 다음 다른 메트릭을 사용합니다.

CASE_1 = "This generation rules the nation"
CASE_2 = "Rules the nation This generation"

두 가지 경우에는 해당 문구의 동일한 의미에 대한 정확한 텍스트가 있지만 ratio()를 사용하는 것은 상당히 다르며 partial_ratio()를 사용하는 것은 다릅니다.

token_sort_ratio()를 사용하면 기본적으로 정확한 단어이지만 순서가 다르기 때문에 100%가 됩니다. 따라서 이것은 token_sort_ratio() 함수가 개별 토큰을 가져와서 정렬하는 것입니다. 어떤 순서로 오는지는 중요하지 않습니다.

print(fuzz.ratio(CASE_1, CASE_2))
print(fuzz.partial_ratio(CASE_1, CASE_2))
print(fuzz.token_sort_ratio(CASE_1, CASE_2))

출력:

47
64
100

이제 어떤 단어를 다른 단어로 변경하면 여기에 다른 숫자가 표시되지만 본질적으로 이것은 비율입니다. 개별 토큰의 순서는 신경쓰지 않습니다.

CASE_1 = "This generation rules the nation"
CASE_2 = "Rules the nation has This generation"

print(fuzz.ratio(CASE_1, CASE_2))
print(fuzz.partial_ratio(CASE_1, CASE_2))
print(fuzz.token_sort_ratio(CASE_1, CASE_2))

출력:

44
64
94

token_sort_ratio()도 단어가 더 많기 때문에 다르지만 token_set_ratio()라는 항목도 있고 집합에는 각 토큰이 한 번만 포함됩니다.

따라서 얼마나 자주 발생하는지는 중요하지 않습니다. 예제 문자열을 살펴보겠습니다.

CASE_1 = "This generation"
CASE_2 = "This This generation generation generation generation"

print(fuzz.ratio(CASE_1, CASE_2))
print(fuzz.partial_ratio(CASE_1, CASE_2))
print(fuzz.token_sort_ratio(CASE_1, CASE_2))
print(fuzz.token_set_ratio(CASE_1, CASE_2))

꽤 낮은 점수를 볼 수 있지만 token_set_ratio() 함수를 사용하여 100%를 얻었습니다. Thisgeneration이라는 두 개의 토큰이 두 문자열에 모두 존재하기 때문입니다.

process 모듈을 사용하여 퍼지 문자열 일치를 효율적으로 사용

프로세스가 도움이 되고 컬렉션에서 이 퍼지 매칭을 사용하여 추출할 수 있기 때문에 퍼즈뿐만 아니라 프로세스도 있습니다.

예를 들어 시연할 몇 가지 목록 항목을 준비했습니다.

Diff_items = [
    "programing language",
    "Native language",
    "React language",
    "People stuff",
    "This generation",
    "Coding and stuff",
]

그들 중 일부는 매우 유사합니다. (모국어 또는 프로그래밍 언어) 볼 수 있으며 이제 계속해서 최상의 개별 일치 항목을 선택할 수 있습니다.

점수를 평가한 다음 최고의 선택을 선택하여 수동으로 수행할 수 있지만 프로세스를 사용하여 수행할 수도 있습니다. 이를 위해서는 process 모듈에서 extract() 함수를 호출해야 합니다.

첫 번째는 대상 문자열이고, 두 번째는 추출할 컬렉션이고, 세 번째는 일치 또는 추출을 2개로 제한하는 제한입니다.

예를 들어 언어와 같은 것을 추출하려는 경우 이 경우 모국어와 프로그래밍 언어가 선택되었습니다.

print(process.extract("language", Diff_items, limit=2))

출력:

[('programing language', 90), ('Native language', 90)]

문제는 이것이 NLP(자연어 처리)가 아니라는 것입니다. 이것 뒤에 지능이 없습니다. 개별 토큰만 봅니다. 예를 들어 프로그래밍을 대상 문자열로 사용하고 이를 실행하면 됩니다.

첫 번째 일치 항목은 프로그래밍 언어이지만 두 번째 일치 항목은 코딩이 아닌 네이티브 언어입니다.

의미론에서 코딩이 프로그래밍에 더 가깝기 때문에 코딩이 있지만 여기서는 AI를 사용하지 않기 때문에 중요하지 않습니다.

Diff_items = [
    "programing language",
    "Native language",
    "React language",
    "People stuff",
    "Hello World",
    "Coding and stuff",
]

print(process.extract("programing", Diff_items, limit=2))

출력:

[('programing language', 90), ('Native language', 36)]

또 다른 마지막 예는 이것이 어떻게 유용할 수 있는지입니다. 우리는 방대한 책 라이브러리를 가지고 있고 책을 찾고 싶지만 정확히 이름이나 이름을 어떻게 부를 수 있는지 모릅니다.

이 경우 extract()를 사용할 수 있으며 이 함수 내에서 fuzz.token_sort_ratioscorer 인수로 전달합니다.

LISt_OF_Books = [
    "The python everyone volume 1 - Beginner",
    "The python everyone volume 2 - Machine Learning",
    "The python everyone volume 3 - Data Science",
    "The python everyone volume 4 - Finance",
    "The python everyone volume 5 - Neural Network",
    "The python everyone volume 6 - Computer Vision",
    "Different Data Science book",
    "Java everyone beginner book",
    "python everyone Algorithms and Data Structure",
]


print(
    process.extract(
        "python Data Science", LISt_OF_Books, limit=3, scorer=fuzz.token_sort_ratio
    )
)

우리는 그냥 통과하고 있습니다. 우리는 그것을 부르지 않고 이제 여기서 최고의 결과를 얻었고 두 번째 결과로 또 다른 데이터 과학 책을 얻었습니다.

출력:

[('The python everyone volume 3 - Data Science', 63), ('Different Data Science book', 61), ('python everyone Algorithms and Data Structure', 47)]

이것은 매우 정확하며 퍼지 방식으로 찾아야 하는 프로젝트가 있는 경우 매우 유용할 수 있습니다. 또한 이를 사용하여 절차를 자동화할 수 있습니다.

githubstackoverflow를 사용하여 추가 도움말을 찾을 수 있는 추가 리소스가 있습니다.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn