Skip to main content

c5tree 🌳

C5.0 Decision Tree Classifier for Python — a scikit-learn-compatible implementation of Ross Quinlan's C5.0 algorithm, with an optional native C++ numeric splitter.

PyPI version Python License: GPL v3


Why C5.0?

scikit-learn's DecisionTreeClassifier uses CART (binary splits, Gini/entropy). C5.0 offers several advantages:

Feature CART (sklearn) C5.0 (c5tree)
Split criterion Gini / Entropy Gain Ratio
Categorical splits Binary only Multi-way
Missing values Requires imputation Native support
Pruning Cost-complexity Pessimistic Error Pruning
Tree size Often larger Smaller, more interpretable

Installation

pip install c5tree

Quick Start

from c5tree import C5Classifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

clf = C5Classifier(pruning=True, cf=0.25)
clf.fit(X_train, y_train)

print(f"Accuracy: {clf.score(X_test, y_test):.3f}")
print(f"Tree depth: {clf.get_depth()}")
print(f"Leaves: {clf.get_n_leaves()}")

Key Features

Gain Ratio Splitting

Corrects ID3's bias toward features with many distinct values by normalising information gain by split information.

Optional Native Acceleration

Numeric split evaluation uses an optional C++ extension through pybind11 when a compiler is available. Standard installs remain supported without a compiler and automatically use the equivalent Python implementation. This keeps C5.0 gain-ratio behavior while accelerating its hottest numeric operation; it is not a LightGBM or XGBoost model.

Native Missing Value Handling

No imputation needed. Missing instances are distributed fractionally across branches, weighted by the proportion of known instances going each way.

import numpy as np

X_with_missing = X.copy().astype(float)
X_with_missing[0, 2] = np.nan   # inject a missing value

clf.fit(X_with_missing, y)      # works out of the box
clf.predict(X_with_missing)     # also works

Categorical Feature Support

Pass a pandas DataFrame and c5tree automatically detects object/category columns and applies multi-way splits:

import pandas as pd

df = pd.DataFrame({
    "outlook":  ["sunny", "overcast", "rainy", "sunny", "rainy"],
    "humidity": [85, 65, 70, 95, 80],
    "play":     [0, 1, 1, 0, 1],
})
X = df[["outlook", "humidity"]]
y = df["play"]

clf = C5Classifier(pruning=False).fit(X, y)

Pessimistic Error Pruning

After the tree is grown, subtrees are replaced by leaves if the pessimistic error estimate of the subtree is no better than a single leaf. Controlled by the cf parameter.

# cf=0.25  → default, moderate pruning
# cf=0.05  → aggressive pruning, very small tree
# cf=0.50  → light pruning, larger tree
clf = C5Classifier(pruning=True, cf=0.05)

Human-Readable Tree

print(clf.text_report())
# [feature_2 <= 1.9000]
#   left:
#     → Predict: 0  [0: 1.00, 1: 0.00, 2: 0.00]  (n=40.0)
#   right:
#     [feature_3 <= 1.7500]
#       ...

Tested sklearn Compatibility

The tested estimator workflows include Pipelines, GridSearchCV, cross_val_score, and clone:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV

pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("clf", C5Classifier()),
])

param_grid = {"clf__cf": [0.05, 0.25, 0.50], "clf__max_depth": [None, 5, 10]}
search = GridSearchCV(pipe, param_grid, cv=5)
search.fit(X_train, y_train)
print(search.best_params_)

Parameters

Parameter Type Default Description
max_depth int or None None Maximum tree depth
min_samples_split int 2 Minimum samples to split a node
min_samples_leaf int 1 Minimum samples at a leaf
pruning bool True Enable pessimistic error pruning
cf float 0.25 Confidence factor for pruning (0.05–0.50)
min_gain_ratio float 0.0 Minimum gain ratio to make a split

Running Tests

python -m pip install -e ".[dev]"
pytest tests/ -v --cov=c5tree

Building Packages

python -m pip install build
python -m build

The wheel includes the native C++ splitter when it can be compiled. Installing from source without a supported compiler still succeeds and uses the Python fallback. Binary wheels can be published for each supported operating system and Python version, as with LightGBM and XGBoost, so most users do not need a compiler.


Background

C5.0 is the successor to C4.5 and ID3, developed by Ross Quinlan. The algorithm was open-sourced in 2011 under the GPL licence. This package is a clean Python reimplementation that integrates C5.0-style splitting with the scikit-learn estimator API.

Reference: Quinlan, J.R. (1993). C4.5: Programs for Machine Learning. Morgan Kaufmann.


Contributing

Contributions are very welcome! Please open an issue before submitting a PR.

Licence

GPL-3.0-or-later License — see LICENSE.

Metadata

Release files for c5tree 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for c5tree 0.2.0
File Size Uploaded Provenance
c5tree-0.2.0.tar.gz 29.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for c5tree 0.2.0
File Interpreter ABI Platform
c5tree-0.2.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details

Total release size: 131.3 kB

Release files / c5tree-0.2.0.tar.gz

Download URL c5tree-0.2.0.tar.gz
Size 29.9 kB
Tags Source
SHA-256 checksum
How to use checksums
1e33ebdfc01246841b02734899ba387ce8f49901f7e6cdc50e413161992fd792
BLAKE2b-256 checksum
How to use checksums
5f113dbd8a8970946527cc3649439e66ea5dbc9b44c411d02f0cf94b087822c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.6

Release files / c5tree-0.2.0-cp311-cp311-win_amd64.whl

Download URL c5tree-0.2.0-cp311-cp311-win_amd64.whl
Size 101.5 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
0a29ae72a2ee312456407ea9f71bbec81d101b1d55983003446efef89eb96158
BLAKE2b-256 checksum
How to use checksums
084e92a707399add54067dd08cfbb89695ab27695a10fcdcfded140b67dfd251
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.6

Security for c5tree 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page