# Fuzzy String Matching In Python

data-science

text-analysis

nlp

As a data scientist, you are forced to retrieve information from various sources by either leveraging publicly available API’s, asking for data, or by simply scraping your own data from a web page. All this information is useful if we are able to combine it and not have any duplicates in the data. But how do we make sure that there are no duplicates?

I know … *“duh! you can just use a function that retrieves all the unique _information thus removing duplicates”*. Well, that’s one way, but our function probably can’t tell that a name like *“Barack Obama”* is the same as *“Barack H. Obama”* right? (Assuming we were retrieving names of the most famous people in the world). We can clearly tell that these names are different but they are probably referring to the same person. So, how do we match these names?

This is where Fuzzy String Matching comes in. This post will explain what Fuzzy String Matching is together with its use cases and give examples using Python’s Library *Fuzzywuzzy*.

**Fuzzy Logic**

Fuzzy(adjective): difficult to perceive; indistinct or vague -Wikipedia

Fuzzy logic is a form of multi-valued logic that deals with reasoning that is approximate rather than fixed and exact. Fuzzy logic values range between 1 and 0. i.e the value may range from completely true to completely false. In contrast, * Boolean Logic* is a two-valued logic: true or false usually denoted 1 and 0 respectively, that deals with reasoning that is fixed and exact. Fuzzy logic tends to reflect how people think and attempts to model our decision making hence it is now leading to new intelligent systems(expert systems).

So, if we are comparing two strings using fuzzy logic, we would be trying to answer the question *“How similar are string A and string B?”, and rephrasing it as “Are string A and String B the same?”* when using the Boolean Logic.

#### Fuzzy String Matching

Fuzzy String Matching, also known as Approximate String Matching, is the process of finding strings that approximately match a pattern. The process has various applications such as *spell-checking*, *DNA analysis and detection,* spam detection, *plagiarism detection e.t.c*

#### Introduction to *Fuzzywuzzy* in Python

**Fuzzywuzzy** is a python library that uses **Levenshtein Distance** to calculate the differences between sequences and patterns that was developed and also open-sourced by SeatGeek, a service that finds events from all over the internet and showcase them on one platform. The big problem they were facing was the labeling of the same events as stated on their blog. This is the same as the example I gave at the beginning of the post where an entity such as a person’s name can be labelled differently on different sources.

##### Installation

To install the library, you can use pip:

```
pip install fuzzywuzzy
pip install python-Levenshtein
```

##### Examples

First we have to import the fuzzywuzzy modules:

```
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
```

Now, we can get the similarity score of two strings by using the following methods; ratio() or partial_ratio():

```
fuzz.ratio("Catherine M Gitau","Catherine Gitau")
91
```

```
fuzz.partial_ratio("Catherine M. Gitau","Catherine Gitau")
100
```

You’re probably wondering why the scores are different. This is because the fuzz.ratio() method just calculates the edit distance between some ordering of the token in both input strings using the `difflib.ratio.`

You can find out more about the difflib.ratio here. The ** fuzz.partial_ratio()** takes in the shortest string, which in this case is “Catherine Gitau” (length 14) , then matches it with all the sub-strings of length(14) in “Catherine M. Gitau” which means matching with “Catherine Gitau” which gives 100%. You can play around with the strings until you get the gist.

What if we switched up two names in one string? In the following example, I’ve interchanged the name “Catherine Gitau” to “Gitau Catherine” .Let’s see the scores:

```
fuzz.ratio("Catherine M Gitau","Gitau Catherine")
55
fuzz.partial_ratio("Catherine M. Gitau","Gitau Catherine")
60
```

We see that both methods are giving out low scores, this can be rectified by using ** token_sort_ratio()** method. This method attempts to account for similar strings that are out of order. Example, if we used the above strings:

```
fuzz.token_sort_ratio("Catherine Gitau M.", "Gitau Catherine")
94
```

As you can see, we get a high score of 94.

#### Conclusion

This article has introduced Fuzzy String Matching which is a well known problem that is built on Leivenshtein Distance. From what we have seen, it calculates how similar two strings are. This can also be calculated by finding out the number of operations needed to transform one string to the other .e.g with the name “Barack”, one might spell it as “Barac”. Only one operation is needed to correct this i.e adding a K at the end. You can try this out using the *stringdist* library in **r** as such:

```
adist("Barack", "Barac")
[1]
```

#### Sources

Fuzzy string matching in Python

Till next time:)