Python에서 퍼지 문자열 일치
오늘은 파이썬에서 퍼지 문자열 매칭을 할 수 있게 해주는 thefuzz
라이브러리를 사용하는 방법에 대해 알아보겠습니다. 또한 퍼지 문자열 논리의 도움으로 문자열을 효율적으로 일치시키거나 추출할 수 있는 프로세스
모듈을 사용하는 방법을 배웁니다.
thefuzz
모듈을 사용하여 Python에서 퍼지 문자열 일치
이 라이브러리는 이름이 변경된 특정 이름을 가지고 있기 때문에 이전 버전과 함께 재미있는 이름을 가지고 있습니다. 이제 유지 관리되는 다른 저장소입니다. 그러나 현재 버전은 thefuzz
이므로 아래 명령에 따라 설치할 수 있습니다.
pip install thefuzz
그러나 온라인에서 예제를 보면 fuzzywuzzy
라는 이전 이름을 가진 몇 가지 예제를 찾을 수 있습니다. 따라서 더 이상 유지 관리되지 않고 구식이지만 해당 이름을 가진 몇 가지 예를 찾을 수 있습니다.
thefuzz
라이브러리는 python-Levenshtei
를 기반으로 하므로 이 명령을 사용하여 설치해야 합니다.
pip install python-Levenshtein
그리고 설치 중 문제가 발생하면 다음 명령을 사용할 수 있으며, 다시 오류가 발생하면 Google에서 검색하여 관련 솔루션을 찾을 수 있습니다.
pip install python-Levenshtein-wheels
정규식을 사용하거나 두 문자열을 따라 문자열을 비교하는 것과 같이 본질적으로 퍼지 일치하는 문자열입니다. 퍼지 논리의 경우 조건의 진리값은 0
과 1
사이의 실수가 될 수 있습니다.
따라서 기본적으로 True
또는 False
라고 말하는 대신 0
에서 1
사이의 값을 지정하는 것입니다. 거리 메트릭을 사용하여 거리라는 값의 형태로 두 문자열 간의 비유사도를 계산하여 계산됩니다.
주어진 문자열을 사용하여 일부 알고리즘을 사용하여 두 문자열 사이의 거리를 찾습니다. 설치 프로세스를 완료하면 thefuzz
모듈에서 fuzz
및 process
를 가져와야 합니다.
from thefuzz import fuzz, process
fuzz
를 사용하기 전에 두 문자열 간의 차이점을 수동으로 확인합니다.
ST1 = "Just a test"
ST2 = "just a test"
print(ST1 == ST2)
print(ST1 != ST2)
부울 값을 반환하지만 퍼지 방식으로 이러한 문자열이 얼마나 유사한지에 대한 백분위수를 얻습니다.
False
True
퍼지 문자열 일치를 사용하면 퍼지 방식으로 보다 효율적이고 빠르게 이 작업을 수행할 수 있습니다. 두 개의 문자열이 있는 하나의 예제가 있고 하나의 문자열이 대문자 J
와 동일하지 않다고 가정합니다(위에 제공된 대로).
이제 유사성에 대한 메트릭을 제공하는 ratio()
함수를 호출하면 100
중 91
이라는 매우 높은 비율을 제공합니다.
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%를 얻었습니다. This
와 generation
이라는 두 개의 토큰이 두 문자열에 모두 존재하기 때문입니다.
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_ratio
를 scorer
인수로 전달합니다.
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)]
이것은 매우 정확하며 퍼지 방식으로 찾아야 하는 프로젝트가 있는 경우 매우 유용할 수 있습니다. 또한 이를 사용하여 절차를 자동화할 수 있습니다.
github 및 stackoverflow를 사용하여 추가 도움말을 찾을 수 있는 추가 리소스가 있습니다.
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