9
$\begingroup$

I found this blog (which is highly entertaining). It has an interesting post where the author uses the GPT-2 neuro-network with candle scent training data to generate new candle scents. The AI comes up with some delightful names such as

  • Frozen Styrofoam
  • Asparagus & Pumpkin
  • Marshmallow Chutney
  • Friendly Wetsuit

along with much more "normal" candle scents such as

  • Mango Vanilla
  • Summer Sky
  • Christmas Almond
  • Wildflower Honey
  • Vanilla Pumpkin Cake

I was wondering if it would be possible to do something similar in Mathematica. There exists this example, but based in python.

I've scraped a few websites for a list of 1.5k candle names: https://pastebin.com/T9VW709E. I note that GPT-2 is accessible from Mathematica relatively easily. Can I get Mathematica to predict new candle scents from my (relatively limited) training data?

$\endgroup$
5
$\begingroup$

You might be wanting something more skilled using GTP-2 and etc. However I found with fairly little work I could get some fun results.

First I simply took your list and used the GPT-2 net to create the 768 vector values for each candle name...

candlenames = data from link
model = NetModel["GPT-2 Transformer Trained on WebText Data"]
coor = Table[model[candlenames[[i]]], {i, 1, Length[candlenames]}];

I then took the coor data and took the median of each vector value and gave each name a point value.

preditiondata = Table[candlenames[[i]] -> First[Mean[coor[[i]]]], {i, 1, Length[candlenames]}];
p = Predict[preditiondata, Method -> "NeuralNetwork"]

After this I naively generated a list of 50, 000 adjective and noun combinations

names = {RandomWord["Adjective", 50000] RandomWord["Noun", 50000]};

Which is hilarious enough as it is....

RandomChoice[list, 10]

$$\{\text{lush} \text{ tractor},\text{erasable} \text{ toiler},\text{ frosted} \text{haulage},\text{contraceptive} \text{ temporal},\text{dowse} \text{ sociable},\text{adjunct} \text{ largo},\text{garbed} \text{ investiture},\text{deprecating} \text{ info},\text{advance} \text{ overhang},\text{oration} \text{ undiscovered}\}$$

Lush Tractor and Contraceptive Temporal probably being my favourite candle scents....

Anyways, I then used the predictor to give what i hoped to be good names based off of high values from the list of candle names given...which depending on the person was a wild success or huge statistical failure.

