[(‘Star Wars‘, 95), (‘Star Trek‘, 53)]
If you‘ve ever worked with text data, you know that comparing and matching strings is a common but surprisingly tricky task. Whether it‘s searching for similar documents, checking for plagiarism, linking records in a database, or cleaning up messy text fields, being able to quantify the similarity between two pieces of text is an important skill in natural language processing (NLP) and text analytics.
Fortunately, the FuzzyWuzzy Python library makes it easy to do fuzzy string matching with just a few lines of code. In this ultimate guide, we‘ll dive deep into what FuzzyWuzzy is, how it works under the hood, and how you can use it for a variety of practical applications.
What is FuzzyWuzzy?
FuzzyWuzzy is an open-source Python library for fuzzy string matching originally developed by SeatGeek, a ticket search engine company. It uses Levenshtein Distance to calculate the differences between strings and returns a "similarity ratio" on a scale from 0 to 100, where 100 means the strings are identical.
Unlike other string comparison methods that look for exact matches, FuzzyWuzzy uses fuzzy logic to determine the similarity between strings. This means it can handle cases like misspellings, abbreviations, and rearranged words that would trip up simpler matching algorithms.
The FuzzyWuzzy library was first released in 2011 and has steadily grown in popularity over the years. Today it has over 3,000 stars on GitHub and is used by many well-known companies and organizations including Mozilla, Zappos, and the U.S. Department of Veterans Affairs.
How FuzzyWuzzy Works
Under the hood, FuzzyWuzzy calculates string similarity using an algorithm called Levenshtein Distance (named after the Soviet mathematician Vladimir Levenshtein who first described it in 1965). Levenshtein Distance is defined as the minimum number of single-character edits needed to transform one string into another. These edits can include:
- Insertions: abc → abcd
- Deletions: abc → ac
- Substitutions: abc → abd
For example, the Levenshtein Distance between "kitten" and "sitting" is 3:
kitten → sitten (substitution of "s" for "k")
sitten → sittin (substitution of "i" for "e")
sittin → sitting (insertion of "g" at the end)
Once this "edit distance" is calculated, FuzzyWuzzy converts it into a similarity ratio by subtracting it from the length of the longer string and dividing by the length of the longer string:
ratio = (len(s1) + len(s2) – edit_distance) / max(len(s1), len(s2))
So if the edit distance between two strings is 3 and the longer string has 10 characters, the similarity ratio would be (10 + 10 – 3) / 10 = 0.85 or 85%. Pretty neat!
Here‘s a quick example of how you might use this basic ratio() function in Python:
from fuzzywuzzy import fuzz
string1 = "apple inc"
string2 = "apple inc."
string3 = "apple incorporated"
print(fuzz.ratio(string1, string2)) # 96
print(fuzz.ratio(string1, string3)) # 80
As you can see, FuzzyWuzzy correctly identifies that "apple inc" and "apple inc." are more similar than "apple inc" and "apple incorporated", even though it‘s only a difference of one character.
In addition to the basic ratio() function, FuzzyWuzzy provides several other useful string matching functions:
-
partial_ratio(): Calculates the similarity between the shorter string and the most similar substring of the longer string. This is useful for finding matches where one string may only be a part of the other.
-
token_sort_ratio(): Preprocesses the strings by splitting them into tokens (i.e. words), sorting the tokens alphabetically, and then joining them back together. This helps to match strings that have the same words but in a different order.
-
token_set_ratio(): Similar to token_sort_ratio() but only considers the unique tokens (words) in each string, ignoring duplicates and word order entirely. Useful for matching lists of keywords.
-
WRatio(): A custom weighted ratio that‘s especially good at dealing with alphanumeric strings. Takes into account both the similarity and the length difference between the strings.
Here‘s an example showing how these different functions handle messy strings:
from fuzzywuzzy import fuzz
string1 = "The quick brown fox jumped over the lazy dog"
string2 = "A speedy brown fox leapt over the lazy canine"
print(fuzz.ratio(string1, string2)) # 59
print(fuzz.partial_ratio(string1, string2)) # 69
print(fuzz.token_sort_ratio(string1, string2)) # 77
print(fuzz.token_set_ratio(string1, string2)) # 100
print(fuzz.WRatio(string1, string2)) # 74
As you can see, while the basic edit distance ratio only gives these strings a similarity of 59%, the token set ratio considers them a 100% match since they contain all the same words (even though the words appear in a different order). The partial ratio and token sort ratio fall somewhere in between, taking word order into account but not as strictly as the basic ratio function.
Applications and Use Cases
So what can you actually use FuzzyWuzzy for? As it turns out, fuzzy string matching is an important building block for all kinds of text analysis and NLP tasks. Here are a few common applications:
1. Checking for Text Similarity and Duplicates
One of the most straightforward uses of FuzzyWuzzy is to check whether two strings, documents, or text snippets are similar to each other. This is super handy for things like:
- Detecting plagiarism between student papers or website content
- Finding and eliminating duplicate database records
- Catching spam or sock puppet accounts based on username / display name similarity
- Identifying version-controlled files that only differ by a few lines of code
2. Fuzzy Searching
Another powerful application of fuzzy string matching is to build search engines that can handle misspellings, typos, and irregular naming conventions. With FuzzyWuzzy, you can easily search through a large corpus of text data to find strings that approximately match a given query, even if the query contains errors.
For example, let‘s say you have a database of movie titles like this:
movie_titles = [
‘Star Wars‘,
‘Star Trek‘,
‘The Godfather‘,
‘The Shawshank Redemption‘,
‘The Lord of the Rings: The Fellowship of the Ring‘,
‘Schindler‘s List‘,
…
]
A regular search for "Star Wars" would work fine, but if the user accidentally types "Satr Wars" or "Stra Wars", it wouldn‘t return anything.
With FuzzyWuzzy, you can easily add fuzzy search capabilities:
from fuzzywuzzy import process
query = "Stra Wars"
results = process.extract(query, movie_titles)
print(results)
Voila! The fuzzy search still returns "Star Wars" as the best match with a 95% similarity score, even with a typo in the search query.
You can use this same basic technique to power search features in all kinds of applications, from e-commerce websites to HR resume databases to legal discovery engines. Anywhere you have a large amount of unstructured text data, fuzzy matching can make your search results more robust and user-friendly.
3. Data Cleaning and Entity Resolution
Another powerful use case for fuzzy string matching is in data cleaning and entity resolution (also known as record linkage or deduplication). Data scientists spend a huge amount of time just preparing and normalizing text data before any actual analysis can be done. Fuzzy matching can automate a lot of this grunt work.
For example, let‘s say you have a huge customer database with millions of records, but the names and addresses were entered inconsistently over the years by different people. Some of the company names might be abbreviated ("IBM" vs "International Business Machines"), some of the street names might be misspelled, and so on.
To get an accurate picture of your customers, you need to resolve all of these different text strings that refer to the same real-world entities. This is where FuzzyWuzzy comes in. You can use it to cluster similar records together, identify the canonical name for each entity, and merge the duplicate records.
There are even some higher-level Python libraries like Dedupe that use FuzzyWuzzy under the hood to power more sophisticated entity resolution pipelines that can handle millions of records efficiently.
4. Evaluating NLP Models
In addition to being useful for data preprocessing and search applications, FuzzyWuzzy can also help you evaluate various NLP models and algorithms.
For instance, let‘s say you‘re building a text summarization tool and want to compare the output of different approaches. You can‘t just use an exact string comparison between the human-written reference summary and the machine-generated summaries, because even a single word or punctuation difference would tank the similarity score.
Instead, you can use FuzzyWuzzy‘s ratio() function to calculate the approximate similarity between the reference summary and each candidate summary:
from fuzzywuzzy import fuzz
reference_summary = "The quick brown fox jumps over the lazy dog."
candidate_summary_1 = "The fast brown fox jumps over the lazy canine."
candidate_summary_2 = "A quick brown fox leaps over the lazy dog."
candidate_summary_3 = "The story is about a brown fox and a lazy dog."
print(fuzz.ratio(reference_summary, candidate_summary_1)) # 86
print(fuzz.ratio(reference_summary, candidate_summary_2)) # 84
print(fuzz.ratio(reference_summary, candidate_summary_3)) # 57
Even though all three candidate summaries differ from the reference text, the first two are clearly more similar in meaning than the third one. The fuzzy matching scores reflect this, giving the first two candidates scores in the 80s while the third one only gets a 57.
You can also use FuzzyWuzzy to evaluate other common NLP tasks like:
-
Spelling correction: Compute the similarity between the original misspelled text and the automatically corrected version.
-
Machine translation: Compare the similarity of human-translated reference sentences vs. machine translations.
-
Keyphrase extraction: Check how closely the extracted keywords and phrases match the human-labeled gold standard references.
The possibilities are endless! Any time you need to approximately compare two pieces of text or measure an NLP model‘s performance, FuzzyWuzzy is a handy tool to have in your toolkit.
Tips and Caveats
While FuzzyWuzzy is very easy to use, there are a few things to keep in mind to get the most out of it:
-
Preprocess your text: Before doing any fuzzy matching, it‘s a good idea to standardize your text inputs as much as possible. Convert everything to lowercase, remove punctuation, expand abbreviations, etc. The cleaner your strings are, the better the matching results will be.
-
Use the right matching function: FuzzyWuzzy provides several different string matching algorithms, so choose the one that makes the most sense for your particular use case. When in doubt, try a few of them and see which gives the best results for your data.
-
Set a similarity threshold: To determine whether two strings should actually be considered a "match", you‘ll need to define a cut-off value for the similarity ratio. Typically a 80-90% ratio is a good starting point, but the optimal threshold will depend on your specific application and tolerance for false positives vs. false negatives.
-
Be mindful of performance: While FuzzyWuzzy is pretty fast, calculating similarity ratios between every pair of strings in a large dataset can still take a long time. If you‘re working with millions of strings, you may need to use some additional filtering, indexing, or parallel processing to make it feasible.
-
Use other libraries for more advanced NLP: FuzzyWuzzy is great for basic string similarity matching, but it‘s not a full-fledged natural language processing library. If you need to do more complex NLP tasks like part-of-speech tagging, named entity recognition, or sentiment analysis, you‘ll want to explore other libraries like spaCy, NLTK, or CoreNLP.
Final Thoughts
We‘ve covered a lot of ground in this guide to the FuzzyWuzzy library, from the underlying Levenshtein distance algorithm to real-world applications like entity resolution and information retrieval.
As you‘ve seen, fuzzy string matching is an incredibly powerful tool to have in your NLP and text analytics toolbox. With just a few lines of Python, you can unlock new insights from messy, unstructured text data and build more intelligent, fault-tolerant language processing systems.
Whether you‘re a data scientist, software engineer, or business analyst, learning how to leverage FuzzyWuzzy can help you wrangle text data more effectively and open up new possibilities for working with natural language.
So what are you waiting for? Install FuzzyWuzzy today and start experimenting with fuzzy matching in your own projects! As you gain more experience with the library, you‘re sure to find even more creative ways to apply it for your own use cases and domains.
Here are a few helpful resources to learn more:
- FuzzyWuzzy GitHub Repo: https://github.com/seatgeek/fuzzywuzzy
- Python-Levenshtein: https://github.com/ztane/python-Levenshtein/
- "FuzzyWuzzy: Fuzzy String Matching in Python" by SeatGeek: https://chairnerd.seatgeek.com/fuzzywuzzy-fuzzy-string-matching-in-python/
Happy fuzzy matching!