@Override
  public List<FeatureSet> constructEnsembleFeatureSets(FeatureSet training_set) {
    List<FeatureSet> training_sets = new ArrayList<FeatureSet>();

    // Identify the majority class.
    Distribution class_distribution =
        PartitionUtils.generateAttributeDistribution(training_set.getDataPoints(), training_set.getClassAttribute());


    Double majority_size = 0.0;
    Double smallest_size = Double.MAX_VALUE;
    for (String s : class_distribution.keySet()) {
      if (class_distribution.get(s) > majority_size) {

        majority_size = class_distribution.get(s);
      }
      if (class_distribution.get(s) < smallest_size) {
        smallest_size = class_distribution.get(s);
      }
    }

    // Assign folds to majority class data points -- each majority class data point exists in a single training set,
    // each other point exists in all of them.
    int num_folds = (int) Math.floor(majority_size / smallest_size);

    try {
      PartitionUtils.assignStratifiedFoldNum(training_set.getDataPoints(), "ensemble_sampling_fold", num_folds,
          training_set.getClassAttribute());

      // Generate training sets.
      for (int i = 0; i < num_folds; ++i) {
        FeatureSet sampled_training_set = training_set.newInstance();
        for (Word w : training_set.getDataPoints()) {
          if (!w.hasAttribute("ensemble_sampling_fold") || w.getAttribute("ensemble_sampling_fold").equals(i)) {
            sampled_training_set.getDataPoints().add(w);
          }
        }

        training_sets.add(sampled_training_set);
      }
    } catch (AuToBIException e) {
      e.printStackTrace();
    }

    return training_sets;
  }