Skip to main content

Scoring & Presets

The CompositeScorer combines multiple string similarity metrics into a single weighted score. Pre-tuned presets are available for common matching scenarios such as person names and addresses.


CompositeScorer

Construction

Create a scorer by specifying a list of (metric_name, weight) tuples. Weights are normalized internally, so they do not need to sum to 1.

from reclink import CompositeScorer

scorer = CompositeScorer([
("jaro_winkler", 0.6),
("token_sort", 0.4),
])
ParameterTypeDescription
componentslist[tuple[str, float]]List of (metric_name, weight) pairs. Metric names are any string metric: "jaro_winkler", "levenshtein", "cosine", "token_sort", "token_set", "phonetic_hybrid", etc.

CompositeScorer.preset(name)

Load a pre-configured scorer by name.

scorer = CompositeScorer.preset("name_matching")
ParameterTypeDescription
namestrPreset name: "name_matching", "address_matching", or "general_purpose".

Returns: CompositeScorer

scorer.similarity(a, b)

Compute the weighted similarity between two strings.

scorer.similarity("Jon Smith", "John Smyth") # 0.89
ParameterTypeDescription
astrFirst string.
bstrSecond string.

Returns: float in [0, 1].

scorer.match_best(query, candidates, threshold)

Find the single best match from a list of candidates.

result = scorer.match_best("Jon Smith", ["John Smith", "Jane Doe", "Bob Jones"])
# ("John Smith", 0.96, 0) -> (string, score, index)
ParameterTypeDefaultDescription
querystr--Query string.
candidateslist[str]--Candidate strings to compare against.
thresholdfloat | NoneNoneMinimum score. If no candidate meets the threshold, returns None.

Returns: tuple[str, float, int] | None -- (matched_string, score, index) or None.

scorer.match_batch(query, candidates, threshold, limit)

Find all candidates above a score threshold, optionally limited to the top results.

results = scorer.match_batch(
"Jon Smith",
["John Smith", "Jane Doe", "Jonathan Smyth"],
threshold=0.7,
limit=5,
)
# [("John Smith", 0.96, 0), ("Jonathan Smyth", 0.82, 2)]
ParameterTypeDefaultDescription
querystr--Query string.
candidateslist[str]--Candidate strings.
thresholdfloat | NoneNoneMinimum score to include a candidate.
limitint | NoneNoneMaximum number of results to return.

Returns: list[tuple[str, float, int]] -- sorted by descending score.


Presets

Pre-tuned scorers are available as factory functions and via CompositeScorer.preset().

name_matching

Optimized for person-name matching. Balances edit-distance sensitivity (Jaro-Winkler), token-order invariance (Token Sort), and phonetic similarity.

from reclink.presets import name_matching

scorer = name_matching()
scorer.similarity("Jon Smith", "John Smyth") # 0.89

Or equivalently:

scorer = CompositeScorer.preset("name_matching")
MetricWeight
jaro_winkler0.5
token_sort0.3
phonetic_hybrid0.2

address_matching

Optimized for street addresses, where word order varies and abbreviations are common.

from reclink.presets import address_matching

scorer = address_matching()
scorer.similarity("123 Main St", "123 Main Street")

Or equivalently:

scorer = CompositeScorer.preset("address_matching")
MetricWeight
token_set0.5
jaccard0.3
levenshtein0.2

general_purpose

A balanced scorer for general text matching.

from reclink.presets import general_purpose

scorer = general_purpose()
scorer.similarity("quick brown fox", "the quick brown foxes")

Or equivalently:

scorer = CompositeScorer.preset("general_purpose")
MetricWeight
jaro_winkler0.4
cosine0.4
token_sort0.2

Examples

Custom scorer for company names

from reclink import CompositeScorer

scorer = CompositeScorer([
("token_set", 0.5), # "IBM Corp" vs "Corp IBM"
("jaro_winkler", 0.3), # Short-range typos
("cosine", 0.2), # Token overlap
])

scorer.similarity("Acme Corporation", "ACME Corp.") # High
scorer.similarity("Acme Corporation", "Beta Industries") # Low

Using presets with match_batch

from reclink.presets import name_matching

scorer = name_matching()

candidates = [
"John Smith",
"Jane Doe",
"Jonathan Smyth",
"Bob Johnson",
"Jon Smithe",
]

results = scorer.match_batch("Jon Smith", candidates, threshold=0.75)
for name, score, idx in results:
print(f" {name} ({score:.3f})")
# John Smith (0.960)
# Jon Smithe (0.944)
# Jonathan Smyth (0.823)

Comparing presets

from reclink.presets import name_matching, address_matching, general_purpose

a, b = "123 N Main Street", "123 North Main St"

print(f"name_matching: {name_matching().similarity(a, b):.3f}")
print(f"address_matching: {address_matching().similarity(a, b):.3f}")
print(f"general_purpose: {general_purpose().similarity(a, b):.3f}")

  • String Metrics -- all available metric names for CompositeScorer
  • Batch Operations -- match_best and match_batch for single-metric matching
  • Pipeline -- use comparators and classifiers for full record linkage workflows
  • Evaluation -- measure quality of matching results