Fuzzy-Matcher

repository·master·Indexed 42 days ago

https://github.com/intuit/fuzzy-matcher

A Java-based library for matching and grouping similar elements in a collection of documents to find duplicates or categorize entities with variations in spelling, formatting, or abbreviations. It features a customizable four-stage process consisting of Pre-Processing, Tokenization, Match Type, and Scoring. Supports various strategies including Exact Word Match, Soundex Match, NGram Match, and Nearest Neighbors Match. Version 1.2.1 requires Java 11.

Tokens
3K
Snippets
7
Records
11
Agent score
4%

What's inside Fuzzy-Matcher

  1. Configure Documents and Elements

    master

    To perform fuzzy matching, you must structure your data into Document and Element objects using their respective builders.

    // Example of building a Document with Elements
    List<Document> documentList = Arrays.asList(input).stream().map(contact -> {
        return new Document.Builder(contact[0]) // contact[0] is the unique Key
                .addElement(new Element.Builder<String>()
                        .setValue(contact[1])
                        .setType(NAME)
                        .createElement())
                .addElement(new Element.Builder<String>()
                        .setValue(contact[2])
                        .setType(ADDRESS)
                        .createElement())
                .createDocument();
    }).collect(Collectors.toList());
  2. How Fuzzy-Matcher works

    master

    Fuzzy-Matcher is a Java library designed to identify and group similar entities within a collection of documents. It operates by breaking down data through a hierarchical structure:

    1. Document: The top-level entity (e.g., a Contact).
    2. Element: Attributes within a document (e.g., name, address, email).
    3. Token: The smallest unit of data derived from an Element via Tokenization.

    The library then compares these tokens using a MatchType and calculates a similarity score through Scoring. The entire process is highly customizable through four stages: Pre-Processing, Tokenization, Match Type, and Scoring.

  3. Match Types and Tokenization Strategies

    master

    Fuzzy-Matcher supports several strategies for matching different data formats:

    • Exact Word Match: Uses Word tokenization and Equality matching. Good for names where word order might vary (e.g., "Wayne Grace Jr." vs "Grace Hilton Wayne").
    • Soundex Match: Uses Word-Soundex tokenization. Useful for phonetic similarities (e.g., "Steven" vs "Stephen").
    • NGram Match: Uses N-Gram tokenization. Ideal for strings that aren't easily split by words, like emails.
    • Nearest Neighbors Match: Uses Value tokenization and Nearest Neighbor matching. Best for continuous values like numeric amounts or dates where closeness matters more than exact equality.
  4. The Four Stages of Fuzzy Match

    master

    The fuzzy matching process consists of four customizable stages that allow you to tune how different data types are compared:

    1. Pre-Processing

    Accepts a Java Function to clean data before matching. Available defaults include:

    • Trim: Removes leading/trailing spaces (default).
    • Lower Case: Converts characters to lowercase (default).
    • Remove Special Chars: Keeps only alpha, numeric, and spaces (default for TEXT type).
    • Numeric: Strips non-numeric characters (default for NUMBER type).
    • Email: Strips the domain from an email to focus on the local part (default for EMAIL type).

    2. Tokenization

    Defines how an Element is broken into Tokens. You can provide a custom Function or use defaults:

    • Word: Splits by spaces.
    • N-Gram: Splits into 3-letter sequences.
    • Word-Soundex: Splits by words and encodes them using Apache Soundex.
    • Value: Uses the entire element value as a single token (useful for Nearest Neighbor matches).

    3. Match Type

    Determines how tokens are compared:

    • Equality: Checks for exact matches between token values.
    • Nearest Neighbor: Finds tokens within a specified neighborhood range (probability 0.0 - 1.0; defaults to 0.9).

    4. Scoring

    Calculates similarity at two levels:

    • Element scoring: Averages matching tokens against total tokens. Each element can have a threshold (default 0.3).
    • Document scoring: Compares matching elements against total elements. Elements can be assigned a weight for significance. Documents have a threshold (default 0.5).
  5. Understand MatchService Performance

    master

    Performance varies based on the MatchType used for your elements:

    • EQUALITY: Linear performance O(N), where N is the number of Elements in all documents. This is the default for most types.
    • NEAREST_NEIGHBOR: Performance is O(N logN). This is the default for NUMBER and DATE types. Performance is also influenced by the NeighborhoodRange setting; higher values generally perform better.

    Tip: To guarantee linear performance for numeric/date types, override the MatchType to EQUALITY instead of using a NeighborhoodRange of 1.0.

  6. Install Fuzzy-Matcher via Maven

    master

    Add the following dependency to your pom.xml to use Fuzzy-Matcher. Note that version 1.2.1 requires Java 11. If you are using Java 8, you must use version 1.1.x.

    <dependency>
        <groupId>com.intuit.fuzzymatcher</groupId>
        <artifactId>fuzzy-matcher</artifactId>
        <version>1.2.1</version>
    </dependency>
  7. Handle Match Results

    master

    The MatchService returns a Map<String, List<Match<Document>>> where the key is the Document.key. Each Match<Document> object contains the following information:

    // Accessing match details
    match.getData();        // The source Document on which the match is applied
    match.getMatchedWith();  // The target Document that the data matched with
    match.getScore().getResult(); // The probability score between 0.0 - 1.0
  8. Use MatchService to find duplicates or matches

    master

    The MatchService is the primary entry point for executing matches. It supports three distinct matching patterns depending on your use case.

    MatchService matchService = new MatchService();
    
    // 1. Match a list of Documents (De-duplication use case)
    matchService.applyMatchByDocId(List<Document> documents);
    
    // 2. Match a new list of Documents against an existing list (Bulk import use case)
    matchService.applyMatchByDocId(List<Document> documents, List<Document> matchWith);
    
    // 3. Match a single Document against an existing list (Single creation use case)
    matchService.applyMatchByDocId(Document document, List<Document> matchWith);
  9. Reference: Element Configuration Keys

    master

    When constructing an Element, you can use the following configuration keys to fine-tune matching behavior:

    * __Value__ : String representation of the value to match
    * __Type__ : These are predefined elements, which apply relevant functions for "PreProcessing", "Tokenization" and "MatchType"
    * __Variance__: (Optional) To differentiate same element types in a document. eg. a document containing 2 NAME element one for "user" and one for "spouse"
    * __Threshold__: A double value between 0.0 - 1.0, above which the element is considered as match.
    * __Weight__: A value applied to an element to increase or decrease the document score. The default is 1.0.
    * __PreProcessingFunction__: Override The _PreProcessingFunction_ function defined by Type
    * __TokenizerFunction__: Override The _TokenizerFunction_ defined by Type
    * __MatchType__: Override the MatchType defined by Type
    * __NeighborhoodRange__: Relevant only for `NEAREST_NEIGHBORS` MatchType. Defines how close should the `Value` be, to be considered a match. Accepted values between 0.0 - 1.0 (defaults to 0.9)
  10. Configure Predefined Element Types

    master

    Fuzzy-Matcher provides several predefined Element Types with sensible defaults for preprocessing, tokenization, and matching logic. You can use these types directly or override their specific functions when building an Element.

    |  Element Type | PreProcessing Function | Tokenizer Function           | Match Type       |
    |---------------|------------------------|------------------------------|--------------------|
    | ___NAME___    | namePreprocessing()    | wordSoundexEncodeTokenizer() |     EQUALITY       |
    | ___TEXT___    | removeSpecialChars()   | wordTokenizer()              |     EQUALITY       |
    | ___ADDRESS___ | addressPreprocessing() | wordSoundexEncodeTokenizer() |     EQUALITY       |
    | ___EMAIL___   | removeDomain()         | triGramTokenizer()           |     EQUALITY       |
    | ___PHONE___   | numericValue()         | decaGramTokenizer()          |     EQUALITY       |
    | ___NUMBER___  | numberPreprocessing()  | valueTokenizer()              | NEAREST_NEIGHBORS |
    | ___DATE___    | none()                 | valueTokenizer()              | NEAREST_NEIGHBORS |
    | ___AGE___     | numberPreprocessing() | valueTokenizer()              | NEAREST_NEIGHBORS |
  11. Reference: Document Configuration Keys

    master

    When constructing a Document, the following configuration fields are available:

    * __Key__: Required field indicating unique primary key of the document
    * __Elements__: Set of elements for each document
    * __Threshold__: A double value between 0.0 - 1.0, above which the document is considered as match.