learn-entity-resolution-with-phoebe / Session 2 of 6
Learn Entity Resolution with Phoebe · Session 2 of 6

Comparing strings honestly

Before any pair can be scored, "how similar are these two strings" needs an actual number. Tonight builds seven of them, from a 1965 edit-distance paper to a pair of 1918 patents, and pairs each one with the exact case where it is confidently wrong. That pairing is the whole session: a measure without its failure mode is a tool you will misuse in production.

🟠 Hands-on Data engineers Anyone merging two customer systems 45 min
0-3 · Welcome 3-24 · Seven ways to compare 24-40 · Build-along: break each measure 40-45 · Q&A
Part 0

Where we are

Session 1 established the shape of the problem: 63 Meridian records, 32 real people, 1,953 possible pairs, and no column that joins them. Every one of those pairs will eventually need a similarity score on each field before anything can be weighed. Tonight is where that number comes from. Session 3 turns these scores into evidence with weights, session 4 makes comparison affordable at scale, and session 5 judges the whole thing honestly.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. Seven similarity measures with their real definitions, the concrete case where each one lies to you, and a live lab where you type two strings and watch all seven recompute. You will also see why normalising data before comparing it is not a cleanup step, it is a bet with a real cost.

LiveWhy one number is never enough4 min▶

Ask a room to say whether "Katherine" and "Catherine" are the same name and most people say yes instantly. Ask them to say by how much and the room goes quiet, because similarity is not one thing. An edit-distance measure, a phonetic code and a token-overlap measure all answer a different question, and each was built to catch a different kind of typing mistake.

  • Positional measures care where in the string the difference sits, and how many character-level operations it takes to fix it.
  • Phonetic measures throw the spelling away entirely and compare how the word would sound if read aloud.
  • Token measures throw the order away and compare which words appear, which is exactly wrong for edit distance and exactly right for a name typed in the wrong order.
Real world

Meridian's CRM export has "Chen Robert" in one system because a form asked for surname first, and "Robert Chen" in the other. An edit-distance measure sees almost nothing in common between those two strings. A token measure sees the same two words and calls it identical. Neither answer is wrong, they are answering different questions.

Self-studyThe lab you will use all night3 min▶

Every number quoted from here on is read off the live widget lower in this page, not typed in by hand. Type any two strings into it and all seven measures recompute immediately, with the Soundex code for each printed underneath. Six presets are loaded to get you started - Katherine/Catherine, Mary Ann/Mray Ann, Robert Chen/Chen Robert, Thomas Muller/Thomas Mueller, Smith/Smyth, and Priya Nair/Priya Nayar - but the free-text boxes are the point. If a claim in this session sounds surprising, retype the pair yourself before you believe it.

Part 1 · covers the two edit distances

Counting the operations it takes to fix a string

7 min live

Edit distance answers a literal question: how many single-character operations turn one string into the other. The two measures below differ only in which operations they allow, and that one difference decides whether a transposed pair of letters looks like a small mistake or a large one.

LEVENSHTEIN - SUBSTITUTE AND INSERT/DELETE ONLY M r a y A n n sub r->a M a a y A n n sub a->r M a r y A n n cost 2 DAMERAU-LEVENSHTEIN - ADDS ONE TRANSPOSITION STEP M r a y A n n swap r,a M a r y A n n cost 1 - one adjacent-swap step Same two words, two different costs. Levenshtein has no transposition operation, so a swapped pair of letters must be paid for as a substitute plus a shift, doubling the apparent damage of the single most common typing slip. Type Mary Ann against Mray Ann in the lab below and read both scores off it directly.
🔍 Click to zoom - the only difference between the two measures is one operation, and it changes the score
LiveLevenshtein, and where it over-penalises4 min▶

Levenshtein distance (1965/66, published in Soviet Physics Doklady) is the minimum number of single-character insertions, deletions and substitutions needed to turn one string into the other. It is the oldest of tonight's measures and still the default most people reach for, because it needs no assumptions about language or pronunciation, only characters.

Its blind spot is exactly the mistake humans make most: swapping two adjacent letters. Levenshtein has no operation called "swap", so a transposition has to be expressed as a substitution plus an insertion or deletion, which prices it at 2 instead of the single slip it actually is. "Mary Ann" against "Mray Ann" is over-penalised for precisely this reason, and the lab below will show you the number.

Self-studyDamerau-Levenshtein closes one gap, not all of them4 min▶

Damerau-Levenshtein (Damerau, 1964, Communications of the ACM) adds a fourth operation, transposing two adjacent characters, at a cost of 1. It is built directly from an empirical observation Damerau made about real typing errors: the overwhelming majority of single mistakes are one of insertion, deletion, substitution or an adjacent transposition, so a distance that prices all four correctly should track real typos far better than one that only has three.

