# Problem

I can not seem to figure out the correct way of formatting Dataset to be used with predict. I am providing Mathematica's example, which works fine. I also am including an abitrary "dataset" which is what one might expect from a csv.

## Mathematica's Example

d = Dataset[{<|"age" -> 32, "height" -> 160, "gender" -> "female"|>,
<|"height" -> 183, "age" -> 41, "gender" -> "female"|>,
<|"height" -> 123, "age" -> 30, "gender" -> "female"|>,
<|"height" -> 175, "age" -> 21, "gender" -> "male"|>,
<|"height" -> 150, "age" -> 11, "gender" -> "male"|>,
<|"age" -> 52, "height" -> 164, "gender" -> "female"|>}]

p = Predict[d -> "age"]


## Arbitrary Example

list = {{"feature1", "feature2", "feature3", "class"},
{1, 2, 3, "one"},
{4, 5, 6, "two"},
{1, 2, 3, "three"},
{4, 5, 6, "one"},
{1, 2, 3, "one"},
{1, 2, 3, "three"},
{4, 5, 6, "two"},
{1, 2, 3, "one"}};

data = Dataset[
Table[<|Table[
list[[1]][[i]] -> list[[j]][[i]], {i, 1,
Length[list[[j]]]}]|>, {j, 2, Length[list]}]];

(*i.e. data = Dataset[{
<|"feature1" -> 1, "feature2" -> 2, "feature3" -> 3, "class" -> "one"|>,
<|"feature1" -> 4, "feature2" -> 5, "feature3" -> 6, "class" -> "two"|>,
<|"feature1" -> 1, "feature2" -> 2, "feature3" -> 3, "class" -> "three"|>,
<|"feature1" -> 4, "feature2" -> 5, "feature3" -> 6, "class" -> "one"|>,
<|"feature1" -> 1, "feature2" -> 2, "feature3" -> 3, "class" -> "one"|>,
<|"feature1" -> 1, "feature2" -> 2, "feature3" -> 3, "class" -> "three"|>,
<|"feature1" -> 4, "feature2" -> 5, "feature3" -> 6, "class" -> "two"|>,
<|"feature1" -> 1, "feature2" -> 2, "feature3" -> 3, "class" -> "one"|>}*)

Predict[data->"class"]


## Question 1

So this causes an error, and my question is why? The structure is essentially the same as the one provided in their example.

### Note

Interestingly NetTrain takes a different approach for using Dataset

newInput = {<|"Input" -> {1, 2, 3}, "Output" ->  "one"|>,
<|"Input" -> {4, 5, 6}, "Output" ->  "two"|>,
<|"Input" -> {1, 2, 3}, "Output" ->  "three"|>,
<|"Input" -> {4, 5, 6}, "Output" ->  "one"|>,
<|"Input" -> {1, 2, 3}, "Output" ->  "one"|>,
<|"Input" -> {1, 2, 3}, "Output" ->  "three"|>,
<|"Input" -> {4, 5, 6}, "Output" ->  "two"|>,
<|"Input" -> {1, 2, 3}, "Output" ->  "one"|>};

newInput[[;; , 2]] = NetEncoder[{"Class", {"one", "two", "three"}, "UnitVector"}][newInput[[;; , 2]]]

net = NetInitialize[NetGraph[{Tanh, DotPlusLayer[3]}, {1 -> 2}, "Input" -> 3]]

NetTrain[net, newInput];


## Question 2

How come this (net) Dataset input structure (e.g. {<|"Input"-> x, "Output"->y|>,...}) works for NetTrain, but not for Predict, when Predict has an option for "NeuralNetwork"? Likewise, how come NetTrain doesn't have the same input arugments as Predict, e.g. why can I not pass in the varible data -> "Class" to NetTrain.

I am just curious as to why there can't be some uniformity for input... or if there is and I just do not understand it, for it to be expounded to me.

## UPDATE

So in the Predict Documentation it has the following statement:

Thus given the previous issues I have had with this I tried it on a new plain example:

rows = {"1", "2", "3", "4", "5"};
cols = {"a", "b", "c", "d", "e"};
data = RandomInteger[10, {10, 5}];
ds = Dataset[<|
Table[rows[[r]] -> <|
Table[cols[[c]] -> data[[r]][[c]], {c, Length@cols}]|>, {r,
Length@rows}]|>]


Then I try my hand at predict:

rf = Predict[ds -> "e", Method -> "RandomForest"];
rf = Predict[ds -> ds["e"], Method -> "RandomForest"];
rf = Predict[ds -> "5", Method -> "RandomForest"];
rf = Predict[ds -> ds["5"], Method -> "RandomForest"];


and I get the following errors

Can someone please explain what is going on? The delay in this comes from me having previous success using Predict after this post using syntax along the lines of

rf = Predict[ds -> "e", Method -> "RandomForest"];

but now that is no longer working...

Question 1

So this causes an error, and my question is why? The structure is essentially the same as the one provided in their example.

Because this is classification, not prediction. Look at the target column. Are they numbers? That is prediction. Are they classes? That is classification. Hence use Classify.

Question 2

How come this (net) Dataset input structure (e.g. {<|"Input"-> x, "Output"->y|>,...}) works for NetTrain, but not for Predict, when Predict has an option for "NeuralNetwork"? Likewise, how come NetTrain doesn't have the same input arugments as Predict, e.g. why can I not pass in the varible data -> "Class" to NetTrain.

Because the training data for nets has to cover more cases than the input data expected by Classify and Predict. For one thing, NetTrain can be used to do train both regressors and classifiers. And with suitable modifications it can cover things like multi-task and unsupervised learning. That makes it somewhat more verbose to specify the training data, and to answer your originally question, unavoidably different in what it expects.

• @SumNeuron because Predict doesn't know which column is the output, whereas with networks there are named ports, and "Output" is the default name for a single layer or NetChain's output port, so that's why NetTrain knows that "Output" is the output (but there could be others depending on the network). It's trivial to make Predict use "Output" as the output by just writing Predict[dataset -> "Output", ...]. – Taliesin Beynon Sep 2 '16 at 10:59