Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: How to split a data frame into training, validation, and test sets?

Tags:

I'm using R to do machine learning. Following standard machine learning methodology, I would like to randomly split my data into training, validation, and test data sets. How do I do that in R?

I know there are some related questions on how to split into 2 data sets (e.g. this post), but it is not obvious how to do it for 3 split data sets. By the way, the correct approach is to use 3 data sets (including a validation set to tune your hyperparameters).

like image 886
stackoverflowuser2010 Avatar asked Mar 17 '16 18:03

stackoverflowuser2010


People also ask

How do you split dataset into training validation and testing?

Split the dataset We can use the train_test_split to first make the split on the original dataset. Then, to get the validation set, we can apply the same function to the train set to get the validation set. In the function below, the test set size is the ratio of the original data we want to use as the test set.

How do you split a Dataframe in R?

Use the split() function in R to split a vector or data frame. Use the unsplit() method to retrieve the split vector or data frame.


2 Answers

This linked approach for two groups (using floor) doesn't extend naturally to three. I'd do

spec = c(train = .6, test = .2, validate = .2)  g = sample(cut(   seq(nrow(df)),    nrow(df)*cumsum(c(0,spec)),   labels = names(spec) ))  res = split(df, g) 

To check the results:

sapply(res, nrow)/nrow(df) #    train     test validate  #  0.59375  0.18750  0.21875  # or... addmargins(prop.table(table(g))) #    train     test validate      Sum  #  0.59375  0.18750  0.21875  1.00000  

With set.seed(1) run just before, the result looks like

$train                    mpg cyl  disp  hp drat    wt  qsec vs am gear carb Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 Merc 280C         17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4 Merc 450SE        16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3 Merc 450SL        17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 Merc 450SLC       15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3 Fiat 128          32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1 Toyota Corolla    33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1 Dodge Challenger  15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2 AMC Javelin       15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2 Pontiac Firebird  19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2 Fiat X1-9         27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1 Porsche 914-2     26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2 Volvo 142E        21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2  $test                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb Valiant            18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 Cadillac Fleetwood 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4 Toyota Corona      21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 Camaro Z28         13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4 Ford Pantera L     15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4 Ferrari Dino       19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6  $validate                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4 Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4 Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2 Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2 Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8 

Data.frames can be accessed like res$test or res[["test"]].

cut is the standard tool for partitioning based on shares.

like image 65
Frank Avatar answered Oct 19 '22 23:10

Frank


Following the approach shown in this post, here is working R code to divide a dataframe into three new dataframes for testing, validation, and test. The three subsets are non-overlapping.

# Create random training, validation, and test sets  # Set some input variables to define the splitting. # Input 1. The data frame that you want to split into training, validation, and test. df <- mtcars  # Input 2. Set the fractions of the dataframe you want to split into training,  # validation, and test. fractionTraining   <- 0.60 fractionValidation <- 0.20 fractionTest       <- 0.20  # Compute sample sizes. sampleSizeTraining   <- floor(fractionTraining   * nrow(df)) sampleSizeValidation <- floor(fractionValidation * nrow(df)) sampleSizeTest       <- floor(fractionTest       * nrow(df))  # Create the randomly-sampled indices for the dataframe. Use setdiff() to # avoid overlapping subsets of indices. indicesTraining    <- sort(sample(seq_len(nrow(df)), size=sampleSizeTraining)) indicesNotTraining <- setdiff(seq_len(nrow(df)), indicesTraining) indicesValidation  <- sort(sample(indicesNotTraining, size=sampleSizeValidation)) indicesTest        <- setdiff(indicesNotTraining, indicesValidation)  # Finally, output the three dataframes for training, validation and test. dfTraining   <- df[indicesTraining, ] dfValidation <- df[indicesValidation, ] dfTest       <- df[indicesTest, ] 
like image 41
stackoverflowuser2010 Avatar answered Oct 19 '22 23:10

stackoverflowuser2010