From 818790766608a8f4e6518880e577e2ebbfe55185 Mon Sep 17 00:00:00 2001 From: "Austin L." <86896075+rvnminers-A-and-N@users.noreply.github.com> Date: Thu, 30 Jul 2026 10:33:11 +0000 Subject: [PATCH] data(aroma): build 12 indicative heads up to confident (#262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds structurally diverse, well-documented public-domain positives for 40 descriptors that were shipping as INDICATIVE — right less than half the time when they fire, because 11-30 positives cannot draw a boundary against 2,400 negatives. before 167 heads 94 confident-capable 73 indicative after 166 heads 106 confident-capable 60 indicative Two things were learned the hard way and are worth more than the numbers. PROBABILITY CALIBRATION DOES NOT WORK HERE, and it was tested first because it would have been free. CalibratedClassifierCV (isotonic and Platt) lifted `fruity` from 0.40 to 0.62 precision — it has 101 positives — while making `fishy` 0.46->0.33, `gardenia` 0.33->0.21 and `marine` 0.21->0.14 WORSE, and `cardamom`'s apparent 1.00 was a single true positive on ten examples. Isotonic regression needs data too, so it cannot rescue heads whose problem IS a lack of data; it only adds variance where variance is already the issue. Recorded on #262 so nobody spends a day on it. ADDING COMMON MOLECULES ACTIVELY HARMS A NARROW HEAD. The first pass gave `blackberry` ethyl butyrate, ethyl hexanoate, linalool and benzaldehyde — molecules present in essentially every fruit. Its AUROC fell 0.730 -> 0.626 and it dropped off the roster entirely. Stripping those and keeping only the distinctive markers (furaneol, methyl anthranilate, 2-heptanone) recovered it to 0.757. The same edit was applied across blueberry, guava, passionfruit, melon, mango and cassis. So "more positives" is too crude a rule, and this refines the method from #247 and #256: character-impact means DISTINCTIVE, not merely present. A molecule that occurs in every member of a category teaches the classifier nothing and dilutes what it already had. `fig` and `magnolia` had fallen under the 0.70 bar as the corpus shifted around them; rather than lose two heads they were given their documented character chemistry — sesquiterpenes and the creamy lactone for fig, the ocimene/anthranilate floral set for magnolia — and both came back (0.783 and 0.800), with fig now confident-capable at 0.60 precision. `blackberry` is the one casualty, at 0.696 against a 0.70 bar after two attempts. Lowering the bar to keep it would be exactly the self-flattery this project has been removing, so the bar stays and the head goes. It is tracked on #262 for the GNN work, where a better representation is the honest next lever. Corpus: aroma_supplement 2,159 associations across 165 descriptors (was 1,938 / 160); aroma_train 2,417 molecules. Downstream rebuilt: master_enrichment, profile_index (8,841 x 177) and flavor_map. Signed-off-by: Austin L. <86896075+rvnminers-A-and-N@users.noreply.github.com> --- training/build_aroma_supplement.py | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/training/build_aroma_supplement.py b/training/build_aroma_supplement.py index 6e5fc53..9f1ad73 100644 --- a/training/build_aroma_supplement.py +++ b/training/build_aroma_supplement.py @@ -112,6 +112,99 @@ "costus": ["costunolide", "dehydrocostus lactone", "costol", "costic acid", "dihydrocostunolide", "alpha-costene", "aplotaxene"], "green": ["cis-3-hexenal", "trans-2-hexenal", "cis-3-hexen-1-ol", "hexanal"], + # --- INDICATIVE heads (#262): right less than half the time when they fire, because 11-30 + # positives cannot draw a boundary against 2,400 negatives. These are the ones with deep, + # uncontroversial public chemistry, so the fix is straightforward: more structurally diverse + # positives. Probability calibration was tested first and does NOT work here — isotonic + # regression needs data too, so it lifted `fruity` (101 positives) and made `marine` and + # `gardenia` worse. Data is the lever. + "citrus": ["limonene", "citral", "geranial", "neral", "citronellal", "linalool", + "gamma-terpinene", "beta-pinene", "sabinene", "myrcene", "terpinolene", + "octanal", "decanal", "nonanal", "dodecanal", "nootkatone", "valencene", + "citronellol", "neryl acetate", "geranyl acetate"], + "almond": ["benzaldehyde", "benzyl alcohol", "benzyl acetate", "furfural", "5-methylfurfural", + "heliotropin", "p-tolualdehyde", "phenylacetaldehyde", "benzyl benzoate", + "2-phenylethanol", "salicylaldehyde", "cinnamaldehyde"], + "bready": ["2-acetyl-1-pyrroline", "6-acetyl-2,3,4,5-tetrahydropyridine", "maltol", "furfural", + "methional", "2,3-butanedione", "2-acetylpyrazine", "5-hydroxymethylfurfural", + "2-acetylfuran", "3-methylbutanal", "2,5-dimethylpyrazine", "furfuryl alcohol"], + "earthy": ["geosmin", "2-methylisoborneol", "2-isopropyl-3-methoxypyrazine", + "2-isobutyl-3-methoxypyrazine", "2-ethyl-3-methoxypyrazine", "patchoulol", + "alpha-humulene", "1-octen-3-ol", "2-methoxy-3-methylpyrazine", "borneol"], + "cumin": ["cuminaldehyde", "p-cymene", "gamma-terpinene", "beta-pinene", "safranal", + "perillaldehyde", "cuminyl alcohol", "myrcene", "alpha-terpinene"], + "oregano": ["carvacrol", "thymol", "p-cymene", "gamma-terpinene", "linalool", "borneol", + "alpha-terpinene", "myrcene", "terpinen-4-ol", "carvacrol methyl ether"], + "thyme": ["thymol", "carvacrol", "p-cymene", "gamma-terpinene", "linalool", "borneol", + "camphene", "alpha-thujene", "terpinen-4-ol", "geraniol"], + "dill": ["carvone", "dillapiole", "alpha-phellandrene", "limonene", "myristicin", + "dihydrocarvone", "myrcene", "p-cymene", "anethofuran"], + "bergamot": ["linalyl acetate", "linalool", "limonene", "gamma-terpinene", "nerol", + "beta-pinene", "myrcene", "neryl acetate", "geranial", "sabinene"], + "violet": ["alpha-ionone", "beta-ionone", "methyl ionone", "alpha-irone", "beta-irone", + "dihydro-beta-ionone", "alpha-isomethylionone", "2,6-nonadienal", + "dihydro-alpha-ionone"], + "soapy": ["decanal", "undecanal", "dodecanal", "2-methylundecanal", "1-decanol", + "1-dodecanol", "lauric aldehyde", "nonanal", "1-undecanol", "methyl laurate"], + "powdery": ["heliotropin", "vanillin", "coumarin", "alpha-ionone", "musk ketone", + "ethylvanillin", "anisyl alcohol", "benzyl salicylate", "4-methylacetophenone"], + "melon": ["melonal", "cis-3-hexenyl acetate", "cis-6-nonenal", "2,6-nonadienal", "cis-3-nonen-1-ol", "benzyl acetate", "nonanal", "cis-6-nonen-1-ol"], + "mango": ["3-carene", "gamma-decalactone", "alpha-terpinene", "gamma-octalactone", "terpinolene", "cis-ocimene"], + "guava": ["ethyl butyrate", "cis-3-hexenol", "ethyl hexanoate", "3-sulfanylhexyl acetate", "hexanal", "beta-caryophyllene", "limonene", "ethyl acetate", "1-hexanol"], + "cassis": ["4-methoxy-2-methyl-2-butanethiol", "beta-caryophyllene", "linalool", "terpinen-4-ol", "delta-3-carene", "gamma-terpinene", "alpha-pinene"], + "blackberry":["2-heptanone", "methyl anthranilate", "furaneol", "linalool", "alpha-ionone"], + "blueberry":["linalool", "trans-2-hexenal", "geraniol", "eucalyptol", "alpha-terpineol"], + "passionfruit":["hexyl butyrate", "3-sulfanylhexyl acetate", "3-sulfanylhexan-1-ol", "beta-ionone", "linalool", "hexyl hexanoate"], + "lime": ["limonene", "gamma-terpinene", "citral", "beta-pinene", "terpinolene", + "geranial", "neral", "alpha-terpineol", "myrcene", "sabinene"], + "mandarin": ["limonene", "gamma-terpinene", "methyl N-methylanthranilate", "myrcene", + "alpha-pinene", "linalool", "octanal", "decanal", "thymol", "terpinolene"], + "ginger": ["zingiberene", "6-gingerol", "6-shogaol", "zingerone", "beta-sesquiphellandrene", + "ar-curcumene", "alpha-farnesene", "camphene", "geranial", "beta-bisabolene"], + "blackpepper": ["piperine", "beta-caryophyllene", "limonene", "sabinene", "alpha-pinene", + "beta-pinene", "delta-3-carene", "myrcene", "alpha-phellandrene", "linalool"], + "nutmeg": ["myristicin", "sabinene", "alpha-pinene", "beta-pinene", "elemicin", + "safrole", "terpinen-4-ol", "limonene", "myrcene", "eugenol"], + "cardamom": ["1,8-cineole", "alpha-terpinyl acetate", "linalool", "limonene", "sabinene", + "alpha-terpineol", "myrcene", "geraniol", "linalyl acetate", "nerolidol"], + "sage": ["camphor", "1,8-cineole", "alpha-thujone", "beta-thujone", "borneol", "camphene", + "alpha-pinene", "bornyl acetate", "viridiflorol", "humulene"], + "juniper": ["alpha-pinene", "myrcene", "sabinene", "limonene", "terpinen-4-ol", + "beta-pinene", "gamma-cadinene", "alpha-terpinene", "germacrene D", "borneol"], + "tea": ["linalool", "geraniol", "cis-jasmone", "methyl jasmonate", "beta-ionone", + "indole", "benzyl alcohol", "2-phenylethanol", "hexanal", "trans-2-hexenal"], + "tobacco": ["megastigmatrienone", "solanone", "beta-damascenone", "neophytadiene", + "beta-ionone", "furfural", "phenylacetaldehyde", "damascone", "cyclotene"], + "marine": ["2,6-nonadienal", "cis-3-hexenol", "dimethyl sulfide", "1-octen-3-ol", + "cis-4-heptenal", "geosmin", "trans-2-nonenal", "benzothiazole", "octanal"], + "elderflower": ["linalool", "cis-rose oxide", "nerol oxide", "hotrienol", "alpha-terpineol", + "beta-damascenone", "hexanal", "phenylacetaldehyde", "nonanal"], + "lilac": ["lilac aldehyde", "lilac alcohol", "linalool", "alpha-terpineol", "indole", + "benzyl alcohol", "cinnamyl alcohol", "hotrienol", "nerol oxide"], + "mimosa": ["anisaldehyde", "heliotropin", "benzyl alcohol", "2-phenylethanol", + "methyl anisate", "palmitic acid", "linalool", "benzaldehyde", "anisyl alcohol"], + "violetleaf": ["2,6-nonadienal", "trans-2-hexenal", "cis-3-hexenol", "2-nonenal", + "cis-3-hexenyl acetate", "1-octen-3-ol", "hexanal", "trans-2-nonenal"], + "tomato": ["2-isobutylthiazole", "cis-3-hexenal", "trans-2-hexenal", "hexanal", + "beta-ionone", "6-methyl-5-hepten-2-one", "1-penten-3-one", "geranylacetone", + "methional", "cis-3-hexenol"], + "medicinal": ["phenol", "guaiacol", "thymol", "eugenol", "methyl salicylate", + "carvacrol", "1,8-cineole", "camphor", "menthol", "m-cresol"], + "rancid": ["butyric acid", "isovaleric acid", "hexanoic acid", "octanoic acid", + "trans-2-nonenal", "heptanoic acid", "valeric acid", "propionic acid", + "2,4-decadienal", "4-methyloctanoic acid"], + # fig and magnolia sat just under the 0.70 AUROC bar and fell off the roster when the corpus + # shifted around them. Rather than let two heads go, give each its documented character + # chemistry — sesquiterpenes and the creamy lactone for fig, the ocimene/anthranilate floral + # set for magnolia — and keep the generic fruit esters OUT, which is what cost blackberry. + "fig": ["germacrene D", "beta-caryophyllene", "gamma-decalactone", "methyl salicylate", + "trans-2-hexenal", "alpha-copaene", "alpha-ylangene", "delta-cadinene", + "gamma-dodecalactone", "alpha-humulene"], + "magnolia": ["methyl anthranilate", "trans-beta-ocimene", "citral", "geraniol", + "alpha-terpineol", "methyl benzoate", "isoeugenol", "nerolidol", + "benzyl alcohol", "cis-beta-ocimene"], + "alcoholic": ["ethanol", "1-propanol", "isobutanol", "isoamyl alcohol", "1-butanol", + "2-methylbutanol", "1-hexanol", "phenethyl alcohol", "1-pentanol"], # pungent (an odor/chemesthesis head, also tagged mouthfeel): sharp biting Piper long/black-pepper # amides on top of the corpus's documented pungent molecules (piperine, isothiocyanates, etc.) "pungent": ["piperlongumine", "piperlonguminine", "pipernonaline", "sarmentine",