Splits the dataset randomly into proportionally sized partitions. @param rand the source of randomness for moving data around @param splits any array, where the length is the number of datasets to create and the value of in each index is the fraction of samples that should be placed into that datas
(Random rand, double... splits)
| 463 | * @return a list of new datasets |
| 464 | */ |
| 465 | public List<Type> randomSplit(Random rand, double... splits) |
| 466 | { |
| 467 | if(splits.length < 1) |
| 468 | throw new IllegalArgumentException("Input array of split fractions must be non-empty"); |
| 469 | IntList randOrder = new IntList(getSampleSize()); |
| 470 | ListUtils.addRange(randOrder, 0, getSampleSize(), 1); |
| 471 | Collections.shuffle(randOrder, rand); |
| 472 | |
| 473 | |
| 474 | int[] stops = new int[splits.length]; |
| 475 | double sum = 0; |
| 476 | for(int i = 0; i < splits.length; i++) |
| 477 | { |
| 478 | sum += splits[i]; |
| 479 | if(sum >= 1.001/*some flex room for numeric issues*/) |
| 480 | throw new IllegalArgumentException("Input splits sum is greater than 1 by index " + i + " reaching a sum of " + sum); |
| 481 | stops[i] = (int) Math.round(sum*randOrder.size()); |
| 482 | } |
| 483 | |
| 484 | List<Type> datasets = new ArrayList<Type>(splits.length); |
| 485 | |
| 486 | int prev = 0; |
| 487 | for(int i = 0; i < stops.length; i++) |
| 488 | { |
| 489 | datasets.add(getSubset(randOrder.subList(prev, stops[i]))); |
| 490 | prev = stops[i]; |
| 491 | } |
| 492 | |
| 493 | return datasets; |
| 494 | } |
| 495 | |
| 496 | /** |
| 497 | * Splits the dataset randomly into proportionally sized partitions. |