Skip to content
Back to skills

Multi Metric String Similarity

ASecurity

Computes multiple complementary string similarity scores (Gestalt, Levenshtein, Jaro-Winkler, LCS) per field pair as features for entity matching classifiers.

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
developmentpythongoperformance

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill multi-metric-string-similarity --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Multi Metric String Similarity?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Multi Metric String Similarity
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-multi-metric-string-similarity/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-multi-metric-string-similarity)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: nlp-multi-metric-string-similarity
description: >
  Computes multiple complementary string similarity scores (Gestalt, Levenshtein, Jaro-Winkler, LCS) per field pair as features for entity matching classifiers.
---
# Multi-Metric String Similarity

## Overview

No single string similarity metric captures all types of text variation. Gestalt (SequenceMatcher) handles rearrangements, Levenshtein captures edit distance, Jaro-Winkler rewards prefix matches (good for names), and LCS measures shared subsequences. Computing all four per field pair — plus normalized variants — gives a downstream classifier rich signals for entity matching, deduplication, and record linkage.

## Quick Start

```python
import difflib
import Levenshtein

def string_similarity_features(s1, s2):
    """Compute multiple similarity metrics for a string pair."""
    if not s1 or not s2:
        return {"gestalt": -1, "levenshtein": -1, "jaro_winkler": -1,
                "norm_levenshtein": -1}
    gestalt = difflib.SequenceMatcher(None, s1, s2).ratio()
    leven = Levenshtein.distance(s1, s2)
    jaro = Levenshtein.jaro_winkler(s1, s2)
    max_len = max(len(s1), len(s2))
    return {
        "gestalt": gestalt,
        "levenshtein": leven,
        "jaro_winkler": jaro,
        "norm_levenshtein": leven / max_len if max_len > 0 else 0,
    }

# Apply to each field pair in candidate matches
for field in ["name", "address", "city"]:
    feats = df.apply(
        lambda r: string_similarity_features(r[f"{field}_1"], r[f"{field}_2"]),
        axis=1, result_type="expand"
    )
    feats.columns = [f"{field}_{c}" for c in feats.columns]
    df = pd.concat([df, feats], axis=1)
```

## Workflow

1. For each candidate pair, extract corresponding text fields
2. Compute Gestalt ratio, Levenshtein distance, Jaro-Winkler similarity
3. Normalize Levenshtein by max string length for scale-invariant comparison
4. Optionally add LCS length and LCS ratio (LCS / min or max length)
5. Use all metrics as features in a LightGBM/XGBoost classifier

## Key Decisions

- **Which metrics**: Gestalt + Jaro-Winkler + normalized Levenshtein is the minimum useful set
- **Normalization**: Divide edit distance by max length; divide LCS by min length for recall
- **Missing values**: Use -1 sentinel for missing/null fields (tree models handle this well)
- **Performance**: For millions of pairs, use python-Levenshtein (C extension) not pure Python

## References

- [Foursquare - LightGBM Baseline](https://www.kaggle.com/code/ryotayoshinobu/foursquare-lightgbm-baseline)
- [binary_lgb_baseline[0.834]](https://www.kaggle.com/code/guoyonfan/binary-lgb-baseline-0-834)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.