Unit of outcome. One row per resolved domain. Deals, win/loss labels, and firmographics live here. This is what gets clustered.
Most tools score accounts against a description of your ideal customer. This one scores them against your outcomes — the deals you actually won and lost — and turns a few dozen labels into a living map of a market.
Every account-based platform will sell you a score. Almost all of them compute it the same way: you write down who your ideal customer is — industry, size, a few technographics — and the tool ranks the world by resemblance to that story. The story is a hypothesis, and it is usually wrong at the edges in exactly the places that matter.
We start from the other end. The only ground truth in go-to-market is which deals closed-won and which closed-lost. That signal is small, noisy, and precious — and most systems either throw it away or bury it inside weights they will not show you. We keep it, and we build everything on top of it.
The vocabulary of the map is simple. Keystones are communities of accounts with a distinctive win/loss signature — green where you win, red where you lose. The halo is the soft ring of lookalikes around a winning keystone. Buying groups are the people inside an account who actually decide. The rest of this page is how those three things get built, in order.
B2B revenue arrives at the account level, so the account is the unit of outcome — a deal attaches to a company. Inside that company is a buying group: the role-tagged set of people who evaluate, champion, and sign. Below them sit individuals, the unit of contact and identification, whose behavior rolls up to the account.
This ordering is load-bearing. Clustering, polarity, and lookalike scoring all operate primarily on company vectors. People are a secondary lens — once an account lights up, the buying group tells you whom to reach and in what role. A one-person business is just the degenerate case: a buying group of one.
Unit of outcome. One row per resolved domain. Deals, win/loss labels, and firmographics live here. This is what gets clustered.
Unit of decision. The people at an account, tagged by buying role, assembled by domain match under trust caps (see §07).
Unit of contact. Identified visitors and known contacts. Behavior (page views, in-market topics) rolls up to the account.
Before anything can be clustered it has to become a point in a high-dimensional space. Each entity is first serialized into a canonical text description assembled in a fixed field order — industry, then size band, revenue band, geography, description, and finally a sentence describing the roster. The order is locked deliberately: shuffling those fields measurably degrades downstream retrieval quality, so the template is versioned and frozen.
That text is embedded with a modern text-embedding model into a 1024-dimensional vector, stored in Postgres via pgvector behind an HNSW index for fast nearest-neighbor search. Every embedding is keyed by a hash of its source text plus the model and template version — so an unchanged account is never paid for twice, and a re-model only re-embeds what actually moved.
A company embedding is its own artifact, built from the company's own canonical text — never the mean of its members' vectors. Averaging people washes out exactly the firmographic signal that distinguishes accounts, so the company grain is embedded directly.
A thousand-dimensional cloud isn't a map yet. We reduce it with UMAP twice: once into a ~15-dimensional clustering space that preserves neighborhood structure, and once into the 2-D layout you actually see. Both projections are computed server-side with a fixed random seed and cached — the browser never runs a physics simulation on tens of thousands of nodes; it renders a precomputed layout.
Then HDBSCAN finds the communities. Crucially it produces soft membership: every account gets a probability of belonging to each cluster rather than a hard assignment. That soft membership is where the halo falls out for free — an account sitting on the fringe of a winning community, with partial membership, is by definition a lookalike.
Nodes are entities; edges come in two flavors, each capped so the render stays legible:
A fact, not a similarity. People sharing a company are linked. Small accounts get a full clique; large ones collapse to a hub-and-spoke from the highest-confidence member so edge counts don't explode.
k-nearest-neighbors in the 2-D layout stitch each cluster together. Edge weight is inverse layout distance — near neighbors draw bold, far ones fade.
The map can't draw every node, so it samples the highest-confidence members per community under a fixed budget — and the edge builder is handed the exact same sample, sorted the exact same way. Lines only ever connect nodes you can actually see. Sampling order and edge placement are one coupled decision, on purpose.
A cluster earns keystone status when its win/loss mix is different enough from your baseline that we would bet real money on the difference. The hard part isn't detecting a signal — it's not hallucinating one out of four data points. So a cluster passes through a three-layer statistical gate before it's allowed to claim anything.
A 4-deal cluster at "100% win rate" is not 100%. Each cluster's rate is pulled toward your overall win rate with a Beta(·) prior worth ~10 pseudo-deals, and we report a 95% credible interval — a range, never a bare point estimate.
Is this cluster's split genuinely unlike the rest of the population, or just variance? A two-sided exact test yields a p-value. Below a floor of n = 4 deals, the verdict is simply no verdict.
Test many clusters and some will look "significant" by luck. We control the false-discovery rate across all clusters at once (q ≈ 0.15), so the green ones survived multiple-comparison correction, not chance.
Survivors are ranked by WRAcc — weighted relative accuracy, which rewards a cluster for being both large (coverage) and distinctive (lift) rather than a tiny pocket of purity. Then each is tiered by how much we trust it:
Same 77% raw win rate, opposite verdicts. Four deals shrink hard and carry a credible interval too wide to act on; fifty-two barely move and earn a keystone. The map is built to under-claim — a cluster that's only 58% wins from a shared funnel stays neutral grey rather than being painted green for a demo.
There are two ways to look like a winner. Geometrically — sitting near a winning keystone in embedding space, which is the halo. And by a trained scorer that reads an account's features and returns a fit score. The geometry is free; the scorer is where the discipline lives. It is built, deliberately, to be reproducible and to know when it should keep quiet.
≥20 wins and ≥20 losses before it trains at all. Under that threshold it returns nothing and says why — no fit scores invented from ten examples.
PCA on every account, labeled or not, with a fixed seed. Because the reduction is unsupervised, no label can leak into the feature space it produces.
Logistic vs. LightGBM, chosen by stratified 5-fold cross-validation. At low sample counts logistic regression usually wins, and we let it — simpler and steadier.
Platt scaling on out-of-fold predictions. We then report percentiles, not raw probabilities — under positive-unlabeled data, ranks are trustworthy and absolute probabilities are not.
Only signals an unknown prospect could also have are allowed to feed the model — page views, site visits, in-market topics, hiring activity. Never "they replied to our email" or "they reached stage 3 in the CRM," because you only observe those for people already in your funnel. Train on those and the model just learns to recognize your existing pipeline.
And the output is not a single black-box number. The scorer emits its top feature contributions, the loss exclusions — the traits that predict losing, so you can stop spending on them — and a reproducibility line. Negative lookalikes are a first-class deliverable, which is exactly the thing intent vendors won't give you: the losers, labeled, and the weights, shown.
A company can sell into more than one ideal customer profile — a self-serve motion and an enterprise motion, say — and blending them lies about both. A 70% win rate that's really 90% in one segment and 40% in another describes neither.
So the ICP is promoted from an implicit singleton to a first-class entity, and every downstream artifact is keyed by it: communities, memberships, edges, fit scores, audiences, layouts, snapshots. Keystone baselines and lookalike training run per ICP. A winner discovered in one profile never touches the baseline of another, and the same account can carry different fit scores under different profiles — because it genuinely is a different bet in each.
When a client has exactly one profile, the stratified pipeline is byte-identical to the un-stratified one — the machinery is dormant until a second ICP exists. Correctness first; the multiplicity is there when you need it, invisible when you don't.
People join an account's buying group by email-domain match — a deliberately simple, binary rule — but simplicity needs guardrails. Each match is capped by a per-size-band roster ceiling: a company in the "11–25 employees" band that resolves 400 matched people is a data error, not a buying group, and gets dropped to an "unattributed" residual. Shared and freemail domains are blocklisted so a thousand strangers at one webmail host don't fuse into a fake account.
Outcomes are then de-duplicated to the latest closed deal per company, and an invariant is enforced: a company is never simultaneously a win and a loss. Clean labels in, honest keystones out.
Over the 2-D layout the map paints a smoothed win/loss lift field — a kernel-density estimate normalized so one deal reads as roughly one unit, masked wherever evidence is too thin to mean anything. You can see, at a glance, the regions where wins concentrate and where they evaporate.
Then the map does work. A keystone or its halo becomes an audience — pushed to email sequences, synced to your CRM, or mirrored into ad platforms as a custom audience. The outreach produces replies, meetings, and eventually new closed deals. Those come back as fresh labels, the model re-trains, and the keystones sharpen. That is the loop — and it is the only moat that compounds. Warehouse row counts don't; a tightening outcome model does.
| Parameter | Value | Where it bites |
|---|---|---|
| Embedding dimension | 1024 | text-embedding model, HNSW in pgvector |
| PCA components | 8 | full-SVD, fixed seed, fit on all accounts |
| Keystone floor · nmin | 4 | below this, no win/loss verdict |
| Empirical-Bayes prior strength | ≈10 | pseudo-deals of pull toward baseline |
| FDR level · q | 0.15 | Benjamini-Hochberg across all clusters |
| Watch-tier lift | 0.10 | early-signal threshold vs. baseline |
| Scorer training gate | 20W / 20L | minimum labels before it trains |
| Cross-validation | 5-fold | stratified; picks logistic vs. LightGBM |
| Same-company clique max | 6 | above this, hub-and-spoke not clique |
| Layout k-NN | 3 | same-community stitching edges |
| Company similarity · k / floor | 6 / 0.55 | cosine neighbors between accounts |
| Edge budget | 5k + 5k | relational + visual, per client·ICP |
| Heat grid | 96² · σ2.5 | KDE lift surface, masked ≥0.35 |