# How to generate a training set in an automatic way?

This question is related to [my previous item][1] where arithmetic with machine learning was considered. The results of the Predict command were not good because of a small size 19 of a training set

ClearAll["Global`*"];
trainingset = {"2+2" -> 4, "2+3*2" -> 8, "(12+7)*5" -> 95, "7*6" -> 42,
"7+22" -> 29, "4+5" -> 9, "4*1+5" -> 9, "17*3+4*5" -> 41, "7+9*2" -> 25, "11+3" -> 14,
"6+6" -> 12, "4*5+6" -> 26, "5*7" -> 35, "3*2" -> 6, "3+2" -> 5, "9*3" -> 27,
"3*9" -> 27, "6*3+8*2" -> 34, "5*4" -> 20};

My question is: how to generate such training set of size 200 with one or two additions and multiplications over integers from 0 to 100 in an automatic way? [1]: Why Method -> "NeuralNetwork" does not work for me?

PS. See the first example at https://reference.wolfram.com/language/tutorial/NeuralNetworksSequenceLearning.html#1013067167

• @Niki Estner: Can you kindly base your claim, giving us references? Does a chess program know what is "knight"? Jul 25, 2018 at 11:25
• @NikiEstner: See the first example at reference.wolfram.com/language/tutorial/… . Dec 30, 2020 at 9:21

This should work.

rn["num"] := RandomInteger[{0, 100}]
rn["op"] := RandomChoice[{"+", "*"}]

set = ToString @ Row[rn /@ Riffle[Table["num", {#}], "op"]] & /@
RandomInteger[{2, 4}, 200];

set = # -> ToExpression[#] & /@ set;

Output looks like

{"94+66+34*28" -> 1112, "37*40*57" -> 84360, "34*59+27+97" -> 2130, . . .}

In the code above the function rn (random) makes a random number or operator as needed. So for example rn /@ {"num", "op", "num"} might give me {1, "+", 2}. From there I can merge those into a single string. So the matter is then just creating a series of "num"/"op" lists of the right form. As an example:

Riffle[Table["num", {4}], "op"]
{"num", "op", "num", "op", "num", "op", "num"}

So this Riffle/Table expression forms the heart of a Function that I map over a list of (pseudo)random integers of the right specification.

The final step is to take our complete strings and evaluate them as input, and this is performed by ToExpression. # -> ToExpression[#] & is another Function that gives input mapped to output as a series of Rules.

The same operations written in a step by step way:

rn["num"] := RandomInteger[{0, 100}]
rn["op"] := RandomChoice[{"+", "*"}]

RandomInteger[{2, 4}, 10];

Table["num", {#}] & /@ %

Riffle[#, "op"] & /@ %

Map[rn, %, {2}]

ToString /@ Row /@ %

Thread[% -> ToExpression /@ %]

There are certainly other ways to approach this problem; this is merely what came to mind first as an expedient solution.

• Many thanks from me to you for your work. Can you kindly comment your code (In order to use it in teaching the code should be understandable to students.)? Jul 25, 2018 at 11:12
• Also the code p = Predict[set, Method -> "RandomForest"]; p["4+6"] results 600785. Jul 25, 2018 at 11:18
• Changing the parameters 100->20, {2,4}->{1,3}, 200->10000, I obtain 22.5 for t["4+6*3"]. Jul 25, 2018 at 12:19
• @user64494 Tomorrow I'll add comments or otherwise make the code more transparent. Jul 25, 2018 at 13:17
• @user64494 Sorry, I forgot to return to this. Hopefully tomorrow I will remember. <:-0 Jul 26, 2018 at 16:32