Suppose I have iris data In the Dataset Format.
How to split the iris data Into training and testing for Machine learning?
For example,Transform the data for Classify.
Let's use the Titanic dataset
tit = ExampleData[{"Dataset", "Titanic"}];
Let's see it's columns
tit[Union, Keys]
Let's choose an objective
obj = "survived";
Let's add an id to each row
tit = tit[AssociationThread[Range@Length@#, #] &];
Let's create a database that splits the features and objective, to make this general.
titSplit =
tit[All, <|"Features" -> Values@*KeyDrop[obj],
"Objective" -> Key[obj]|>];
Let's split the rows arbitrarily to have a test and train set.
numTraining = 200;
ids = Range@tit[Length];
testIds = ids~RandomSample~numTraining;
trainIds = ids~Complement~testIds;
titUnclass = titSplit[<|"Test" -> testIds, "Train" -> trainIds|>];
Let's train the classifier
cfun = titUnclass["Train", Classify@*Values, #Features -> #Objective &];
Let's create a new dataset appending the classifications as a column in the Test dataset.
titClass =
titUnclass[{"Test" ->
Query[All, Append[#, <|"Classified as" -> cfun@#Features|>] &]}];
Or perhaps just have the results in a separate database results = titUnclass["Test", All, cfun@#Features &];
Let's ask for performance measures
cfm = titUnclass["Test",
ClassifierMeasurements[cfun, #] & @* Values,
#Features -> #Objective &];
cfm["Accuracy"]
(* 0.75 *)
Edit
This is based on the OP @PhilChang nice suggestion in the comments
RandomSample
works on Dataset
s
rtit = RandomSample@ExampleData[{"Dataset", "Titanic"}];
Split
obj = "survived"; numTrain = 200;
ctit = rtit[<|"Train" -> (;; numTrain), "Test" -> (numTrain + 1 ;;)|>];
Train
cfun = ctit["Train", GroupBy[Key[obj] -> KeyDrop[obj]], Values][
Classify];
Measure
cfm = ctit["Test", GroupBy[Key[obj] -> KeyDrop[obj]], Values][
ClassifierMeasurements[cfun, #] &];
cfm["Accuracy"]
Accuracy
= 0.63. Naive splitting like this is often biased by the dataset layout, eg, look at the distribution of "class": trainTit[Map[First] /* Counts, "Features"]
--> "1st" -> 200
versus testTit[Map[First]...]
--> "1st" -> 123, "2nd" -> 277, "3rd" -> 709
. Typically, bootstrap or other resampling methods are used to minimize the effects of clustering. Certainly you'd want to randomize the partition.
$\endgroup$
Commented
Aug 12, 2014 at 19:49
ValidationSet
option to Classify
and Predict
to override our internal cross-validation if you have your own test set. Also, @Rojo, note that in 10.0.2 you can use the Classify[data -> out]
shorthand to indicate that the column name or number is the one being predicted, so you don't have to split off the features from the output yourself.
$\endgroup$
Commented
Feb 9, 2015 at 18:50
I think there is a resource function now...
https://resources.wolframcloud.com/FunctionRepository/resources/TrainTestSplit/