It still has two limits worth naming. It is still positional - it does not know that "ph" and "f" can sound the same, or that "Muller" and "Mueller" are the same transliterated name spread across more than one adjacent swap. And it is still blind to phonetics entirely: nothing in either edit distance knows what a word sounds like, which is what Part 3 exists to fix.

Part 2 · covers Jaro and Jaro-Winkler

A prefix bonus that only helps at the start

6 min live

Jaro-Winkler is the most quoted name-matching measure in the field, and also the most misunderstood, because its one clever idea - trust the start of a name more than the end - is also its one hard limit.

JW = Jaro + L × P × (1 - Jaro) L - COMMON PREFIX LENGTH Matching characters at the very start of both strings, capped at 4 regardless of length. P - PREFIX SCALE, DEFAULT 0.1 Winkler's chosen weight per prefix character. Above 0.25 the score can exceed 1. WORKED EXAMPLE - KATHERINE AGAINST CATHERINE Common prefix: none - "K" vs "C" disagree immediately, so L = 0 Boost = 0 × 0.1 × (1-Jaro) = 0, whatever Jaro already was JW collapses to plain Jaro here. The one mechanism built to reward a matching start cannot fire when the start is where the two names actually differ - read the live score in the lab below.
🔍 Click to zoom - the prefix boost needs agreement exactly where Katherine and Catherine disagree
LiveJaro first, then Winkler's addition5 min▶

Jaro similarity (1989) was built for short strings like personal names. It finds characters that match within a small window of each other's position, counts how many matched characters are out of order (transpositions), and combines match count and transposition count into a score between 0 and 1. Because matches only count within a window, it copes reasonably with characters shifting position by a little, and it copes badly with long strings where whole tokens have been reordered - a job token measures do far better, in Part 3.

Jaro-Winkler (Winkler, 1990) adds a bonus for agreement at the very start of the string: JW = Jaro + L × P × (1 - Jaro), where L is the common prefix length, capped at 4 characters, and P is the prefix scale, 0.1 by default. The cap exists because Winkler found the earliest characters of a name are the most reliably typed ones in practice - a reasonable bet for Western given names, and the reason 0.1 is the default rather than something larger: push P above 0.25 and the formula can push the score above 1, which is not a valid similarity any more.

Real world

Type Katherine against Catherine into the lab. The names share seven of nine characters and would sound identical read aloud, yet the prefix disagrees in the very first letter, so L is 0 and the boost is exactly 0. Jaro-Winkler quietly becomes plain Jaro on this pair, which is lower than most people expect walking in. This is the best teaching moment in the whole session: the measure is famous for its prefix logic, and this is the pair where that logic contributes nothing.

Self-studyWhere the prefix bet pays off, and where it does not4 min▶

The prefix assumption is not arbitrary, it is tuned to Western given and family names, where data-entry errors cluster toward the end of a long word and the first few letters are usually typed carefully and read carefully. That is a real, useful bias for a lot of Meridian's data. It stops being useful the moment the variation lives at the front: transliterated names, prefixed titles, and any name where two cultures romanise the leading sound differently will all get zero help from L, no matter how similar the rest of the string is.

The practical rule that falls out of this: Jaro-Winkler is a good default for Western personal names typed by a careless human, and a poor default for anything transliterated, anything token-reordered, or anything where the difference is structurally at the start. Know which kind of dirt you are looking at before trusting the prefix bonus to catch it.

Part 3 · covers token, cosine and phonetic measures, plus normalisation

Order, sound, and the bet you make before any of this runs

8 min live

The last three measures throw something away on purpose - order, rarity, or spelling itself - and normalisation is the step that happens before any measure runs at all, quietly deciding what the comparison even sees.

MEASURE TRANSPOSE TOKEN ORDER PHONETIC TRANSLIT SUFFIX/NOISE TINY CORPUS STARTS DIFFERENT Levenshtein ✗✗✗✗✓✓✓ Damerau-Lev. ✓✗✗✗✓✓✓ Jaro ✓✗✗✗✓✓✓ Jaro-Winkler ✓✗✗✗✓✓✗ Jaccard tokens ✗✓✗✗✓✓✓ Cosine TF-IDF ✗✓✗✗✓✗✓ Soundex/Metaphone ✓✗✓✓✗✓✓ No row is all checks. Meridian's dirt needs at least three measures, never one. Session 3 is what combines them into a single score instead of picking a favourite.
🔍 Click to zoom - the honest reason session 3 needs more than one measure at a time
LiveToken sets: Jaccard and cosine on TF-IDF5 min▶

