3 Approaches to Business Similarity
Comparing attribute-based, embedding-based, and fuzzy matching on 6,218 real Boise businesses
The Problem
When you're building a local business intelligence layer, one of the first questions users ask about any company is: who else is like them?
"Similar businesses" sounds simple until you think about what "similar" actually means. A brewery in downtown Boise is similar to another brewery across town (same industry). But it's also similar to the taproom next door (same location, same foot traffic). And it's similar to a craft distillery in the same price range (same customer profile).
We needed a similarity engine that could surface meaningful matches across 6,218 businesses scraped from Google Maps and OpenStreetMap -- and we wanted to understand which approach would scale best as we expand city by city.
The Dataset
Each business record includes name, lat/lon, NAICS code, super category, business type, and B2B/B2C classification. The entire enrichment pipeline runs locally on a Mac Studio M4 Max -- no cloud compute, no API calls at inference time. The data playbook is designed to be replicable per city in a single night.
Three Approaches to Similarity
Each approach represents a different philosophy about what makes two businesses "similar." We ran all three against the full 6,218 business dataset to see how they compare.
A hand-tuned scoring function that combines five structured signals. No machine learning at match time -- every score is explainable and deterministic.
The idea: generate dense vector embeddings of each business profile, then find nearest neighbors via cosine similarity. This should capture latent semantic relationships that rule-based systems miss.
gemma4:e4b via Ollama's /api/embed endpoint returned empty vectors. The model doesn't natively support embedding generation -- it's a text generation model, not a bi-encoder. This is a known gap: not every Ollama model exposes usable embeddings.
Next step: test with a dedicated embedding model like nomic-embed-text or mxbai-embed-large.
Uses fuzzy string matching on business names and type labels. No structured data required beyond a name and a category tag. This is the simplest approach -- and it surfaces surprising cross-category connections that the attribute model misses.
Head-to-Head Results
| Metric | Model A Attribute |
Model B Embedding |
Model C Fuzzy |
|---|---|---|---|
| Coverage |
100%
|
0%
|
99.7%
|
| Avg Top Score |
89.5
|
--
|
77.6
|
| Matches/Business |
10
|
--
|
10
|
| Category Diversity |
1.0
|
--
|
1.14
|
| LLM at Match Time? | No | Yes | No |
Each approach has a different strength. The attribute model produces the highest-confidence matches because it leverages structured NAICS codes. The fuzzy model finds connections across category boundaries. And embedding-based search, once running with a proper bi-encoder, should capture semantic nuance that neither rule-based approach can.
Coverage Across 6,218 Businesses
In Practice: 10 Barrel Brewing
Here's what the attribute model returns for 10 Barrel Brewing, a local brewery in downtown Boise:
Same NAICS code (312120), same super category, same B2C classification, and all within a few miles of downtown. The attribute model nails this class of query.
Where Model C shines: the fuzzy matcher might also surface a craft distillery or a taproom with a similar name pattern -- cross-category matches that the attribute model won't find because the NAICS codes differ. For a user exploring a neighborhood, that kind of diversity is valuable.
Architecture: Why Deterministic Wins (For Now)
- + 100% explainable scores
- + Zero inference cost
- + Sub-millisecond per pair
- - Needs structured data
- - Misses semantic nuance
- + Captures latent patterns
- + Works on unstructured text
- + Improves with more data
- - Needs right model choice
- - Black-box similarity
- + Near-zero requirements
- + Good cross-category matches
- + Fast to implement
- - Lower confidence scores
- - Name-dependent (noisy)
Cost to Replicate
Takeaways
Structured attributes beat unstructured approaches when you have the data.
The attribute model's 89.5 avg score vs. fuzzy's 77.6 comes down to NAICS codes. If you've invested in enrichment, you should use it.
Not every LLM supports embeddings. Choose your model deliberately.
Text generation models and bi-encoder embedding models are fundamentally different architectures. Ollama's embed endpoint works with dedicated embedding models, not chat models.
Fuzzy matching is an underrated complement to structured search.
Model C's 1.14 category diversity means it surfaces matches the attribute model can't. The best similarity engine probably blends both.
$50 per city is a viable unit economics for local business intelligence.
Google Maps + OSM + local compute means you can build a business similarity layer for any metro area overnight. The playbook is replicable.
What's Next
The production system will use the attribute model as the primary ranker and blend in embedding-based and fuzzy signals for diversity. This feeds directly into OnlyData Club company profiles, where "similar businesses" is one of the core intelligence layers.
Building local business intelligence pipelines?
Follow on LinkedInProduct Hacker · Boise, Idaho · 2026