Ensembles#
The RuleTree.ensemble module combines RuleTrees by boosting. The ensembles take tabular data
(fit(X, y), predict(X)) and stop early when the error on a validation set, taken from the
training set (val_size), does not improve for patience iterations.
from sklearn.datasets import load_diabetes
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from RuleTree import RuleTreeRegressor
X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
single_tree = RuleTreeRegressor(max_depth=3, random_state=0).fit(X_train, y_train)
print("single tree, R2 on the test set:", round(r2_score(y_test, single_tree.predict(X_test)), 3))
single tree, R2 on the test set: 0.188
Gradient boosting#
GBoostRegressor fits each tree on the residuals of the
previous ones (squared loss). The base estimator can be any RuleTreeRegressor, with any stumps:
from RuleTree.ensemble.GBoostRegressor import GBoostRegressor
boosting = GBoostRegressor(base_estimator=RuleTreeRegressor(max_depth=2, random_state=0),
n_estimators=50, learning_rate=0.1, random_state=0)
boosting.fit(X_train, y_train)
print("trees:", len(boosting.estimators_))
print("R2 on the test set:", round(r2_score(y_test, boosting.predict(X_test)), 3))
trees: 45
R2 on the test set: 0.339
GBoostClassifier fits, for each class, a boosting of
regression trees on the log-odds of the class (one-vs-rest, logistic loss); the classes are fitted
in parallel processes (n_jobs):
from sklearn.datasets import load_breast_cancer
from RuleTree.ensemble.GBoostClassifier import GBoostClassifier
X_bc, y_bc = load_breast_cancer(return_X_y=True)
X_bc_train, X_bc_test, y_bc_train, y_bc_test = train_test_split(X_bc, y_bc, test_size=0.3, random_state=0)
classifier = GBoostClassifier(base_estimator=RuleTreeRegressor(max_depth=2, random_state=0),
n_estimators=20, n_jobs=1, random_state=0)
classifier.fit(X_bc_train, y_bc_train)
print("accuracy on the test set:", round((classifier.predict(X_bc_test) == y_bc_test).mean(), 3))
accuracy on the test set: 0.947
GBoostClassifier.predict returns the right classes only when they are 0, ..., n_classes - 1:
encode other labels first, e.g. with sklearn.preprocessing.LabelEncoder.
XGBoost#
XGBoostRegressor is a gradient boosting with the
trees of XGBoost (RuleTreeXGBoostRegressor): the
splits maximize the XGBoost gain, the splits with a gain lower than gamma are pruned, and each
leaf predicts its regularized value sum(residuals) / (n + lam).
from RuleTree.ensemble.XGBoostRegressor import XGBoostRegressor
from RuleTree.stumps.regression import XGBoostStumpRegressor
from RuleTree.tree.RuleTreeXGBoostRegressor import RuleTreeXGBoostRegressor
xgboost = XGBoostRegressor(base_estimator=RuleTreeXGBoostRegressor(
max_depth=2, lam=1, base_stumps=XGBoostStumpRegressor(lam=1)), n_estimators=20)
xgboost.fit(X_train, y_train)
print("R2 on the test set:", round(r2_score(y_test, xgboost.predict(X_test)), 3))
R2 on the test set: 0.332
Without base_estimator, the trees use as many processes as CPUs.
Explainable boosting#
EBMRegressor is an explainable boosting machine: each tree
is fitted on a single feature or on a pair of features, so the prediction is a sum of functions of
one or two features, which can be plotted and inspected.
from RuleTree.ensemble.EBMRegressor import EBMRegressor
ebm = EBMRegressor(base_estimator=RuleTreeRegressor(max_depth=1, random_state=0),
n_iterations=20, learning_rate=0.1, random_state=0)
ebm.fit(X_train, y_train)
print("terms:", len(ebm.estimators_), "- e.g.", list(ebm.estimators_)[:3], list(ebm.estimators_)[-1])
print("R2 on the test set:", round(r2_score(y_test, ebm.predict(X_test)), 3))
terms: 55 - e.g. [0, 1, 2] (8, 9)
R2 on the test set: 0.344
The terms are the features (their index) and the pairs of features; estimators_[term] is the
list of trees of the term.