Open source · MIT

Kin

Record linkage: finds the same person written down in different ways and shows what the score is made of.

v1.0.0 The arithmetic behind the score
FastAPIPython 3.13PostgreSQL 18psycopg 3Jinja2Tailwind 4
Kin

One person, three records

Every customer base eventually holds the same person three times: once from the CRM export, once from a web form, once from the system that was replaced two years ago. The surname has a typo, the phone is written in another format, the birthday has the day and month swapped, and the old system spelled everything in Latin letters.

Deduplication tools answer with a single number and leave you guessing. Kin shows the arithmetic instead: which fields matched, how much each contributed, where the two thresholds sit, and, using the decisions a human already made, how many pairs the current thresholds would send the wrong way.

What is inside

Blocking instead of brute force

Every record gets several coarse keys: surname prefix with birth year, with given name, with city, the last seven digits of the phone, the email local part. On the demo base that turns 2.1M possible pairs into 5 934 candidates without losing a single true duplicate: the seeder measures recall and prints it.

Metrics written by hand

Jaro-Winkler with a prefix bonus, bounded Levenshtein, token overlap for addresses, and a date comparison that knows the two most common data-entry mistakes: a swapped day and month, and a typo in the year.

Transliteration built in

«Соловьёва» meets «Solovieva» and «Королёв» meets «Korolev». Names are compared both as written and transliterated, and the better of the two counts, so the old Latin-only system stops being a separate database.

Two thresholds with a live preview

The sliders sit under the histogram and share its scale. Move them and the screen recounts what would be merged automatically, what would go to a human and what would be discarded. Saving is a separate action, taken after the consequences are visible.

The queue is the ground truth

Every human decision is stored with its author, and the threshold screen uses them to report false merges and missed merges at the current settings. The human outranks the machine: «do not merge» keeps a pair apart at any score.

Clusters with a weakest link

Accepted pairs are joined by union-find, and every cluster reports its weakest internal link. Chains where A resembles B, B resembles C and A has nothing to do with C surface first, the main danger of systems like this.

Screenshots

Thresholds: the score histogram and two movable lines
Thresholds: the score histogram and two movable lines
Review: fields side by side and each one's contribution
Review: fields side by side and each one's contribution
Preview: what happens if the thresholds move
Preview: what happens if the thresholds move
Clusters: the most suspicious first
Clusters: the most suspicious first
A cluster: its records and the golden one
A cluster: its records and the golden one
Dark theme
Dark theme

Installation

git clone https://github.com/dripips/kin.git cd kin docker compose up --build

Have a project or idea?

Write to me and we will talk the task through.