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

This question is related to my previous item 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?

• If you show an average 5-year old these samples, without explaining what the numbers and symbols mean, do you think he could learn arithmetic this way? If the average human can't do that, what makes you think a machine learning algorithm can? – Niki Estner Jul 25 '18 at 9:19
• @Niki Estner: Can you kindly base your claim, giving us references? Does a chess program know what is "knight"? – user64494 Jul 25 '18 at 11:25
• It's hard to give references that something doesn't work... To parse arithmetic, you need stack data structures, I don't see how an "off-the-shelf" network can represent this, and I can't imagine how it would get there using simple gradient descent. I might be wrong, but your questions sound like you're just starting with ML - so you might want to start with something where you know it can be done. – Niki Estner Jul 26 '18 at 10:39

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 /@ %

`