Jaccard similarity on token sets (Jaccard, 1901) treats a string as a bag of words and scores the overlap: shared tokens divided by all tokens across both sides. It is completely order-independent, which is exactly what "Robert Chen" against "Chen Robert" needs - both sides are the set {robert, chen}, so Jaccard reports 1. Its failure sits one level down: it treats a token as atomic, so "Jon" and "John" are two entirely different tokens with zero overlap between them, even though a human reads them as the same name missing one letter. Jaccard cannot see inside a token at all.

Cosine similarity on TF-IDF vectors (the vector-space model, Salton) fixes a different problem: not every shared token is equally informative. "Ltd" and "Inc" appear in hundreds of company names and should barely move a similarity score, while a distinctive word like "Northwind" should move it a lot. TF-IDF weighting down-weights the common tokens automatically, which is exactly the property you want for company-name matching. Its failure is structural rather than conceptual: the "IDF" half of the name needs a corpus to estimate how rare a token actually is, and on a tiny corpus - Meridian's few dozen company names, or any young dataset - those rarity estimates are unstable and can swing the score around for reasons that have nothing to do with the two strings being compared.

LivePhonetics: Soundex, Metaphone, and the value of a second code5 min▶

Soundex (Robert Russell and Margaret Odell, US patents 1,261,167 of 1918 and 1,435,663 of 1922) is the oldest phonetic code in production use anywhere, predating every other measure in this session by decades. It keeps the first letter of a name as-is, converts the rest of the consonants into a small set of digit codes for similar-sounding groups, drops vowels entirely, and pads or truncates the result to four characters. "Smith" and "Smyth" collapse onto the same code because Soundex never looks at the vowel that differs.

The same mechanism is also its failure. A four-character code is a very small space, so genuinely different names collapse onto the same code far more often than seems safe, and the whole scheme was designed around English orthography and consonant sounds - it degrades on names built from other phonetic systems. Type two names that sound similar into the lab and read the codes it prints underneath; a match there is a hint worth checking, never a verdict on its own.

Metaphone (Lawrence Philips, 1990, published in Computer Language) improved on Soundex's rule set for English pronunciation but still returns one code, which means it still cannot represent a name with two legitimate pronunciations. Double Metaphone (Philips, 2000, C/C++ Users Journal 18, pages 38 to 43) fixes exactly that: it returns a primary and a secondary code, so a name that could plausibly be pronounced two ways - many Slavic, Germanic, Celtic, Greek and Hispanic surnames among them - carries both possibilities forward instead of forcing a single guess.

Verification honesty. NYSIIS (Taft, 1970, New York State Identification and Intelligence System) is a further phonetic scheme with different vowel and suffix rules than Soundex. The original agency report was not fetched for this course, so the commonly cited claim that NYSIIS improves match accuracy by roughly 2.7 percent over Soundex on European and Hispanic surnames is reported here as it travels through secondary sources, not verified against the primary study. Treat that number as a widely repeated estimate, not a checked fact.

LiveNormalisation is a prior step, and it is a bet5 min▶

Every measure above runs on whatever text it is handed, and what it is handed is usually the product of a normalisation step that ran first: expanding nicknames, standardising transliteration, abbreviating or expanding street types, stripping company suffixes, or reducing a phone number to digits only. None of the seven measures know this happened. That is exactly the risk - normalisation destroys the original difference before any measure gets a chance to weigh it.

  • Nickname lists. Folding "Bob" into "Robert" and "Mike" into "Michael" recovers real matches a string measure alone would score low. It also assumes a nickname always means the same underlying formal name, which is not universally true.
  • Transliteration. "Muller" and "Mueller" are the same German surname written two ways after the umlaut is dropped or expanded. A transliteration table catches this reliably; a raw edit distance sees two substitutions and one insertion.
  • Street abbreviation. "Street" and "St", "Court" and "Ct" need a lookup table, not a smarter string measure, because the shortening is a convention rather than a spelling error.
  • Phone digits only. Stripping formatting down to digits turns "0412 336 908" and "+61 412 336 908" into comparable strings, though it also throws away the country-code information that would otherwise tell you the numbers are formatted for different markets.
  • Company suffix stripping. Removing "Ltd", "Inc", "Limited" and similar tokens correctly joins "Northwind Ltd" and "Northwind Limited". It also correctly joins "Northwind Ltd" and "Northwind Pty Ltd" if those happen to be separate legal entities, which is the trade you are actually making.

Folding "Katherine" and "Catherine" together at the normalisation stage correctly joins the one pair in Meridian where that is the right call, and it risks wrongly joining two different people elsewhere in a larger dataset who happen to share that variant spelling by coincidence rather than by being the same person. There is no version of normalisation that avoids this trade - the honest move is to make the bet visible, not to pretend cleaning the data removed the judgement call.

Build-along

Break each measure on purpose

★ 16 min · everyone builds

