docs: def run(self, training_set, trainer, filename = "bootstrapped_model.hdf5", force = False):
      """run(training_set, trainer, [filename], [force]) -> model
  
      Runs the bootstrapped training of a strong classifier using the given training data and a strong classifier trainer.
      The training set need to contain extracted features already, as this function will need the features several times.
  
      **Parameters:**
  
      ``training_set`` : :py:class:`TrainingSet`
        The training set containing pre-extracted feature files
  
      ``trainer`` : :py:class:`bob.learn.boosting.Boosting`
        A strong boosting trainer to use for selecting the weak classifiers and their weights for each round.
  
      ``filename`` : str
        A filename, where to write the resulting strong classifier to.
        This filename is also used as a base to compute filenames of intermediate files, which store results of each of the bootstrapping steps.
  
      ``force`` : bool
        If set to ``False`` (the default), the bootstrapping will continue the round, where it has been stopped during the last run (reading the current stage from respective files).
        If set to ``True``, the training will start from the beginning.
  
      **Returns:**
  
      ``model`` : :py:class:`bob.learn.boosting.BoostedMachine`
        The resulting strong classifier, a weighted combination of weak classifiers.
      """
  
      feature_extractor = training_set.feature_extractor()
  
      training_data = None
      training_labels = None
      model = None
  
      positive_indices, negative_indices = set(), set()
  
      for b in range(self.m_number_of_rounds):
        # check if old results are present
        temp_file = "%s_round_%d.hdf5" % (os.path.splitext(filename)[0], b+1)
        if os.path.exists(temp_file) and not force:
          logger.info("Loading already computed stage %d from %s.", b+1, temp_file)
          model, positives, negatives = self._load(bob.io.base.HDF5File(temp_file))
          positive_indices |= positives
          negative_indices |= negatives
  
        else:
          if positive_indices or negative_indices:
            # load data from previous rounds
            logger.info("Getting training data of previous rounds")
            training_data, training_labels = training_set.sample(positive_indices = positive_indices, negative_indices = negative_indices)
            positive_indices, negative_indices = set(), set()
  
          # get data for current round
          logger.info("Getting new data for bootstrapping round %d", b+1)
          new_data, new_labels = training_set.sample(model, self.m_number_of_positive_examples_per_round, self.m_number_of_negative_examples_per_round)
          if training_data is None:
            training_data = new_data
          else:
            training_data = numpy.append(training_data, new_data, axis=0)
          if training_labels is None:
            training_labels = new_labels
          else:
            training_labels = numpy.append(training_labels, new_labels, axis=0)
  
          logger.info("Starting training with %d examples", training_data.shape[0])
          model = trainer.train(training_data, training_labels, self.m_number_of_weak_learners_per_round[b], model)
  
          # write model and extractor to temporary file to be able to catch up later
          logger.info("Saving results for stage %d to file %s", b+1, temp_file)
          self._save(bob.io.base.HDF5File(temp_file, 'w'), model, training_set.positive_indices, training_set.negative_indices)
  
        feature_extractor.model_indices = model.indices
  
      # finally, return the trained model
      return model