code: protected List<List<String>> prepareToStringProbabilistic()
      {
          // adding zeros
          for (String row : allGoldLabels) {
              if (!map.containsKey(row)) {
                  map.put(row, new TreeMap<String, Integer>());
              }
  
              for (String col : allPredictedLabels) {
                  if (!map.get(row).containsKey(col)) {
                      map.get(row).put(col, 0);
                  }
              }
          }
  
          List<List<String>> result = new ArrayList<>();
  
          List<String> allPredictedLabelsSorted = new ArrayList<>();
          TreeSet<String> extraPredictedLabels = new TreeSet<>(allPredictedLabels);
          extraPredictedLabels.removeAll(allGoldLabels);
  
          allPredictedLabelsSorted.addAll(allGoldLabels);
          allPredictedLabelsSorted.addAll(extraPredictedLabels);
  
          // header
          List<String> header = new ArrayList<>();
          header.add("↓gold\\pred→");
          header.addAll(allPredictedLabelsSorted);
          result.add(header);
  
          for (String rowLabel : allGoldLabels) {
              List<String> row = new ArrayList<>();
              row.add(rowLabel);
  
              double rowSum = getRowSum(rowLabel);
  
              for (String predictedLabel : allPredictedLabelsSorted) {
                  double value = 0;
  
                  if (this.map.containsKey(rowLabel) && this.map.get(rowLabel)
                          .containsKey(predictedLabel)) {
                      value = this.map.get(rowLabel).get(predictedLabel) / rowSum;
                  }
                  row.add(String.format(locale, getFormat(), value));
              }
  
              result.add(row);
          }
  
          return result;
      }
docs: Makes probabilistic confusion matrix, where the entries are real numbers sum up to 1 for
  each gold row
  
  @return table