The lab below is live - type into either box and every measure recomputes immediately, with the Soundex codes for both strings printed underneath. Read every number in this session off it directly; nothing here is a number to memorise.

Load the Mary Ann / Mray Ann preset. Read the Levenshtein score and the Damerau-Levenshtein score side by side. Confirm the gap is exactly the transposition penalty difference from Part 1 - one operation under Damerau, two under plain Levenshtein.

Load Katherine / Catherine. Read the Jaro score and the Jaro-Winkler score. They should be close to identical - find where the prefix boost failed, and say in one sentence why L came out at zero.

Now type Robert Chen against Robert Chan - two different people in Meridian. Read the Soundex codes printed under the boxes. If they match, you have found the case the honesty callout above warned about: a phonetic code that says identical for two people who are not.

Try Thomas Muller / Thomas Mueller and Smith / Smyth. Note which measures score them high and which score them low, and connect that back to the matrix figure - phonetic measures should win both, edit distance should struggle with the vowel-heavy transliteration case.

For each Meridian field below, pick the single measure you would trust most and write one line defending the choice: name, company, street address, phone. There is a defensible answer for each, and it is rarely the same measure twice.

Compare your four choices with a neighbour. Where you disagree, load both strings into the lab and let the numbers settle it rather than the argument.

Keep your four field-to-measure choices. Session 3 assigns a real weight to each field based on how often it agrees on a true match versus a non-match, and it is worth knowing whether your intuition from tonight lines up with the estimated numbers.

Homework

Before session 3

25 min
Check yourself

Three questions

In Jaro-Winkler's formula, JW = Jaro + L × P × (1 - Jaro), what is L and what is it capped at?

L is the length of the matching prefix shared by both strings, and Winkler capped it at 4 regardless of how much longer the strings are. Combined with the default prefix scale of 0.1, that keeps the maximum possible boost at 0.4 times whatever Jaro similarity was missing - and is exactly why the boost is zero whenever the very first character disagrees, as it does for Katherine against Catherine.

Folding "Katherine" and "Catherine" together at the normalisation stage correctly joins one true pair in Meridian. What does that same rule risk doing elsewhere?

Normalisation is lossy by construction: it destroys a distinction before any similarity measure gets to weigh it. The Katherine and Catherine fold is the right call for the one true Meridian pair it fixes, and the same rule applied at scale can just as easily fuse two genuinely different people who share that spelling variant. That is why normalisation is described as a bet rather than a cleanup step.

Robert Chen and Robert Chan produce the same Soundex code. What is the correct conclusion?

Soundex compresses a name into four characters by design, and that small a space guarantees collisions between names that sound broadly alike but are not the same. Chen and Chan are exactly this case. The honest use of a phonetic code is as one signal among several - session 3 is where it gets combined with the rest rather than trusted alone.

Sources covered

What this session teaches, and where it came from

✓Levenshtein, 1965/66, Soviet Physics DokladyPrimary. Edit distance with insert, delete, substitute; the transposition-cost failure taught in full
✓Damerau, 1964, Communications of the ACMPrimary. The fourth operation, transposition at cost 1, and why it still misses phonetics
✓Jaro, 1989, and Winkler, 1990Primary. The prefix formula worked by hand, including why P defaults to 0.1
✓Jaccard, 1901, and Salton's TF-IDF vector-space modelPrimary. Token-set overlap and corpus-weighted cosine, each with its failure case
✓Odell and Russell, US patents 1,261,167 (1918) and 1,435,663 (1922)Primary. Soundex's own rules, and its four-character collision problem
✓Philips, Metaphone (1990) and Double Metaphone (2000, C/C++ Users Journal 18, 38-43)Primary. Why a second code exists at all - real pronunciation ambiguity
◐Taft, NYSIIS, 1970, New York State Identification and Intelligence SystemSecondary - the original report was not fetched; the ~2.7 percent claim over Soundex is repeated as reported elsewhere, not verified

Every fact on this page, and its verification tier, is recorded in the course's source map.

Session 2 cheat sheet · pin this

Edit distanceLevenshtein: no transposition, costs 2. Damerau-Levenshtein: adds it, costs 1.
Jaro-Winkler formulaJW = Jaro + L × P × (1-Jaro). L = prefix length capped at 4, P = 0.1 default.
JW's blind spotDifference at the START gets zero boost - Katherine vs Catherine, L = 0.
Token measuresJaccard: order-free, blind inside a token (Jon/John = 0). Cosine TF-IDF: down-weights Ltd/Inc, needs a real corpus.
PhoneticsSoundex: 4 chars, collapses names, English-only. Double Metaphone: primary + secondary code for real ambiguity.
Normalisation is a betIt joins the pair you meant and risks joining a pair you did not. Say so, do not hide it.