Choosing a similarity threshold
Turn a 0 to 1 cosine similarity into accept, review and reject decisions using your own data, not a number copied from another vendor.
Every match carries a score, cosine similarity between two faceprints from 0 to 1. Compare additionally returns match, evaluated at a default threshold. Neither is a verdict on its own. The right cut-off depends on your photos, your population, and the cost of each kind of mistake.
Start from your own pairs
Collect labelled pairs
A few hundred same-person pairs and a few hundred different-person pairs drawn from your real photos: same cameras, same lighting, same demographics. Event galleries, ID documents and webcam frames behave differently.
Score them
Run each pair through POST /v1/compare (or index one side and search with the other). Record the score and the label.
Plot the two distributions
Same-person scores cluster high, different-person scores cluster low, and there is an overlap region. Your threshold lives somewhere in that overlap. Moving it right trades false accepts for false rejects.
Pick bands, not a point
For most products two thresholds beat one:
| Score | Decision | Example UX |
|---|---|---|
| above the high threshold | accept automatically | show the photo in the guest's gallery |
| between the two | route to review | "Is this you?" confirmation, or a human queue |
| below the low threshold | reject | hide |
Rules of thumb
- Identity verification (KYC, account recovery) should sit on the strict side and pair the face match with document authentication and liveness. A face match proves resemblance, not that the document is genuine or the person is live.
- Photo discovery (galleries, tagging) can sit looser, because a wrong suggestion is cheap and the user confirms it.
- Search
thresholdandlimitare request parameters. Use them to cap what comes back, but keep the banding logic on your side where you can change it without redeploying prompts to users.
Do not carry numbers across vendors
Rekognition reports similarity on a 0 to 100 scale; SightRadar uses 0 to 1. Dividing by 100 converts the scale but not the operating point: different models put the same decision at different cut-offs. Re-derive the threshold from your own pairs when you migrate, and compare providers on ranking agreement, not raw scores. The Rekognition shim converts the scale automatically so existing call sites keep working while you recalibrate.
Watch it in production
Log the score and the decision, never the images. A drifting accept rate is the earliest sign that your photo mix has changed (a new venue, a new camera) and the threshold needs revisiting.
Further reading: Choosing a face-match threshold on the blog.