Beginner perfumer · 111
Beginner perfumer #111: one parenthesis worth two thousand rows — which name normalisation actually pays
· 18 min read
The last article closed by saying normalisation should push the number higher and that I had not tried. This is the result. I split name normalisation into four layers and measured how many formula records each one recovers. Stripping punctuation and whitespace and unifying stereodescriptors like cis and (Z) recovers 147 records between them. Stripping dilution markers like '50% in DPG' recovers 16. Stripping the manufacturer parenthetical off the database name — (IFF), (Firmenich), (Givaudan) — recovers 2,003, more than ten times everything before it combined. The database stores hedione (Firmenich) while perfumers write hedione, and that one name accounts for 165 formulas. Coverage moves from 60.32% to 72.81%. But you cannot strip parentheses blindly: of the 1,096 names ending in one, 26 read (mixture of isomers) and 22 read (salt), and stripping those merges materials that are not the same.
About a 5 minute read.
The short version
- I split name normalisation into four layers and measured what each recovers:
| Step | Names matched | Records covered | Marginal gain |
|---|---|---|---|
| ① Exact match (baseline) | 1,050 | 10,545 (60.32%) | — |
| ② Strip punctuation and whitespace, unify stereodescriptors | 1,106 | 10,692 (61.16%) | +147 |
③ Strip dilution markers (50% in DPG) |
1,117 | 10,708 (61.26%) | +16 |
④ Strip the manufacturer parenthetical ((IFF)) |
1,382 | 12,711 (72.71%) | +2,003 |
- Step four is worth more than ten times the first three combined
- The database stores
hedione (Firmenich); perfumers writehedione. That one name is 165 formulas - But you cannot strip blindly: among those 1,096 names are
(mixture of isomers),(salt)and(whole plant)
The homework the last article left
Last round I examined the database's alias field and found that 95,214 aliases add three names, because 87.9% of them are truncated fragments.
That article's closing section said:
I did not compute how much fuzzy matching would recover. Everything here is exact string matching. Normalisation (stripping spaces and hyphens, unifying cis with (Z)) should push it higher, and I have not tried.
This is that experiment. And the answer differs from what I guessed: the three normalisations I listed turn out to be the three least useful ones.
What each layer is worth
I took the 2,429 distinct names in the 954-formula corpus and matched them against the database's
name and head_synonym, adding one normalisation at a time.
② Punctuation, whitespace, stereodescriptors: +147 records
The new matches look like this:
| Corpus writes | Database writes |
|---|---|
dihydro myrcenol |
dihydromyrcenol |
camphor |
(±)-camphor |
allyl alpha-ionone |
allyl-alpha-ionone |
dihydro beta ionone |
dihydro-beta-ionone |
One space, one hyphen, one (±). These really do block a match, and they affect 147 records.
③ Dilution markers: +16 records
| Corpus writes | Database writes |
|---|---|
maltol 5% in phenethyl alcohol |
maltol |
oakmoss absolute 50% in benzyl benzoate |
oakmoss absolute |
geraniol 980 |
geraniol |
I had expected this class to be large, given how full of dilutions formulas are. In fact the corpus records concentration separately from the ingredient name rather than inside it. Sixteen records.
④ The manufacturer parenthetical: +2,003 records
This is the only step that genuinely pays.
| Corpus writes | Database writes | Corpus occurrences |
|---|---|---|
hedione |
hedione (Firmenich) |
165 |
iso e super |
iso e super (IFF) |
104 |
galaxolide 50 ipm |
galaxolide 50 IPM (IFF) |
82 |
triplal |
triplal (IFF) |
63 |
lyral |
lyral (IFF) |
50 |
vertofix |
vertofix (IFF) |
50 |
Those six names alone come to 514 records.
And what are they? Hedione, Iso E Super, Galaxolide, Lyral, the synthetics modern perfumery leans on hardest. The database appends the manufacturer to the name and perfumers never write that parenthetical. One bracket keeps the backbone of modern perfumery outside the door.
1,096 entries in name or head_synonym end in a parenthetical. The most common:
| Inside the parentheses | Count |
|---|---|
(iff) |
168 |
(givaudan) |
100 |
(symrise) |
69 |
(firmenich) |
53 |
(bedoukian) |
16 |
(takasago) |
11 |
But not blindly
Among those same 1,096 are parentheticals that are not manufacturers:
| Inside the parentheses | Count |
|---|---|
(mixture of isomers) |
26 |
(fixed) |
24 |
(salt) |
22 |
(mixed isomers) |
15 |
(whole plant) |
14 |
(salt) is a salt, which is not the free acid. (mixture of isomers) is not the single isomer.
(whole plant) is not the root extract.
Stripping those merges materials that are not the same, which is worse than failing to match.
The correct approach is a manufacturer allowlist, not stripping every parenthetical. The list I used holds twelve names (IFF, Givaudan, Firmenich, Symrise, Takasago, Bedoukian and others).
One thing I put too strongly last time
In the methyl cedryl ketone entry I wrote that the corpus
calls it by five names and that "counting only the database's official name methyl cedryl ketone
misses 60 formulas."
That sentence is accurate, but I made it sound unsolvable. The database's head_synonym field
holds vertofix (IFF), and stripping one parenthetical matches all 50 vertofix rows immediately.
The only spelling that genuinely needs hand work is acetyl cedrene, at 7 formulas.
The hard part is smaller than I said.
What the remaining 27.19% is
At 72.81% there are still 1,044 names and 4,753 records unmatched. They fall into clear types:
| Type | Example | Corpus count |
|---|---|---|
| Abbreviations | dipg (dipropylene glycol) |
445 |
| Old aldehyde numbering | aldehyde c-14, aldehyde c-10, aldehyde c-12 mna |
64 / 64 / 60 |
| Different common-name skeleton | cis-3-hexenol against the database's (Z)-3-hexen-1-ol |
100 |
| Natural oils with qualifiers | bergamot oil bergaptene reduced, ylang ylang oil |
132 / 113 |
| Spelling variants | styrallyl acetate (the database has styralyl acetate) |
78 |
The aldehyde C-numbers are the most stubborn. Whether aldehyde c-10 is nonanal or decanal,
and the fact that aldehyde c-12 mna and aldehyde c-12 lauric are two entirely different
materials sharing one number, both come from an early twentieth-century trade convention with no
one-to-one relationship to chemical structure.
No string normalisation reaches it; you need a lookup table.
The rule you can use directly
If you want to match your own formula list back to this database:
- Strip manufacturer parentheticals first (by allowlist, not every bracket). Worth 11.5 points
- Remove whitespace and hyphens, unify
cis/(Z)andalpha/a. Worth 0.8 points - Strip
N% in solventtails. Worth 0.1 points - Handle the rest by hand, starting with abbreviations and C-numbers
Step 1 alone is 92% of the total gain. Do that first and take the others as they come.
What this doesn't establish
- I did not verify that all 2,003 new matches are correct. I checked the six highest-frequency ones and they are right. The rest rest on the allowlist rule, unchecked row by row.
- The allowlist is twelve manufacturers I typed out. Any I missed makes the number too low.
- 72.81% is a figure for these 954 formulas and would differ on another set.
- I did no real fuzzy matching, such as edit distance. Everything here normalises first and then matches exactly. How much genuine fuzzy matching would add is still untried, and it brings false positives, so the verification method has to be settled first.
- I did not build the C-number lookup table. I only confirmed it is a problem
(
aldehyde c-12is shared by two different materials) without solving it. - Chemical name matching is a problem with its own literature. Krallinger and colleagues published the CHEMDNER corpus and its annotation principles in J Cheminform in 2015 (PMID 25810773), and Akhondi and colleagues compared identifier consistency across databases in 2012 (PMID 23237381). What I ran here is four rules, not work at that level.