Amazon ML Challenge 2026, Entity resolution
BizMatch
Rank 38 of 32,000+ teams
Finds every real copy of a business across ~10M noisy records and rejects look-alike decoys.
- 38Final rank out of 32,000+ teams in the Amazon ML Challenge 2026
- 0.990Best public-leaderboard macro F0.5, up from 0.921 at the first submission
- 98.75%Candidate recall at ~5 candidates per business (TF-IDF + fine-tuned multilingual-e5)
- +0.0039Gain from label-free France rules, confirmed by two independent statistical tests
How it works
- RetrieveTF-IDF plus fine-tuned multilingual-e5, ~5 candidates per business
- Feature cascade57 pair features into a 3-stage out-of-fold LightGBM cascade
- Rerank7 cross-encoders fused by a LightGBM stacker
- LoRA judgesQwen2.5-7B LoRA judges inside a test-like recalibrator
- DecideExact expected-F0.5 subset per business via a Poisson-binomial DP
Problem
Amazon gave us ~10M noisy business records from two sources and asked which of 1.7M reference businesses each one belonged to. The only fields were name, address and country. The data covered the US, India and France, France had no labels at all, and the set contained adversarial decoys built to look like real matches. Scoring was macro F0.5 per business, so precision weighed more than recall and every business counted equally.
I led Team Minutes, four people, through the challenge.
Approach
The pipeline is a funnel. TF-IDF and a fine-tuned multilingual-e5 bi-encoder pull candidates, with 98.75% recall at ~5 candidates per business, which keeps everything downstream affordable. Each candidate pair gets 57 features and passes through a 3-stage out-of-fold LightGBM cascade. Survivors are scored by 7 cross-encoders (e5, bge-reranker-v2-m3, Qwen3-Reranker), and a LightGBM stacker fuses their outputs. Qwen2.5-7B LoRA judges sit inside a recalibrator built to behave like the test set.
The last step is a decision, not a threshold. F0.5 is computed per business, so a single global cut-off is the wrong tool. For each business I compute the exact expected F0.5 of candidate subsets with a Poisson-binomial dynamic program and return the best one.
Two things mattered more than any model. First, validation. Our early validation set matched neither the test density nor the kind of unmatched records in test. I rebuilt it, and afterwards it agreed with test to four decimals. Second, France. With no labels, we modeled the data generator, derived rules from that model, and only kept them once two independent statistical tests confirmed them (+0.0039).
Everything ran on free tiers and credits: AWS EC2 spot, Kaggle 2×T4, Modal H100, Lightning AI and a laptop RTX 4060. Every stage wrote resumable Parquet artifacts, which is why spot reclaims and a lost cloud account on the final day did not end the run.
Results
We climbed from 0.921 at the first submission to 0.990 macro F0.5 on the public leaderboard and finished rank 38 of 32,000+ teams. Amazon’s email confirmed a top-50 finish nationwide and invited the team to its Applied Scientist Intern interview.
What I learned
Validation design beat model changes. Before the rebuild, a v3 change gained +0.006 on validation and lost on the leaderboard. After it, offline numbers were trustworthy enough that I stopped guessing.
Optimize the metric you are scored on, at the level it is scored. Expected F0.5 per business handled the trade between one sure match and several likely ones better than any threshold I could tune.
When there are no labels, model the generator, then test that model before you trust it. And don’t let rules override the model: our France variants that did scored worse.
Limits, stated not hidden
- Before the validation rebuild, a v3 change gained +0.006 on validation and then lost on the leaderboard.
- France had no labels, so the France rules rest on two statistical tests, not on ground truth.
- Hand-written France rules that overrode the model scored worse than ones that only fed it.
- 0.990 is the public-leaderboard score of a competition entry, not a production system.