Docs · Machine learning
tree: decision tree classifier.
A histogram-based decision tree classifier with Gini impurity, the equivalent of Spark MLlib's DecisionTreeClassifier. One min/max pass fixes uniform bins per feature, then one paged pass per level accumulates class counts per node, feature and bin.
- Module
- ml_tree
- Header
- clio_ml/decision_tree.h
- Rows
- features, then class label
- Limits
- max_depth at most 8
What it does
The host picks each frontier node's best split by maximum Gini gain, breaking ties by lowest feature and then lowest bin. Counts are integers, so the tree is exact and identical across paging, block counts and nodes. The same header also defines the random forest, which reuses DecisionTreeOptions with seed and features_per_node set.
Rows
n_features feature columns followed by the class label in 0..num_classes-1. clio_ml.COLUMNS["tree"] is 1.
Python
import numpy as np, clio_ml as cm
rng = np.random.default_rng(1)
X = rng.normal(size=(4096, 7)).astype(np.float32)
y = ((X[:, 0] > 0) + (X[:, 1] > 0.25)).astype(np.float32) # 3 classes
data = np.column_stack([X, y]).astype(np.float32)
r = cm.fit_tree(data, num_classes=3, max_depth=4, num_bins=32)
print(r.model.depth, r.model.status[:7]) # 0 absent, 2 leaf, 3 split
print(cm.predict("tree", r, data[0, :7])) # predicted classfit_tree(X, **options).- Options (
DecisionTreeOptions):num_classes(2),max_depth(4, at most 8),num_bins(32),threads(256),seed(0; non-zero turns on the Poisson(1) bootstrap used by random forests),features_per_node(0 = all features; otherwise a hashed subset per node),row_base(0). - Result
DecisionTreeResult:modelandstats(summed over passes).model(DecisionTreeModel) is a heap-ordered tree with2^(max_depth+1)-1slots:nf,C,B(bins),depth,mnandinv(binning, nf each),status(0 absent, 2 leaf, 3 split),feat,split,cls(majority class per node),counts(class counts per node). predict("tree", r, x)returns the class index.
C++
struct DecisionTreeOptions {
u32 num_classes = 2;
u32 max_depth = 4; // <= 8
u32 num_bins = 32;
u32 threads = 256;
u32 seed = 0; // != 0: Poisson(1) bootstrap rows
u32 features_per_node = 0; // 0 = all
u64 row_base = 0;
ClusterExchange cluster;
};
struct DecisionTreeModel {
u32 nf = 0, C = 0, B = 0, depth = 0;
std::vector<float> mn, inv;
std::vector<int> status, feat, split;
std::vector<u32> cls;
std::vector<float> counts;
std::vector<float> Flatten() const;
};
struct DecisionTreeResult { DecisionTreeModel model; VecStats stats; };
DecisionTreeResult FitDecisionTree(Dataset &ds, const DecisionTreeOptions &opt);
DecisionTreeResult FitDecisionTreePlain(const float *data, u64 n_rows, u32 nf,
u64 elems_per_page, u32 nblocks,
const DecisionTreeOptions &opt);
DecisionTreeResult FitDecisionTreeReference(/* same arguments */);
u32 DecisionTreePredict(const DecisionTreeModel &m, const float *x);The ChiMod is module ml_tree.
Related: random forest, gradient-boosted trees, gradient-boosted classifier.