presto-ml/src/main/java/io/prestosql/plugin/ml/EvaluateClassifierPredictionsAggregation.java/EvaluateClassifierPredictionsAggregation/output
class EvaluateClassifierPredictionsAggregation:    @OutputFunction(StandardTypes.VARCHAR)
    public static void output(@AggregationState EvaluateClassifierPredictionsState state, BlockBuilder out)
    {
        StringBuilder sb = new StringBuilder();
        long correct = state.getTruePositives()
                .values()
                .stream()
                .reduce(0, Integer::sum);
        long total = correct + state.getFalsePositives().values().stream().reduce(0, Integer::sum);
        sb.append(format(Locale.US, "Accuracy: %d/%d (%.2f%%)\n", correct, total, 100.0 * correct / (double) total));
        Set<String> labels = union(union(state.getTruePositives().keySet(), state.getFalsePositives().keySet()), state.getFalseNegatives().keySet());
        for (String label : labels) {
            int truePositives = state.getTruePositives().getOrDefault(label, 0);
            int falsePositives = state.getFalsePositives().getOrDefault(label, 0);
            int falseNegatives = state.getFalseNegatives().getOrDefault(label, 0);
            sb.append(format(Locale.US, "Class '%s'\n", label));
            sb.append(format(Locale.US, "Precision: %d/%d (%.2f%%)\n", truePositives, truePositives + falsePositives, 100.0 * truePositives / (double) (truePositives + falsePositives)));
            sb.append(format(Locale.US, "Recall: %d/%d (%.2f%%)\n", truePositives, truePositives + falseNegatives, 100.0 * truePositives / (double) (truePositives + falseNegatives)));
        }

        VARCHAR.writeString(out, sb.toString());
    }