Omniscope Custom Blocks › Preparation/Join/Fuzzy-Match

Fuzzy Match

Finds near-duplicate records within one input (with group IDs), or the best matching record in a second input, using fuzzy text similarity.

Preparation › Join Python visokio-agents

Open the demo in Omniscope Download demo.ioz Sample data: crm-accounts.csv Sample data: invoices-to-match.csv Sample data: supplier-master.csv Source on GitHub

Items tagged visokio-agents are community examples built by Visokio's agents, to extend Omniscope's core blocks and views with popular, specialist and more unusual use cases, and to show what anyone, people or agents, can build on Omniscope. They are tested by automated tests and were run on a real Omniscope server. They were not reviewed by Omniscope's core team, so they are not on a par with the core blocks and views, which have years of manual, functional and unit tests behind them. About

Omniscope custom block · Preparation

Find the duplicates your exact joins miss. Group near-identical customers, suppliers or products, or match messy names to a clean master list, with a score for every match.

Python · pandas · nothing extra to install

The problem it solves

The same customer turns up as Acme Widgets Ltd, ACME Widgets Limited and Acme Widget Ltd.. An exact join or de-duplicate treats them as three different companies, so spend is split, campaigns double-mail and supplier analysis under-counts. Fixing it by hand does not scale, and formulas can only compare one pair of values at a time.

Fuzzy Match compares records by similarity: it ignores case, punctuation, accents and company suffixes, tolerates typos and word order, and returns a similarity score you control with a single threshold.

How it works

What goes in

De-duplicate demo: a CRM export (one input)

Account ID Company Town Postcode Annual Spend
A001 Acme Widgets Ltd Leeds LS1 4AP 12500
A002 ACME Widgets Limited Leeds LS1 4AP 8300
A003 Acme Widget Ltd. Leeds LS1 4AP 950
A004 Brightwater Plumbing Bristol BS2 0JA 4200
A005 Bright Water Plumbing Services Bristol BS2 0JA 3100
A006 Northern Rail Supplies plc York YO1 7HH 22000
A007 Cotswold Organic Farms Cirencester GL7 1AA 7600
A008 Cotswold Organics Farm Cirencester GL7 1AA 2200

40 rows in the sample file.

Lookup demo: invoices (input 1) and supplier master (input 2)

Supplier names as typed on invoices, matched against a 20-row supplier master list.

Invoice Supplier on Invoice Postcode Amount
INV-5001 ACME WIDGETS LTD LS1 4AP 1240.50
INV-5002 Bright Water Plumbing BS2 0JA 380.00
INV-5003 Northern Rail Supplies YO1 7HH 9120.75
INV-5004 Cotswold Organics GL7 1AA 455.20
INV-5005 Harbor View Hotel PL1 2PB 2210.00
INV-5006 Pennine Eng. Group HD1 2TP 15600.00

20 rows in the sample file.

The options

Option Demo setting What it does
Match field Company The text field to compare, such as a company or customer name.
Must match exactly (optional) Postcode Only records with the same value in this field are compared, such as postcode or country. Improves precision and makes large inputs much faster.
Similarity measure Jaro-Winkler, any word order (recommended for names) How the similarity of two values is scored, from 0 (nothing in common) to 1 (identical after clean-up).
Match threshold 0.88 Pairs scoring at or above this value count as a match. 0.85 to 0.92 suits company names.
Ignore case, accents and punctuation On Compare "Café & Co." and "cafe and co" as the same text.
Ignore company suffixes On Drop words such as Ltd, Limited, plc, LLP, Inc, Corp, Co, GmbH and The before comparing.
Matches per record (lookup mode) 1 Lookup demo: best match only. The lookup demo uses the Word set measure with threshold 0.85.

What comes out

Matched records (de-duplicate)

Records sharing a Group ID are the same account. Filter on Is Group Master = Yes for a clean list, or aggregate by Group ID.

Account ID Company Postcode Annual Spend Group ID Group Size Is Group Master Best Match Score
A001 Acme Widgets Ltd LS1 4AP 12500 1 3 Yes 1
A002 ACME Widgets Limited LS1 4AP 8300 1 3 No 1
A003 Acme Widget Ltd. LS1 4AP 950 1 3 No 0.9833
A004 Brightwater Plumbing BS2 0JA 4200 2 1 Yes
A005 Bright Water Plumbing Services BS2 0JA 3100 3 1 Yes
A006 Northern Rail Supplies plc YO1 7HH 22000 4 1 Yes
A007 Cotswold Organic Farms GL7 1AA 7600 5 2 Yes 0.9591
A008 Cotswold Organics Farm GL7 1AA 2200 5 2 No 0.9591
A009 Harbour View Hotel PL1 2PB 15400 6 2 Yes 1
A010 The Harbour View Hotel PL1 2PB 6100 6 2 No 1
A011 Pennine Engineering Group HD1 2TP 31000 7 2 Yes 0.984
A012 Pennine Engineering Grp HD1 2TP 4500 7 2 No 0.984

Matched records (lookup)

Invoice names resolved to supplier numbers, even with typos (Kingsfisher), missing words (Solent Marine) and American spelling (Harbor).

Invoice Supplier on Invoice Match: Supplier No Match: Supplier Name Match Score Match Status
INV-5001 ACME WIDGETS LTD S100 Acme Widgets Limited 1 Matched
INV-5002 Bright Water Plumbing No match
INV-5003 Northern Rail Supplies S102 Northern Rail Supplies PLC 1 Matched
INV-5004 Cotswold Organics No match
INV-5005 Harbor View Hotel S104 Harbour View Hotel Ltd 0.9444 Matched
INV-5006 Pennine Eng. Group No match
INV-5007 Riverside Dental S106 Riverside Dental Practice 1 Matched
INV-5008 Thames Valley Logistic S107 Thames Valley Logistics Limited 0.9565 Matched
INV-5009 Highland Coffee Roasters Ltd S108 Highland Coffee Roasters 1 Matched
INV-5010 Lakeland Outdoor S109 Lakeland Outdoor Gear Ltd 1 Matched

