# Cluster Similar Values

Group near-duplicate values in a column (typos, casing, spacing) and get a canonical form per cluster. Runs in your browser, nothing is uploaded, free.

## Run it

- **CLI:** `gizza tool cluster-similar-values "New York
new york
New  York
Nwe York
Boston"`
- **Web:** https://gizza.ai/tools/cluster-similar-values/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/cluster-similar-values/tool.json

## Inputs

- `data` — Values (CSV, or one per line) _(field)_
- `column` — Column (name or 1-based index; blank = the only column) _(field)_
- `delimiter` — Delimiter (, tab ; |) _(field)_
- `header` — First row is a header _(field)_
- `threshold` — Similarity threshold (0–100) _(field)_
- `normalize_case` — Ignore case (USA = usa) _(field)_
- `normalize_spacing` — Ignore extra spacing (New  York = New York) _(field)_
- `output` — Output format _(field)_

## Output

- Clusters (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `data` — Values (CSV, or one per line)
- `column` — Column (name or 1-based index; blank = the only column)
- `delimiter` — Delimiter (, tab ; |)
- `header` — First row is a header
- `threshold` — Similarity threshold (0–100)
- `normalize_case` — Ignore case (USA = usa)
- `normalize_spacing` — Ignore extra spacing (New  York = New York)
- `output` — Output format

Example: `https://gizza.ai/tools/cluster-similar-values/?data=New%20York%0Anew%20york%0ANew%20%20York%0ANwe%20York%0ABoston&column=city&delimiter=%2C&header=true&threshold=85&normalize_case=true&normalize_spacing=true&output=markdown`

---

## Cluster similar values

Real-world columns are full of the "same" value written many ways — `New York`,
`new york`, `New  York`, `Nwe York`. This tool **fuzzy-clusters** the values in
one column so those near-duplicates land in the same group, then proposes a
**canonical form** (the most frequent original) for each cluster. Feed it a CSV
or a plain list, one value per line. Everything runs in your browser; nothing is
uploaded.

### How it works

Each value is compared with a normalized **Levenshtein** edit-distance ratio
scored 0–100. Two values join the same cluster when their similarity is at or
above the **threshold**. Before comparing, values are optionally folded to ignore
letter **case** and extra **spacing**, so those differences don't count against a
match. The most frequent original in each cluster becomes its canonical
suggestion.

### Worked example

Input (one value per line), threshold `70`:

```
New York
new york
New  York
Nwe York
Boston
```

The four New-York variants (a typo, a case change, a double space) cluster
together with canonical **New York**, while **Boston** stays on its own. The
Mapping table then gives you every `original → canonical` pair to apply back to
your data.

### Options

- **Column** — for a CSV, the header name (with *First row is a header* on) or a
  1-based index. Blank uses the only column, which is what a newline list is.
- **Delimiter** — comma, tab, semicolon, pipe, or any single character (ignored
  for a plain list with no separators).
- **Threshold (0–100)** — higher is stricter: `100` merges only values that are
  identical after normalization; lower merges looser matches. `85` is a good
  start; drop toward `70` to catch more typos, raise it if unrelated values merge.
- **Ignore case / Ignore extra spacing** — fold those differences before
  comparing (on by default).
- **Output** — *markdown* (clusters plus a mapping table), *csv* (a flat
  `cluster,original,canonical,count` mapping you can join back), or *json*
  (structured clusters with per-value counts).

### FAQ

<details>
<summary>Which value becomes the canonical suggestion?</summary>

The most frequent original value in the cluster (ties break toward the one seen
first). It's kept exactly as it appears in your data — casing and spacing intact —
so you can trust it as the "correct" spelling to standardize on.

</details>

<details>
<summary>How do I turn a threshold into "how many typos are allowed"?</summary>

The score is `(1 − edits ÷ length) × 100`, where length is the longer of the two
values. So for an 8-character value, a threshold of `85` tolerates about one edit
(insert, delete, or substitute a character); `75` tolerates about two. Shorter
values need a lower threshold to merge, since a single edit is a bigger fraction.

</details>

<details>
<summary>Does it change my data or just report clusters?</summary>

It only reports. You get the clusters and a mapping table — nothing in your input
is rewritten. Use the CSV mapping (`original → canonical`) to apply the merges in
your spreadsheet or script.

</details>

<details>
<summary>How is this different from removing duplicate rows?</summary>

Plain de-duplication only removes rows that match *exactly*. This finds values
that are *nearly* the same — typos, casing, and spacing differences — which exact
matching misses, and suggests a single canonical spelling to standardize them to.

</details>

<details>
<summary>What are the limits?</summary>

It clusters one column at a time and compares values by character edits, so it's
ideal for names, cities, companies, and tags — not for matching semantically
equal but differently-worded phrases. Blank cells are skipped. Greedy clustering
compares each value to its cluster's most-frequent seed, so extremely large,
noisy columns may group slightly differently than an exhaustive pairwise pass.

</details>

<details>
<summary>Is my data uploaded?</summary>

No — it's processed locally with WebAssembly and never leaves your browser.

</details>

## Related tools

- [Outlier detector](https://gizza.ai/tools/outlier-detector/): Find outliers in a list of numbers using the z-score, modified z-score (MAD) and IQR (Tukey's fences) methods, in your browser. Free, private, no upload.
- [Remove Duplicate Lines](https://gizza.ai/tools/remove-duplicate-lines/): Remove duplicate lines from text in your browser — keep first or last occurrence, ignore case or whitespace, uniq-style consecutive mode. Free, private.
- [Extract Action Items from Meeting Notes](https://gizza.ai/tools/action-item-extractor/): Extract action items, owners, and decisions from meeting notes or daily notes with deterministic rules. Markdown checklist or JSON, private in-browser.
- [Amazon Order Analyzer](https://gizza.ai/tools/amazon-order-analyzer/): Paste an Amazon order-history CSV export to summarize total spend by month, top items, and category breakdowns. Browser-only, private, with Markdown or JSON output.
- [Base Decoder](https://gizza.ai/tools/base-decoder/): Auto-detect and decode Base16, Base32, Base45, Base58, Base64, and Base85 text, including nested layers, locally in your browser.
