Skip to main content

Generate random human names under constraints, weighted by real-world frequency data.

Project description

nominate

Generate random human names under constraints, weighted by real-world frequency data.

nominate samples forenames and surnames from country-level census/demographic frequency data (derived from the Onomaverse names dataset, CC BY 4.0), so generated names are as common or as rare as you ask them to be. It is built for narrative use ("name this character") but works anywhere you need plausible names.

The full dataset (110 countries, ~6 MB) ships inside the package — no downloads, no network access at runtime.

Features

  • Weighted sampling: names are drawn proportionally to how often they actually occur.
  • Convention-aware rendering: countries that write the family name first (Vietnam, Korea, China, Hungary, ...) come out that way ("Nguyễn Văn An").
  • Constraints: country/region, gender, syllable count, regex, rhyme / phoneme inclusion-exclusion, uniqueness (exclusion lists), and commonness percentiles.
  • Partial names: freeze known forenames/surnames and complete the rest.
  • Reverse classification: given a name, estimate gender and likely countries.
  • Python API and a CLI.

Install

pip install nominate

Quick start (Python)

from nominate import NameGenerator

gen = NameGenerator(countries=["US"], seed=42)

# One forename + one surname, letting the data decide gender:
name = gen.generate()
print(name.full)

# A common-ish two-syllable feminine name starting with A:
name = gen.generate(
    gender="F",
    syllables=(2, 3),
    regex=r"^A",
    percentile=(0.5, 1.0),
)

# Complete a partial name ("I know the first name, need a surname"):
name = gen.generate(forenames=1, surnames=1, frozen_forenames=["James"])

# A sibling for an existing character (shared surname, unique forename):
name = gen.generate(
    frozen_surnames=["Kowalski"],
    exclude={"Anna"},          # already used
)

# Rhymes and phonemes:
name = gen.generate(rhymes_with="Kelly", exclude_phonemes=["TH"])

# Whole regions, or everything:
gen = NameGenerator(region="europe")
gen = NameGenerator()          # all 110 countries

Reverse classification:

from nominate import classify

result = classify("Anna Kowalska")
result.gender_probabilities   # {"F": 0.997, "M": 0.003}
result.countries              # [("PL", 0.75), ("SE", 0.03), ...]

# Family-name-first names are detected and read in the right order:
result = classify("Nguyễn Văn An")
result.forename, result.surname   # ("An", "Nguyễn")
result.surname_first              # True

Quick start (CLI)

# Generate names:
nominate generate -c US -n 10
nominate generate -c US --gender f --syllables 2-3 --regex '^A' \
    --percentile 25-90 -n 5
nominate generate -c US --freeze-forename James -n 3
nominate generate --region europe -n 5
nominate generate -c US --rhymes-with Kelly --exclude-file used_names.txt

# Classify a name:
nominate classify "Anna Kowalska"

# Inspect the bundled data:
nominate data status
nominate data list --region oceania

Constraints reference

Constraint Python argument CLI flag
Country / region NameGenerator(countries=[...]), region="europe" --country/-c (repeatable), --region
Gender gender="M"/"F", strict_gender=True --gender, --strict-gender
Syllables syllables=2 or syllables=(2, 3) --syllables 2 or 2-3
Regex regex=r"^A.*y$" (case-insensitive by default) --regex
Rhyme rhymes_with="Kelly" --rhymes-with
Phonemes include_phonemes=[...], exclude_phonemes=[...] (ARPAbet) --include-phoneme, --exclude-phoneme
Uniqueness exclude={...} --exclude, --exclude-file
Likelihood percentile=(0.25, 0.9) (or 25-90) --percentile 25-90

Percentiles are within a country and name kind: percentile=(0.9, 1.0) means "the most common 10% of names", (0.0, 0.1) means "the rarest 10%".

By default, gendered sampling trusts the data: a name that is recorded for both genders can be drawn for either, proportionally to its counts. Passing strict_gender=True additionally drops names whose majority gender does not match the requested one.

Data

Per-country Parquet files (given/US.parquet, surname/US.parquet, ...) are bundled at nominate/_bundled/ inside the package. They are produced by the scripts in pipeline/, which merge several sources — the Onomaverse frequency data (via a Hugging Face bucket), the erpel1 Kaggle forenames/surnames dataset, and sigpwned's popular-names-by-country dataset — so that countries with thin census coverage are backfilled rather than silently underrepresented. Supplementary counts are rescaled or Zipf-extrapolated onto each country's measured scale and never override measured data. Everything is enriched with romanizations, ARPAbet phonemes, syllable counts, rhyme keys, and percentile ranks. See pipeline/README.md for details and how to rebuild.

You can point the library at a custom build with NameGenerator(data_dir=...) or the NOMINATE_DATA_DIR environment variable.

Phonetics are Latin-script oriented: names are romanized (via Onomaverse transliterations, falling back to unidecode) and looked up in CMUdict, with a heuristic grapheme-to-phoneme fallback for names CMUdict does not know.

Attribution

Bundled data is derived from:

License

MIT (code). Bundled data: CC BY 4.0 (see Attribution).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nominate-0.1.0.tar.gz (8.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nominate-0.1.0-py3-none-any.whl (8.6 MB view details)

Uploaded Python 3

File details

Details for the file nominate-0.1.0.tar.gz.

File metadata

  • Download URL: nominate-0.1.0.tar.gz
  • Upload date:
  • Size: 8.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nominate-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ca2a8e7b25478b7672293b3a2b9e9e4bf60b9b2dc9cb00407c366490aec5545b
MD5 245be8a143b3e8db54bbdd75cd774be7
BLAKE2b-256 30a8638b6729c8b503daf51d01129b4ec98366e85a0f2c2b5f74f09cac7db9f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for nominate-0.1.0.tar.gz:

Publisher: publish.yml on painebenjamin/nominate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nominate-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nominate-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nominate-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7c23e797c44f72eea201352cff43723999712c0714aa78c92166f0eb70051c35
MD5 38266258995a7b7bc5bd4eacdb91d3af
BLAKE2b-256 56ae2dfa3db263244acf415f25baf8ebfdd383504e83f4ec20dfc842ec150b3b

See more details on using hashes here.

Provenance

The following attestation bundles were made for nominate-0.1.0-py3-none-any.whl:

Publisher: publish.yml on painebenjamin/nominate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page