Python
Scikit-learn
Machine Learning
Data Analysis
Classification Report

Scikit classification report - change the format of displayed results

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

sklearn.metrics.classification_report is handy because it shows precision, recall, F1-score, and support in one place. The catch is that the default output is a preformatted text block aimed at quick inspection, not custom reporting. If you want a different display format, the clean approach is to ask for structured data and format it yourself.

What the Default Report Gives You

A basic call returns a formatted string:

python
1from sklearn.metrics import classification_report
2
3y_true = [0, 1, 0, 1, 1]
4y_pred = [0, 1, 0, 0, 1]
5
6print(classification_report(y_true, y_pred))

That is useful for terminal output, but it becomes limiting if you need:

  • different decimal precision
  • renamed class labels
  • a pandas table
  • JSON for an API or experiment log

The text report is convenient, but it is also the least flexible representation.

Use digits for Small Formatting Changes

If the only issue is numeric precision, use the digits parameter:

python
1from sklearn.metrics import classification_report
2
3y_true = [0, 1, 0, 1, 1]
4y_pred = [0, 1, 0, 0, 1]
5
6print(classification_report(y_true, y_pred, digits=4))

This changes how many decimal places are displayed. It does not change the metric calculation itself.

That makes digits the right answer when you want a slightly different report but still intend to print the built-in string.

Use output_dict=True for Full Control

For real customization, request the report as a dictionary:

python
1from sklearn.metrics import classification_report
2
3y_true = [0, 1, 0, 1, 1]
4y_pred = [0, 1, 0, 0, 1]
5
6report = classification_report(y_true, y_pred, output_dict=True)
7print(report)

Now you have raw numeric values organized by class and aggregate rows. From there you can reorder fields, rename rows, round selectively, or export the result in any structure you want.

This is the best route for dashboards, notebooks, services, and experiment-tracking systems.

Convert the Result to a DataFrame

A common next step is pandas:

python
1import pandas as pd
2from sklearn.metrics import classification_report
3
4y_true = [0, 1, 0, 1, 1]
5y_pred = [0, 1, 0, 0, 1]
6
7report = classification_report(y_true, y_pred, output_dict=True)
8df = pd.DataFrame(report).transpose()
9
10print(df.round(3))

This gives you a table that is much easier to manipulate. For example, you can pick only the columns you care about:

python
print(df[["precision", "recall", "f1-score", "support"]].round(2))

You can also export it with df.to_csv(...) or style it inside a notebook.

Rename Labels and Stabilize Edge Cases

If your class labels need human-readable names, pass target_names:

python
1from sklearn.metrics import classification_report
2
3y_true = [0, 1, 0, 1, 1]
4y_pred = [0, 1, 0, 0, 1]
5
6print(classification_report(
7    y_true,
8    y_pred,
9    target_names=["negative", "positive"]
10))

Another important option is zero_division. When a class has no predicted samples or no true samples, scikit-learn may emit warnings or fill metrics with zeros. If the report is part of an automated workflow, it is usually better to make that behavior explicit:

python
1from sklearn.metrics import classification_report
2
3y_true = [0, 0, 0, 1]
4y_pred = [0, 0, 0, 0]
5
6print(classification_report(y_true, y_pred, zero_division=0))

That keeps edge-case output stable.

JSON Output for Reporting Systems

Once you have a dictionary, JSON is straightforward:

python
1import json
2from sklearn.metrics import classification_report
3
4y_true = [0, 1, 0, 1, 1]
5y_pred = [0, 1, 0, 0, 1]
6
7report = classification_report(y_true, y_pred, output_dict=True)
8print(json.dumps(report, indent=2))

This is much better than parsing the pretty-printed text block when the result needs to be stored or transmitted.

Common Pitfalls

The biggest mistake is parsing the default text output with string operations. That is brittle and unnecessary because the function already offers structured output.

Another mistake is assuming digits changes the underlying metrics. It only changes how the text is displayed.

People also forget that rows such as accuracy, macro avg, and weighted avg are not shaped exactly like per-class rows, so DataFrame formatting should handle them intentionally.

Finally, if some classes are missing from predictions, do not ignore zero_division. Edge-case behavior matters when reports are generated automatically.

Summary

  • Use digits for simple display-only precision changes.
  • Use output_dict=True when you need real formatting control.
  • Convert the result to pandas for tabular reporting and export.
  • Use target_names and zero_division to improve readability and stability.
  • Avoid brittle string parsing when structured metrics are already available.

Course illustration
Course illustration

All Rights Reserved.