> ## Documentation Index
> Fetch the complete documentation index at: https://docs.creditbenchmark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Name Matching & CBID Mapping

> Credit Benchmark resolves free-text company names to CBIDs using a three-stage pipeline: candidate retrieval, feature engineering, and ML-based match scoring.

Each input returns ranked matches with a confidence score between 0 and 1.

<div style={{display: 'flex', alignItems: 'stretch', padding: '32px 24px', background: 'transparent', gap: '0', fontFamily: 'inherit', fontSize: '12px'}}>
  <div style={{flexShrink: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center', minWidth: '130px'}}>
    <div style={{position: 'relative', marginLeft: '24px', marginBottom: '24px'}}>
      <div style={{position: 'absolute', inset: 0, transform: 'translate(-24px, 24px)', border: '1px solid rgba(51,65,85,0.22)', background: 'transparent'}} />

      <div style={{position: 'absolute', inset: 0, transform: 'translate(-12px, 12px)', border: '1px solid rgba(51,65,85,0.3)', background: 'transparent'}} />

      <div style={{position: 'relative', zIndex: 1, border: '1.5px solid #334155', background: '#1e293b', color: '#f8fafc', padding: '12px 14px'}}>
        <div style={{fontWeight: 700, fontSize: '11px', letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: '8px', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '6px'}}>Entity</div>

        <div style={{fontSize: '10px', lineHeight: '1.9', color: '#94a3b8', fontFamily: 'monospace'}}>
          <div><span style={{color: '#7dd3fc'}}>entity\_name</span></div>
          <div><span style={{color: '#86efac'}}>country</span> <span style={{color: '#94a3b8'}}>(opt)</span></div>
          <div><span style={{color: '#86efac'}}>industry</span> <span style={{color: '#94a3b8'}}>(opt)</span></div>
          <div><span style={{color: '#86efac'}}>lei</span> <span style={{color: '#94a3b8'}}>(opt)</span></div>
        </div>
      </div>
    </div>
  </div>

  <div style={{flexShrink: 0, display: 'flex', alignItems: 'center', padding: '0 10px'}}>
    <div style={{width: '20px', height: '1.5px', background: '#94a3b8'}} />

    <div style={{width: 0, height: 0, borderTop: '4px solid transparent', borderBottom: '4px solid transparent', borderLeft: '6px solid #94a3b8'}} />
  </div>

  <div style={{flex: 1, display: 'flex', flexDirection: 'column', gap: '16px'}}>
    {/* Step 1: Candidate Retrieval */}

    <div style={{border: '1px solid #e2e8f0'}}>
      <div style={{background: '#1e3a8a', color: '#f8fafc', padding: '10px 14px'}}>
        <div style={{fontWeight: 700, fontSize: '11px', letterSpacing: '0.04em', textTransform: 'uppercase'}}>1 — Candidate Entity Retrieval</div>
      </div>

      <div style={{padding: '8px 14px', background: 'transparent', fontSize: '11px', lineHeight: '1.6'}}>
        <div>Searches the CB Entity Database for likely candidates</div>
      </div>
    </div>

    {/* Step 2: Feature Engineering */}

    <div style={{border: '1px solid #e2e8f0'}}>
      <div style={{background: '#1e40af', color: '#f8fafc', padding: '10px 14px'}}>
        <div style={{fontWeight: 700, fontSize: '11px', letterSpacing: '0.04em', textTransform: 'uppercase'}}>2 — Feature Engineering</div>
      </div>

      <div style={{padding: '8px 14px', background: 'transparent', fontSize: '11px', lineHeight: '1.6'}}>
        <div>Measures name similarity and metadata alignment per candidate</div>
      </div>
    </div>

    {/* Step 3: ML scoring */}

    <div style={{border: '1px solid #e2e8f0'}}>
      <div style={{background: '#4c1d95', color: '#f8fafc', padding: '10px 14px'}}>
        <div style={{fontWeight: 700, fontSize: '11px', letterSpacing: '0.04em', textTransform: 'uppercase'}}>3 — ML Scoring</div>
      </div>

      <div style={{padding: '8px 14px', background: 'transparent', fontSize: '11px', lineHeight: '1.6'}}>
        <div>Scores each candidate as a match probability</div>
      </div>
    </div>
  </div>

  <div style={{flexShrink: 0, display: 'flex', alignItems: 'center', padding: '0 10px'}}>
    <div style={{width: '20px', height: '1.5px', background: '#94a3b8'}} />

    <div style={{width: 0, height: 0, borderTop: '4px solid transparent', borderBottom: '4px solid transparent', borderLeft: '6px solid #94a3b8'}} />
  </div>

  <div style={{flexShrink: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center', minWidth: '130px'}}>
    <div style={{position: 'relative', marginLeft: '24px', marginBottom: '24px'}}>
      <div style={{position: 'absolute', inset: 0, transform: 'translate(-24px, 24px)', border: '1px solid rgba(51,65,85,0.22)', background: 'transparent'}} />

      <div style={{position: 'absolute', inset: 0, transform: 'translate(-12px, 12px)', border: '1px solid rgba(51,65,85,0.3)', background: 'transparent'}} />

      <div style={{position: 'relative', zIndex: 1, border: '1.5px solid #334155', background: '#1e293b', color: '#f8fafc', padding: '12px 14px'}}>
        <div style={{fontWeight: 700, fontSize: '11px', letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: '8px', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '6px'}}>Top Result</div>

        <div style={{fontSize: '10px', lineHeight: '1.9', color: '#94a3b8', fontFamily: 'monospace'}}>
          <div><span style={{color: '#7dd3fc'}}>CBId</span></div>
          <div><span style={{color: '#7dd3fc'}}>CBEntityName</span></div>
          <div><span style={{color: '#fbbf24'}}>confidence</span></div>
          <div><span style={{color: '#94a3b8'}}>rank</span></div>
        </div>
      </div>
    </div>
  </div>
</div>

This flow shows the end-to-end resolution workflow from input entity fields to ranked candidate results.

## Pipeline

### Candidate Entity Retrieval

The CB Entity Database supports approximate text search, returning a shortlist of plausible candidates. Retrieval uses [BM25 ranking](https://en.wikipedia.org/wiki/Okapi_BM25) — scoring candidates by term frequency and inverse document frequency — and normalises input text to handle punctuation, accents, legal suffixes, and common name variants.

Around 20 candidates are retrieved per name. This stage prioritises [recall over precision](https://en.wikipedia.org/wiki/Precision_and_recall): the true match must appear in the candidate set before scoring can begin.

### Feature Engineering

For each candidate, a feature vector $\mathbf{x}$ is built from dozens of individual signals, grouped into 4 categories:

| Category               | Examples                                                                                                                                                                                                    |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **String similarity**  | [Jaccard](https://en.wikipedia.org/wiki/Jaccard_index) token overlap, [Levenshtein](https://en.wikipedia.org/wiki/Levenshtein_distance) distance, [n-gram](https://en.wikipedia.org/wiki/N-gram) similarity |
| **Search relevance**   | [BM25](https://en.wikipedia.org/wiki/Okapi_BM25) score and rank position from the retrieval stage                                                                                                           |
| **Text normalisation** | Comparison after stripping punctuation, accents, legal suffixes, and name variants                                                                                                                          |
| **Metadata alignment** | Country, sector, and identifier (LEI) consistency between input and candidate                                                                                                                               |

### ML scoring

A machine learning classifier assigns a match probability to each candidate independently:

$$
\hat{p} = P(\text{match} \mid \mathbf{x})
$$

Candidates are ranked by $\hat{p}$ and the top results returned in the response.

#### Training

The model has been trained on an internal dataset of tens of thousands of labelled entity matches — each a true or false match pair. This is distinct from the CB Entity Database itself, which contains millions of records corresponding to observed entities from [bank submissions](/methodology/data-processing/data-submission). The model is retrained weekly as both the CB Entity Database and the entity resolution universe grow.

#### Testing

Performance is evaluated using [k-fold cross-validation](https://en.wikipedia.org/wiki/Cross-validation_\(statistics\)), ensuring metrics reflect generalisation across the full labelled dataset rather than a single train/test split. As the model is retrained on new data, performance is re-evaluated each cycle. Classification metrics are reported on the [Accuracy & Coverage](/api-reference/matching/performance) page.

## Confidence Score

Each candidate is returned with a score $\hat{p} \in [0, 1]$ reflecting the model's certainty it is the correct match.

Internally, we use the following bands as guidance, based on performance measured on our **testing data**:

| Range              | Signal       | Match Rate | Rationale                                                                                                    |
| ------------------ | ------------ | ---------- | ------------------------------------------------------------------------------------------------------------ |
| *p > 0.6*          | Strong match | **94.4%**  | High enough confidence to treat as a match without manual review                                             |
| *p in \[0.3, 0.6]* | Likely match | **\~65%**  | The model considers a match plausible but not certain — scores in this range warrant review before accepting |
| *p \< 0.3*         | Weak         | **\~35%**  | The candidate is less likely to be the correct match — typically surfaced only to confirm no match exists    |

These figures reflect **per-candidate** match rates. When multiple candidates are returned (`limit > 1`) at lower scores, the true entity may still be present somewhere in the result set — reviewing the top candidates collectively improves the chance of a correct resolution even when no single score is high.

See [Entity Resolution: Accuracy & Coverage](/api-reference/matching/performance) for full threshold trade-off analysis.
