SightRadardocs

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:

ScoreDecisionExample UX
above the high thresholdaccept automaticallyshow the photo in the guest's gallery
between the tworoute to review"Is this you?" confirmation, or a human queue
below the low thresholdrejecthide

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 threshold and limit are 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.

Last updated

On this page