results = Table[{list[[i]], p[ToString[list[[i]]]]}, {i, 1, Length[list]}];
names = Position[results, n_ /; n > 1.8]
Sort[Table[results[[First[names[[i]]]]], {i, 1, Length[names]}], #1[[2]] > #2[[2]] &] // MatrixForm

I picked as an arbitrary value above 2 as it seemed to give me results that seemed plausible.

$ \left( \begin{array}{cc} \text{breeze} \text{ exclamatory} & 2.9989 \\ \text{breeze} \text{ smoldering} & 2.9989 \\ \text{avenged} \text{ breeze} & 2.63791 \\ \text{avocado} \text{ weathered} & 2.3345 \\ \text{enchanted} \text{ oxbow} & 2.2121 \\ \text{enchanted} \text{ propagator} & 2.2121 \\ \text{enchanted} \text{ proceeds} & 2.2121 \\ \text{enchanted} \text{ endocrine} & 2.2121 \\ \text{enchanted} \text{ submergence} & 2.2121 \\ \text{enchanted} \text{ torturer} & 2.2121 \\ \text{harvest} \text{ inconsiderable} & 2.20732 \\ \text{harvest} \text{ simplified} & 2.20732 \\ \text{autumn} \text{ unparalleled} & 2.18493 \\ \text{fruit} \text{ venomous} & 2.15026 \\ \end{array} \right) $

In this random list it appears "autumn","enchanted" and "breeze" are popular candle scent titles...I expect because they show up often in the list. By using RandomWord[] more clever and using Predict in combination with the GPT-2 vector values, one could probably get a much better results...However names are quite subjective and I enjoyed the results I got. Maybe this will inspire someone more clever than I.

** Update **

To attempt to get some better names, took all the string names and split them into individual words gave them a weighting through word frequency and ran them through the predictor again with the full names

words = Table[StringSplit[candlenames[[i]]], {i, 1, Length[candlenames]}] // Flatten;

words

swords = DeleteDuplicates[words]; 
totalwords = StringJoin[Riffle[words, " "]];
weightedvalues = Table[swords[[i]] -> 1000 WordFrequency[totalwords, ToString[swords[[i]]]], {i, 1, Length[swords]}]

data = Join[Table[weightedvalues[[i]], {i, 1, Length[weightedvalues]}], Table[candlenames[[i]] -> First[Mean[coor[[i]]]], {i, 1, Length[candlenames]}]];


p = Predict[data, Method -> "NeuralNetwork"]

Now generate the words:

SeedRandom[113]
list = RandomWord["Adjective", limit] RandomWord["Noun", limit];
listnn = RandomWord["Noun", limit, IncludeInflections -> True] RandomWord[limit, IncludeInflections -> True];
l1 = RandomWord["Noun", limit];
l2 = RandomChoice[{2, 0.01} -> {" ", " & "}, limit];
l3 = RandomWord["Noun", limit];

stringlist1 = Table[ToString[list[[i]]], {i, 1, Length[list]}];
stringlist2 = Table[ToString[listnn[[i]]], {i, 1, Length[listnn]}];
namelist = Join[Table[StringJoin[l1[[i]], l2[[i]], l3[[i]]], {i, 1, Length[l1]}], stringlist1, stringlist2];

Pass the data through the predictor,

results = Table[{namelist[[i]], p[namelist[[i]]]}, {i, 1, Length[namelist]}];

names = Position[results, n_ /; n > 0.757];
Sort[Table[results[[First[names[[i]]]]], {i, 1, Length[names]}], #1[[2]] > #2[[2]] &] // MatrixForm

This has given me many different results, but the new weighting makes a heavy difference it seems. I have gotten some interesting results. The weighting would have to be adjusted some more

Some of my favourites:

Niobium spice, Absurd Grapefruit, Fruit Obtrusive, Telemarketing Lumberjack, Fated Mango, Valley & Rhapsody, Claptrap Brew

However, it's taken 60, 000 random generated results to get these and most seem to be better for IPA beers.

Regardless a bit of fun.

| improve this answer | |
$\endgroup$
  • $\begingroup$ coor = Table[model[candlenames[[i]]], {i, 1, Length[candlenames]}]; -- How about using Map? $\endgroup$ – Anton Antonov Mar 2 at 15:43
  • $\begingroup$ @AntonAntonov oh yeah, map is a good function i never use for some reason...i’m sure my code is mostly poorly written :) $\endgroup$ – morbo Mar 2 at 15:46
  • $\begingroup$ @morbo, I was wondering if you could post what 'model[]' is, you use it in coor - but don't post it. :) $\endgroup$ – Tomi Mar 2 at 17:42
  • $\begingroup$ @Tomi whoops! Good eye, :) forgot to copy, it was just the GPT-2 NetModel $\endgroup$ – morbo Mar 2 at 20:45
6
$\begingroup$

Here is a poor mans version with no ML.

words = candlenames // Map[StringSplit /* TextWords] // Flatten // DeleteStopwords;

SeedRandom[111];
Table[RandomSample[words, 2], 10] // Map[StringRiffle[#, " "] &]

(*
{"Cinnamon Caramel", "Boston Cherry", "Oatmeal Cupcake", "Citrus Hot", "Black Vanilla",
 "Honeysuckle Ocean", "Country Musk", "Cupcake Brown", "Sleep Rain", "Cherries Musk"}
*)
| improve this answer | |
$\endgroup$
  • $\begingroup$ If you downvote, please comment on why. Thanks. $\endgroup$ – Rohit Namjoshi Mar 3 at 2:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.