public List<FeatureSet> constructEnsembleFeatureSets(FeatureSet training_set) throws AuToBIException {
    List<FeatureSet> training_sets = new ArrayList<FeatureSet>();

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

    String majority_class = null;
    Double majority_size = 0.0;
    Double second_largest_size = 0.0;
    for (String s : class_distribution.keySet()) {
      if (class_distribution.get(s) > majority_size) {
        second_largest_size = majority_size;
        majority_size = class_distribution.get(s);
        majority_class = 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 / second_largest_size);
    List<Word> majority_class_points = PartitionUtils
        .getAttributeMatchingWords(training_set.getDataPoints(), training_set.getClassAttribute(), majority_class);
    PartitionUtils.assignFoldNum(majority_class_points, "ensemble_sampling_fold", num_folds);

    // 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);
    }
    return training_sets;
  }