5
$\begingroup$

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:

enter image description here

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}]|>]

enter image description here

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

enter image description here

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...

$\endgroup$

1 Answer 1

7
+50
$\begingroup$

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.

UPDATED ANSWER:

Datasets should not have labeled rows if you want to use them in Classify or Predict (what meaning do they labels have?). Use Values[ds] to drop the labels before calling Predict.

$\endgroup$
7
  • $\begingroup$ that does clarify my quesiton thank you. I guess this comes back to part two as to why Predict would not work with the Input -> #, Output -> # format if the classes were encoded as numbers. $\endgroup$
    – SumNeuron
    Commented Sep 2, 2016 at 4:04
  • $\begingroup$ @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", ...]. $\endgroup$ Commented Sep 2, 2016 at 10:59
  • $\begingroup$ here is a follow-up edit to further my question $\endgroup$
    – SumNeuron
    Commented Sep 23, 2016 at 10:45
  • $\begingroup$ @SumNeuron I have updated the answer. $\endgroup$ Commented Sep 26, 2016 at 21:14
  • $\begingroup$ I have noticed that and hence have tired using ds[Values] (which is equivalent to Values[ds]?), which yielded similar errors. As to why one may wish to have labeled rows: depending on what the data is, each record may be of importance to identify later. $\endgroup$
    – SumNeuron
    Commented Sep 27, 2016 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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