Match pairs

Record 1 Record 2 Value 1 Value 2 Score Group ID
1 2 Acme Widgets Ltd ACME Widgets Limited 1 1
1 3 Acme Widgets Ltd Acme Widget Ltd. 0.9833 1
2 3 ACME Widgets Limited Acme Widget Ltd. 0.9833 1
7 8 Cotswold Organic Farms Cotswold Organics Farm 0.9591 5
9 10 Harbour View Hotel The Harbour View Hotel 1 6
11 12 Pennine Engineering Group Pennine Engineering Grp 0.984 7
Duplicates hide your biggest customers: consolidating Fuzzy Match groups shows each account's true annual spend (synthetic data).
Duplicates hide your biggest customers: consolidating Fuzzy Match groups shows each account's true annual spend (synthetic data).

Duplicates hide your biggest customers: consolidating Fuzzy Match groups shows each account's true annual spend (synthetic data).

Where it pays off

Retail and e-commerce: Single customer view

Merge customers who registered twice, ordered as guests or were imported from a loyalty scheme. Campaigns stop double-mailing and lifetime value is measured per real customer.

Finance and procurement: Spend analysis and duplicate vendors

Match invoice supplier names to the vendor master so spend rolls up correctly, and flag vendors set up twice: a common route to duplicate payments.

Healthcare and public sector: Record linkage across systems

Link people across systems that do not share an ID, using name plus date of birth or postcode, with every link scored for human review.

Mergers and data migration: Consolidate two CRMs

After an acquisition, match the two account lists, keep one master per company and carry the other system's IDs across for reconciliation.

Use cases describe typical scenarios and are illustrative.

Why do this in Omniscope

How it fits into an Omniscope workflow

CRM export → Fuzzy Match → Aggregate (by Group ID) → Report

Drop Fuzzy Match after any input block. Its first output feeds an Aggregate block (sum spend by Group ID) or a Record filter (keep group masters); the Match pairs output feeds a review table in a Report, where a data steward can check borderline scores.

For lookups, connect the messy data to the first input and the clean master list to the second. Combine with a Record filter on Match Status = No match to build an exceptions list that refreshes on every run.

Matching, grouping and the steward's review table share one report, so a corrected group flows straight into the spend totals on the next run.

In one step

Two modes in one block (purge duplicates within one source, or match two sources), with a match threshold and a pairs output, and no match keys to build by hand. Results go straight into interactive reports.

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder): a CRM export with duplicate accounts. Look at the CRM Accounts table: Acme Widgets Ltd, ACME Widgets Limited and Acme Widget Ltd. are clearly one customer.
  2. The question: who is our biggest customer? An exact de-duplicate says three different companies, so the answer is wrong.
  3. Open the Fuzzy Match block: match on Company, must match exactly on Postcode, threshold 0.88. That is all the configuration.
  4. Look at the output: Group ID and Group Size. 40 records become 26 accounts. Open the Match pairs output to see the scores for review.
  5. Look at the chart of consolidated spend: the real top accounts only appear after matching.
  6. Switch to the second workflow: invoices matched to the supplier master, including typos and missing words, with a No match list for follow-up.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses pandas, plus the Python standard library (collections, re, unicodedata).

pandas and numpy are part of Omniscope's Docker Python image, and the block was run in both host mode and Docker mode on an Omniscope server, with the same results. It needs nothing else installed.

Tested

Both demo workflows ran without errors on an Omniscope server: de-duplicating the CRM accounts (40 records in Matched records, 15 in Match pairs) and matching invoices to the supplier master (20 and 15). Automated tests also cover normal data, empty input, wrong types and large input.

Reference

Fields it reads

NameTypeWhat it does
Match fieldFieldThe text field to compare, such as a company or customer name.
Match field in second inputFieldLookup mode only. Leave empty to use the field with the same name as the match field.
Second field to compare (optional)FieldAn extra field compared with the same measure, such as an address line. Blended into the score using the weight below.
Second field in second inputFieldLookup mode only. Leave empty to use the field with the same name.
Must match exactly (optional)FieldOnly records with the same value in this field are compared, such as postcode or country. Improves precision and speeds up large inputs.
Must match exactly, second inputFieldLookup mode only. Leave empty to use the field with the same name.

Options

NameTypeWhat it does
Weight of second fieldNumberShare of the score that comes from the second field, from 0 to 1.
Similarity measureChoiceHow the similarity of two values is scored, from 0 (nothing in common) to 1 (identical after clean-up).
Match thresholdNumberPairs scoring at or above this value count as a match. 0.85 to 0.92 suits company names.
Matches per record (lookup mode)Whole numberHow many of the best matches to return for each record of the first input.
Ignore case, accents and punctuationYes / noCompare "Café & Co." and "cafe and co" as the same text.
Ignore company suffixesYes / noDrop words such as Ltd, Limited, plc, LLP, Inc, Corp, Co, GmbH and The before comparing.
Other words to ignoreTextComma-separated words to drop before comparing, such as services, group.

Outputs

OutputWhat it holds
MatchedDe-duplicate: the input with Group ID, Group Size, Is Group Master and Best Match Score. Lookup: the first input with the best match from the second input appended.
PairsEvery pair scoring at or above the threshold, with both values and the score.