<p>I have got a simple contacts database but I'm having problems with users entering in duplicate data. I have implemented a simple data comparison but unfortunately the duplicated data that is being entered is not exactly the same. For example, names are incorrectly spelled or one person will put in 'Bill Smith' and another will put in 'William Smith' for the same person.</p>

<p>So is there some sort of algorithm that can give a percentage for how similar an entry is to another?</p>

[{'answer_id': 31501, 'author': 'Kevin Lamb', 'author_id': 3149, 'author_profile': 'https://Stackoverflow.com/users/3149', 'pm_score': 2, 'selected': False, 'text': "<p>While I do not have an algorithm for you, my first action would be to take a look at the process involved in entering a new contact. Perhaps users do not have an easy way to find the contact they are looking for. Much like on Stack Overflow's new question form, you could suggest contacts that already exist on the new contact screen.</p>\n"}, {'answer_id': 31510, 'author': 'dmckee --- ex-moderator kitten', 'author_id': 2509, 'author_profile': 'https://Stackoverflow.com/users/2509', 'pm_score': 2, 'selected': False, 'text': '<p>I imagine that this problem is well understood but what occurs to me on first reading is:  </p>\n\n<ul>\n<li>compare fields individually</li>\n<li>count those that match (for a possibly loose definition of match, and possibly weighing the fields differently)</li>\n<li>present for human intervention any cases which pass some threshold</li>\n</ul>\n\n<p>Use your existing database to get a good first guess for the threshold, and correct as you accumulate experience.</p>\n\n<p>You may prefer a fairly strong bias toward false positives, at least at first.</p>\n'}, {'answer_id': 31516, 'author': 'Peter Hoffmann', 'author_id': 720, 'author_profile': 'https://Stackoverflow.com/users/720', 'pm_score': 3, 'selected': False, 'text': '<p>You can compare the names with the <a href="http://en.wikipedia.org/wiki/Levenshtein_distance" rel="noreferrer">Levenshtein distance</a>. If the names are the same, the distance is 0, else it is given by the minimum number of operations needed to transform one string into the other.</p>\n'}, {'answer_id': 31518, 'author': 'Jon Limjap', 'author_id': 372, 'author_profile': 'https://Stackoverflow.com/users/372', 'pm_score': 2, 'selected': False, 'text': '<p>This may or may not be related but, minor misspellings might be detected by a <a href="http://en.wikipedia.org/wiki/Soundex" rel="nofollow noreferrer">Soundex search</a>, e.g., this will allow you to consider Britney Spears, Britanny Spares, and Britny Spears as duplicates.</p>\n\n<p>Nickname contractions, however, are difficult to consider as duplicates and I doubt if it is wise. There are bound to be multiple people named Bill Smith and William Smith, and you would have to iterate that with Charles->Chuck, Robert->Bob, etc.</p>\n\n<p>Also, if you are considering, say, Muslim users, the problems become more difficult (there are too many Muslims, for example, that are named Mohammed/Mohammad).</p>\n'}, {'answer_id': 31526, 'author': 'jason saldo', 'author_id': 1293, 'author_profile': 'https://Stackoverflow.com/users/1293', 'pm_score': 2, 'selected': False, 'text': '<p>If you have access SSIS check out the Fuzzy grouping and Fuzzy lookup transformation.</p>\n\n<p><a href="http://www.sqlteam.com/article/using-fuzzy-lookup-transformations-in-sql-server-integration-services" rel="nofollow noreferrer">http://www.sqlteam.com/article/using-fuzzy-lookup-transformations-in-sql-server-integration-services</a></p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/ms137786.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/ms137786.aspx</a></p>\n'}, {'answer_id': 31548, 'author': 'Matt Sheppard', 'author_id': 797, 'author_profile': 'https://Stackoverflow.com/users/797', 'pm_score': 1, 'selected': False, 'text': '<p>I\'m not sure it will work well for the names vs nicknames problem, but the most common algorithm in this sort of area would be the <a href="http://en.wikipedia.org/wiki/Levenshtein_distance" rel="nofollow noreferrer">edit distance / Levenshtein distance</a> algorithm. It\'s basically a count of the number of character changes, additions and removals required to turn one item into another.</p>\n\n<p>For names, I\'m not sure you\'re ever going to get good results with a purely algorithmic approach - What you really need is masses of data. Take, for example, how much better Google spelling suggestions are than those in a normal desktop application. This is because Google can process billions of web queries and look at what queries lead to each other, what \'did you mean\' links actually get clicked etc.</p>\n\n<p>There are a few companies which specialise in the name matching problem (mostly for national security and fraud applications). The one I could remember, Search Software America seems to have been bought out by these guys <a href="http://www.informatica.com/products_services/identity_resolution/Pages/index.aspx" rel="nofollow noreferrer">http://www.informatica.com/products_services/identity_resolution/Pages/index.aspx</a>, but I suspect any of these sorts of solutions would be far to expensive for a contacts application.</p>\n'}, {'answer_id': 34181, 'author': 'Tyler', 'author_id': 3561, 'author_profile': 'https://Stackoverflow.com/users/3561', 'pm_score': 2, 'selected': False, 'text': '<p>If you have a large database with string fields, you can very quickly find a lot of duplicates by using the <a href="http://scholar.google.com/scholar?q=simhash" rel="nofollow noreferrer">simhash</a> algorithm.</p>\n'}, {'answer_id': 39695, 'author': 'Tnilsson', 'author_id': 4165, 'author_profile': 'https://Stackoverflow.com/users/4165', 'pm_score': 3, 'selected': False, 'text': '<blockquote>\n  <p>So is there some sort of algorithm\n  that can give a percentage for how\n  similar an entry is to another?</p>\n</blockquote>\n\n<p>Algorithms as Soundex and Edit distances (as suggested in a previous post) can solve some of your problems. However, if you are serious about cleaning your data, this will not be enough. As others have stated "Bill" does not sound anything like "William".</p>\n\n<p>The best solution I have found is to use a reduction algorithm and table to reduce the names to it\'s root name. </p>\n\n<p>To your regular Address table, add Root-versions of the names, e.g\nPerson (Firstname, RootFirstName, Surname, Rootsurname....)</p>\n\n<p>Now, create a mapping table.\nFirstNameMappings (Primary KEY Firstname, Rootname)</p>\n\n<p>Populate your Mapping table by:\nInsert IGNORE (select Firstname, "UNDEFINED" from Person) into FirstNameMappings</p>\n\n<p>This will add all firstnames that you have in your person table together with the RootName of "UNDEFINED"</p>\n\n<p>Now, sadly, you will have to go through all the unique first names and map them to a RootName. For example "Bill", "Billl" and "Will" should all be translated to "William"\nThis is very time consuming, but if data quality really is important for you I think it\'s one of the best ways. </p>\n\n<p>Now use the newly created mapping table to update the "Rootfirstname" field in your Person table. Repeat for surname and address. Once this is done you should be able to detect duplicates without suffering from spelling errors. </p>\n'}, {'answer_id': 108527, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>You might also want to look into probabilistic matching.  </p>\n'}, {'answer_id': 11422531, 'author': 'DougB', 'author_id': 244112, 'author_profile': 'https://Stackoverflow.com/users/244112', 'pm_score': 1, 'selected': False, 'text': '<p>FullContact.com has API\'s that can solve this for you, see their documentation here: <a href="http://www.fullcontact.com/developer/docs/?category=name" rel="nofollow">http://www.fullcontact.com/developer/docs/?category=name</a>.</p>\n\n<p>They have APIs for Name Normalization (Bill into William), Name Deducer (for raw text), and Name Similarity (comparing two names).</p>\n\n<p>All APIs are free at the moment, it could be a good way to get started.</p>\n'}, {'answer_id': 56507233, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>For those wandering around the web and end up here, might I suggest that you try using a Google Sheet add-on I created called Flookup.\nIt\'s particularly good with names and it has a couple of other awesome features which I\'ll describe below:</p>\n\n<ol>\n<li>Say you have a list of names and there are 2 people called "John Smith". You can use the <code>rank</code> parameter from Flookup to instruct the algorithm to return the 1st, 2nd, 3rd or nth best match. This is helpful if you have additional information that you can use to identify the "John Smith" you want.</li>\n<li>Say you have an additional database/list of apartment numbers. You an specify which "John Smith" you want by typing: <code>John Smith &amp; Apartment A</code> or <code>John Smith &amp; Apartment B</code> as the lookup parameter to help distinguish between the two names.</li>\n</ol>\n\n<p>I hope you find Flookup as beneficial as others have.</p>\n'}]
['https://Stackoverflow.com/questions/31494', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/486/']