Lexical Metrics and Feature Weights
Lexical features run with the base Matheel install and can be used alone or blended with semantic and code-aware scores. Start with Choose similarity metrics if you are unsure which comparison fits your task.
RapidFuzz Distance Families
All ten scalar distance families from RapidFuzz are available as normalized similarities in the 0.0–1.0 range. Larger scores mean more similar prepared strings.
| Feature name | What it compares |
|---|---|
levenshtein |
Insertions, deletions, and substitutions; configurable edit costs. |
damerau_levenshtein |
Edits including adjacent transpositions. |
osa |
Optimal string alignment, with restricted transpositions. |
hamming |
Positional character matches, padding unequal lengths. |
indel |
Insertions and deletions. |
lcs |
Longest common subsequence, normalized by the longer length. |
jaro |
Matching characters and transpositions. |
jaro_winkler |
Jaro similarity with a shared-prefix bonus. |
prefix |
Shared beginning of the strings. |
postfix |
Shared ending of the strings. |
lcs uses RapidFuzz's LCSseq.normalized_similarity: matching characters may have gaps, but keep their relative order. It is a character subsequence score, rather than a longest contiguous substring or a parser-token comparison. See RapidFuzz LCSseq.
Hamming uses pad=True, so unequal-length code does not raise a length error. See RapidFuzz Hamming.
RapidFuzz Fuzzy Ratios
Matheel exposes every scalar scorer in rapidfuzz.fuzz with the rapidfuzz_ prefix. Upstream 0–100 scores are divided by 100 for blending.
| Feature name | Matching strategy |
|---|---|
rapidfuzz_ratio |
Normalized Indel similarity. |
rapidfuzz_partial_ratio |
Match the shorter string within the longer one. |
rapidfuzz_token_sort_ratio |
Sort whitespace-separated words, then compare. |
rapidfuzz_token_set_ratio |
Compare unique and shared words. |
rapidfuzz_token_ratio |
Maximum of token-sort and token-set scores. |
rapidfuzz_partial_token_sort_ratio |
Partial matching after sorting words. |
rapidfuzz_partial_token_set_ratio |
Partial matching of word sets. |
rapidfuzz_partial_token_ratio |
Maximum of the partial token scores. |
rapidfuzz_wratio |
Upstream weighted combination of ratios. |
rapidfuzz_qratio |
Quick ratio with upstream empty-input behavior. |
See the RapidFuzz fuzzy scorer documentation. Partial matching and token subsets can score highly despite extra code; validate against labeled pairs.
Token ratios use whitespace splitting, independent of lexical_tokenizer. Matheel adds no RapidFuzz processor; preprocessing controls case and punctuation. Empty-input behavior is preserved: two empty strings score 1.0 with rapidfuzz_ratio, but 0.0 with rapidfuzz_qratio. partial_ratio_alignment returns alignment data and is not a scalar feature.
Code-Token Baselines
winnowing: token fingerprints from k-grams and sliding-window minima.gst: Greedy String Tiling over token sequences.
These use Matheel's code-token regex after preprocessing. Set lexical_tokenizer="parser" or CLI --lexical-tokenizer parser to compare tree-sitter leaf node types instead. Parser-derived streams reduce sensitivity to identifier spelling; see Tokenization and limits.
Feature Weights
Run matheel metrics for the current string metric catalog, including canonical names, families, and score ranges.
Use a dictionary in Python or repeat --feature-weight name=value in the CLI. Matheel normalizes finite, non-negative weights; they do not need to sum to one.
from matheel.similarity import calculate_similarity
score = calculate_similarity(
"def add(a, b): return a + b",
"def total(x, y): return x + y",
feature_weights={"lcs": 2, "levenshtein": 1},
preprocess_mode="basic",
code_language="python",
)
print(score)
From a repository checkout:
python examples/sample_data.py --output sample_pairs.zip --overwrite
matheel compare sample_pairs.zip \
--feature-weight lcs=2 \
--feature-weight rapidfuzz_ratio=1
rapidfuzz_ratio and indel measure the same normalized similarity. Use one of them unless duplicating its weight is intentional. Other related scorers also produce correlated evidence; adding more features does not automatically improve quality.
If you omit feature_weights, the default remains semantic=0.7 and levenshtein=0.3. That default requires a semantic backend. Set lexical weights explicitly for model-free comparisons. See Scoring and calibration before setting thresholds or mixing semantic score scales.
Baseline Parameters
| Parameter | Used by |
|---|---|
levenshtein_weights |
Levenshtein insertion, deletion, and substitution costs. |
jaro_winkler_prefix_weight |
Jaro-Winkler prefix bonus. |
winnowing_kgram, winnowing_window |
Winnowing fingerprint generation. |
gst_min_match_length |
Minimum GST tile length. |
lexical_tokenizer |
Winnowing and GST: raw or parser. |
matheel compare sample_pairs.zip \
--feature-weight winnowing=1 \
--winnowing-kgram 5 \
--winnowing-window 4 \
--lexical-tokenizer raw
matheel compare sample_pairs.zip \
--feature-weight gst=1 \
--gst-min-match-length 5 \
--code-language java \
--lexical-tokenizer parser