Continue → Overview
← All notes

Chinese name gender: what a character can and cannot tell you

6 min read coverage countries

Most writing systems fail us by returning nothing. Chinese fails us the other way: we answer almost every name and we are wrong about one in eight.

From the published benchmark, across 4,610 names in 25 countries:

Script Names Coverage Accuracy when answered End-to-end
Latin 3,195 98.0% 97.3% 95.3%
Han 222 99.5% 86.9% 86.5%
Hangul 200 99.5% 92.0% 91.5%

Coverage on Han is higher than on Latin. Accuracy is ten points lower. That inversion is the whole story of this market, and it is not a bug we are working around — it is a property of how Chinese given names are formed.

Why the ceiling is lower

European given names come from a finite inherited stock. Margaret is a name because other people were called Margaret; the name carries its gender as membership in a list.

Chinese given names are composed. A parent picks one or two characters for their meaning, sound and stroke balance. The pool is effectively open, and the gender signal lives in connotation rather than membership:

  • 伟 (wěi, "great, mighty") → male, probability 86 on 136 observations
  • 静 (jìng, "quiet, still") → female, probability 61 on 184 observations
  • 芳 (fāng, "fragrant") → female, probability 70

Note the second row. 静 skews female, but at 61% — barely. Plenty of men are called 静, and the data says so instead of rounding it up. A vendor reporting female there without the probability is handing you a coin flip wearing a suit.

This is why probability is load-bearing in Chinese and Korean markets in a way it is not in, say, France. Reading gender alone throws away the only field that distinguishes 86 from 61.

Send characters, not pinyin, when you have them

Romanisation destroys information twice.

Tone marks are dropped. wei collapses 伟 (wěi), 薇 (wēi), 微 (wēi), 威 (wēi) and 唯 (wéi) into one string. Some of those skew male, some female. What you get back is the blend.

Character identity is dropped. Even at the same tone, distinct characters with different gender skews share a syllable. Pinyin is a lossy hash of the thing you actually wanted to look up.

You can see the collapse directly. Wei and 伟 return the same answer — male, 86, 136 observations — because the romanised form resolves through the same entry. But 伟 is one character and Wei is every character that romanises to it. The number is identical; the evidence behind it is not.

Practical rule: if your source system stores Han characters, send Han characters. If it stores pinyin, send pinyin and lower your threshold.

The name-order mistake

This one is worth the price of the whole post.

Chinese names are written surname first: 张伟 is the surname 张 (Zhang) followed by the given name 伟 (Wei). When you send the characters as one string, the whole string is matched as a unit and you get a sensible answer.

Romanised, it goes wrong, because a name-extraction step that assumes "first token is the given name" is a Western assumption:

Input Name extracted Result
张伟 张伟 male, probability 90
Zhang Wei Zhang male, probability 73, total_names: 0, confidence: unverified
Wei Zhang Wei male, probability 86, total_names: 136, confidence: high

All three happen to say male. Only the last one says it for the right reason. Zhang Wei was classified on a surname — and Chinese surnames do carry a weak statistical gender lean, purely as an artifact of the population, which is exactly what makes this failure so quiet. You get a plausible answer with no error and no warning.

Two ways to avoid it:

  1. Put the given name alone in the name field. You almost always know which column it is.
  2. Send whatever you have, then read the name field in the response. It reports what was actually extracted. If it comes back Zhang, your extraction failed and your classification is meaningless — regardless of what gender says.

That second habit generalises. name is an audit field: it lets you separate extraction errors from classification errors, which are two different bugs with two different fixes.

Single characters are whole names

A detail that breaks Latin-centric pipelines. In J. Smith, a one-letter token is an initial and should be skipped. In Chinese, Japanese and Korean, one character is a complete given name — 伟 is Wei, 静 is Jing.

A normaliser that drops short tokens as initials makes the most common names in the target market invisible. Ours checks the script before applying that rule, so single Han, Hiragana, Katakana and Hangul characters are treated as names and everything else short is treated as an initial.

If you are building this yourself, it is the first thing to get right and the easiest to miss, because your test fixtures are probably in Latin.

Korean behaves the same way, slightly better

Hangul sits at 99.5% coverage and 92.0% accuracy — same shape as Han, a little kinder. Korean given names are also composed, usually from two syllable blocks, with the surname first.

박지훈 and 지훈 both resolve to male; the romanised Ji-hoon does too. As with Chinese, the romanisation is weaker evidence than the original script, and the surname-first ordering is the same trap.

What to do with 86.9%

Decide per use case, not per vendor.

Use Reasonable threshold
Salutation in a marketing email probability >= 85, accept medium confidence
Segmentation and aggregate reporting accept everything, keep null as its own bucket rather than imputing
Anything with a legal, medical or financial consequence do not infer gender from a name at all

That last row is not modesty. At a 13% error rate on 222 measured names, name inference is a reasonable prior and an unreasonable fact. If a wrong answer would harm the person it is about, ask them instead.

What we do not claim

The Han figure rests on 222 names from a deterministic fixture, not a population sample. It is reproducible — anyone can run the same file against us or against a competitor and get the same names — but it is a product regression test, not a census.

We also do not claim the mainland Chinese market is solved by ranking on Google. Discovery there runs through Baidu, and that is a separate problem from this one.

The parts you can check yourself are the response fields. Every answer carries probability, total_names, source and matched_as for precisely this reason — the details are in reading a gender response properly, and the endpoints are in the API reference.

Every claim on this page is measurable against your own list. The free tier is enough to check it.