@SuppressWarnings("unchecked")
  public double crossValidationError(int n, Approach approach) throws IOException {
    List<String> queries = QueryLoader.loadQueries(queryFile);
    int partSize = queries.size() / n;
    List<List<String>> partitions = new ArrayList<>(n);
    for (int i = 0; i < (n - 1); i++) {
      partitions.add(queries.subList(i * partSize, (i + 1) * partSize));
    }
    partitions.add(queries.subList((n - 1) * partSize, queries.size()));

    Model model = readModel(MODEL_FILE);
    LOGGER.info("Generating expected counts...");
    ObjectIntOpenHashMap<String> gsResults[] = countResources(partitions, model);

    double rootMeanSquareSum = 0;
    double foldErrors[] = new double[n];
    List<String> training, predicted;
    for (int i = 0; i < n; i++) {
      LOGGER.info("Starting fold " + i + "...");
      training = generateTrainingSet(i, partitions);
      predicted = approach.generateResourceRanking(training, model);
      foldErrors[i] = RMSD.getRMSD(predicted, generateExpectedResult(i, gsResults));
      LOGGER.info("Error of fold " + i + " = " + foldErrors[i]);
      rootMeanSquareSum += foldErrors[i];
    }
    LOGGER.info("Error of folds " + Arrays.toString(foldErrors));
    return rootMeanSquareSum / n;
  }
 public double validate(Approach approach, Model model, QueryExecutor executor)
     throws IOException {
   List<String> queries = QueryLoader.loadQueries(queryFile);
   Baseline baseline = new Baseline(executor);
   return RMSD.getRMSD(
       approach.generateResourceRanking(queries, model),
       generateUriRankRangeMapping(baseline.sumUpResults(model, queries)));
 }