Question: I'm looking for a gem or project that would let me identify that two names are the same person. For example

> 
> `J.R. Smith == John R. Smith == John Smith == John Roy Smith == Johnny Smith`
> 
> 
> 

I think you get the idea. I know nothing is going to be 100% accurate but I'd like to get something that at least handles the majority of cases. I know that last one is probably going to need a database of nicknames.

Answer: 
I think one option would be to use a ruby implementation of the [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance)

The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character.

Then you could define that names with a distance less than X (being X a number you will have to tweak) are from the same person.

**EDIT**
Through a little search I was able to find another algorithm, based on phonetics called [Metaphone](http://en.wikipedia.org/wiki/Metaphone) 

Still has a lot of holes in it, but I think that in this case the best everyone can do is to give you alternatives for you to test and see what works best
For anyone who has to try to match human names from different data sources, this is a VERY hard problem to address. Using a *combination* of 3 gems seems to do pretty well.

We have an application where we have a million people in List A, and need to match them with dozens of different data sources. (And despite what some of the more pedantic comments claim, that is not a 'design flaw' that is the nature of dealing with 'real world' messy data.)

The only thing we have found to work reasonably well thus far is using a combination of the `namae` gem (for parsing names into a standardize first, middle, last, suffix representation) and the `text` gem to calculate levenshtein, soundex, metaphone, and porter scores, AND also `fuzzy-string-match` which calculates the JaroWinkler score (which is often the best of the lot).

1. parse into a standard format separating last, first, middle, suffix using namae. We pre-process with a regex to extract nicknames when formatted `John "JJ" Doe` or `Samuel (Sammy) Smith`
2. calculate ALL scores on a sanitized version of the full name (all caps, remove punctuation, last name first) ... jarowinkler, soundex, levenshtein, metaphone, white, porter. (JaroWinkler and Soundex often do the best.)
3. declare a match if N scores exceed individually set thresholds. (We use any 2 that pass as a pass)
4. if no match, try again using only last name, first name, middle **initial**, with higher thresholds (eg, stricter matching).
5. Still no match, replace first name with nick name (if any) and try again.

With some tweaking of score thresholds for each scoring method, we get pretty good results. YMMV.

BTW putting last name first is very important, at least for JaroWinkler since there is generally less variation in last names (Smithe is almost always Smithe, but first name might be Tom or Tommy or Thomas in different data sources), and the beginning of the string is most 'sensitive' in JaroWinkler. For a "ROB SMITHE / ROBIN SMITHE, the JaroWinkler distance is 0.91 if you do first name first, but 0.99 if you do last name first.