Skip to content

CodLab AI · Feb 2025 – Jul 2026

Author disambiguation at scale

Role
Artificial Intelligence Engineer — sole engineer on the pipeline
Dates
Feb 2025 – Jul 2026 · Karabük
Stack
PythonPostgreSQL 15pgvectorElasticsearchSentenceTransformersRapidFuzzMinHash LSH
articles · ~500M mentions
85M+
accuracy · 200-case benchmark
~92%
runtime · 2.5M records
~4h → ~2h

Entity resolution over bibliometric data — I designed it and ran it in production, on a single machine.

The problem

Bibliometric databases store author name strings, not identities. The same researcher appears under different name formats across their papers; different researchers share the same name. Ask “which papers did this person write” and a naive matcher either splits one career into fragments or merges strangers into one profile.

The merge direction is the dangerous one. A common name can snowball — each bad merge makes the next one look more plausible — until a false mega-cluster absorbs researchers who share nothing but a surname. A system at this scale needs safeguards against that failure mode, not just a good similarity score.

Approach

The pipeline is a two-stage Python ETL. PostgreSQL 15 with pgvector holds the records and their 384-dim embeddings; Elasticsearch with a Turkish analyzer covers fuzzy name search; SentenceTransformers produces the embeddings and RapidFuzz handles string similarity.

Matching runs through a hierarchy of signals rather than one blended score: email, ORCID, ResearcherID, affiliation, the co-authorship graph, and finally semantic embedding similarity, in that order of trust. The hierarchy can also veto — two records carrying different ORCIDs are rejected outright, no matter how well every other signal agrees. A level that stops a merge even when everything else says yes is the most useful decision in the system. On top of the pairwise decisions, anti-snowball safeguards protect against false mega-clusters.

Scale was the other half of the work. A MinHash LSH block-then-cluster candidate layer removed the Elasticsearch bottleneck entirely, and an out-of-core memmap design keeps 85M-scale processing inside a fixed memory budget. The single largest runtime win was mundane: replacing an O(N²) read pattern with O(N) keyset pagination.

What didn’t work

A ThreadPool Elasticsearch prefetch was supposed to overlap I/O with compute. Measured end to end, it made the pipeline 35% slower. And a bucket filter that looked like a cheap optimization cost 30 cases on the ground-truth accuracy benchmark.

Both changes read as improvements and died on measurement — which is the argument for keeping a ground-truth benchmark next to the pipeline.

Results

~92% accuracy on a 200-case ground-truth benchmark, with cluster-quality guards.

Full-pipeline runtime on a 2.5M-record dataset roughly halved: ~4h → ~2h.

Publication

Tüylüoğlu, B. E., & Türker, İ. (2025). Author Name Ambiguity in Turkish Scientific Publications: A Bibliometric Verification Approach. 8th International Trakya Scientific Research Congress.

Demo

The playground reimplements the matching hierarchy in your browser — two editable records, nine decision levels and a merge cap, the ORCID veto — on synthetic data. No API calls; it works offline.

Run the disambiguation demo →

Confidentiality

This pipeline was built for an employer. The write-up above stays at the level of my published paper and CV — no employer source code, no real data, no infrastructure details or internal configuration. The demo is a reimplementation of the general technique, and every record in it is fabricated.