The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
The e2tree package implements the Explainable Ensemble Tree (E2Tree) methodology, which constructs a single interpretable decision tree that approximates the predictions of an ensemble model (such as a random forest). The key idea is to use the dissimilarity structure induced by the ensemble to guide the construction of the tree, thereby preserving the predictive information encoded in the ensemble while providing a transparent, human-readable model.
The methodology is described in:
A typical e2tree analysis follows these steps:
randomForest or ranger)createDisMatrix()e2tree()predict()eValidation() and loi()We use the classic iris dataset to demonstrate a
classification workflow.
library(e2tree)
#> Explainable Ensemble Trees (E2Tree)
#>
#> If you use e2tree in research, please cite:
#>
#> - Aria, M., Gnasso, A., Iorio, C., & Pandolfo, G. (2024). Explainable ensemble trees.
#> Computational Statistics, 39(1), 3-19. DOI: 10.1007/s00180-022-01312-6
#>
#> - Aria, M., Gnasso, A., Iorio, C., & Fokkema, M. (2026). Extending Explainable Ensemble Trees to Regression Contexts. Applied Stochastic Models in Business and Industry, 42(1), e70064. DOI: 10.1002/asmb.70064
data(iris)
set.seed(42)
smp_size <- floor(0.75 * nrow(iris))
train_ind <- sample(seq_len(nrow(iris)), size = smp_size)
training <- iris[train_ind, ]
validation <- iris[-train_ind, ]if (!require("randomForest")) install.packages("randomForest",
repos="https://cran.r-project.org")
#> Loading required package: randomForest
#> randomForest 4.7-1.2
#> Type rfNews() to see new features/changes/bug fixes.
library(randomForest)
ensemble <- randomForest(Species ~ ., data = training,
importance = TRUE, proximity = TRUE)
ensemble
#>
#> Call:
#> randomForest(formula = Species ~ ., data = training, importance = TRUE, proximity = TRUE)
#> Type of random forest: classification
#> Number of trees: 500
#> No. of variables tried at each split: 2
#>
#> OOB estimate of error rate: 5.36%
#> Confusion matrix:
#> setosa versicolor virginica class.error
#> setosa 39 0 0 0.00000000
#> versicolor 0 36 2 0.05263158
#> virginica 0 4 31 0.11428571The ensemble induces a co-occurrence structure that captures how frequently pairs of observations fall into the same terminal nodes across the ensemble’s trees. This structure is encoded in the co-occurrence matrix \(\mathbf{O} = [o_{ij}]\), where each entry \(o_{ij} \in [0, 1]\) reflects the weighted frequency with which observations \(i\) and \(j\) are grouped together. The corresponding dissimilarity matrix is \(\mathbf{D} = \mathbf{1} - \mathbf{O}\).
The e2tree() function constructs a single tree that best
represents the ensemble’s dissimilarity structure. The
setting argument controls the stopping rules:
impTotal: minimum impurity to attempt a splitmaxDec: minimum decrease in impurity requiredn: minimum number of observations in a nodelevel: maximum tree depthprint(tree)
#>
#> Explainable Ensemble Tree (E2Tree)
#> -----------------------------------
#> Task: Classification
#> Response: Species
#> Predictors: 4 (Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)
#> Observations: 112
#> Nodes: 11 (total), 6 (terminal)
#> Max depth: 5
#> Split variables: Petal.Length, Petal.Width, Sepal.Length
#> Classes: setosa, versicolor, virginicasummary(tree)
#>
#> ======================================================================
#> E2TREE MODEL SUMMARY
#> ======================================================================
#>
#> MODEL INFORMATION
#> ----------------------------------------
#> Task: Classification
#> Response: Species
#> Observations: 112
#> Total Nodes: 11
#> Terminal Nodes: 6
#> Max Depth: 5
#> Split Variables: Petal.Length, Petal.Width, Sepal.Length
#> Classes: setosa, versicolor, virginica
#>
#>
#> TERMINAL NODES
#> ----------------------------------------------------------------------
#> Node Prediction n Purity Wt
#> -------------------------------------------------------
#> 2 setosa 39 100.0% --
#> 12 versicolor 35 97.1% --
#> 26 versicolor 2 100.0% --
#> 54 versicolor 2 50.0% --
#> 55 virginica 2 100.0% --
#> 7 virginica 32 96.9% --
#>
#>
#> DECISION RULES
#> ----------------------------------------------------------------------
#>
#> Rule 1 (Node 2, n=39):
#> IF Petal.Length <=1.9
#> THEN: setosa
#>
#> Rule 2 (Node 12, n=35):
#> IF Petal.Length >1.9
#> AND Petal.Width <=1.7
#> AND Petal.Length <=4.8
#> THEN: versicolor
#>
#> Rule 3 (Node 26, n=2):
#> IF Petal.Length >1.9
#> AND Petal.Width <=1.7
#> AND Petal.Length >4.8
#> AND Petal.Length <=4.9
#> THEN: versicolor
#>
#> Rule 4 (Node 54, n=2):
#> IF Petal.Length >1.9
#> AND Petal.Width <=1.7
#> AND Petal.Length >4.8
#> AND Petal.Length >4.9
#> AND Sepal.Length <=6
#> THEN: versicolor
#>
#> Rule 5 (Node 55, n=2):
#> IF Petal.Length >1.9
#> AND Petal.Width <=1.7
#> AND Petal.Length >4.8
#> AND Petal.Length >4.9
#> AND Sepal.Length >6
#> THEN: virginica
#>
#> Rule 6 (Node 7, n=32):
#> IF Petal.Length >1.9
#> AND Petal.Width >1.7
#> THEN: virginica
#>
#> ======================================================================The nodes() accessor extracts the tree structure as a
data frame:
# Terminal nodes only
nodes(tree, terminal = TRUE)
#> node n pred prob impTotal impChildren decImp decImpSur
#> 2 2 39 setosa 1.0000000 0.02581558 NA NA NA
#> 12 12 35 versicolor 0.9714286 0.23840014 NA NA NA
#> 26 26 2 versicolor 1.0000000 0.30526614 NA NA NA
#> 54 54 2 versicolor 0.5000000 0.60063498 NA NA NA
#> 55 55 2 virginica 1.0000000 0.53804112 NA NA NA
#> 7 7 32 virginica 0.9687500 0.27410535 NA NA NA
#> variable split splitLabel variableSur splitLabelSur parent children terminal
#> 2 <NA> NA <NA> <NA> <NA> 1 NA TRUE
#> 12 <NA> NA <NA> <NA> <NA> 6 NA TRUE
#> 26 <NA> NA <NA> <NA> <NA> 13 NA TRUE
#> 54 <NA> NA <NA> <NA> <NA> 27 NA TRUE
#> 55 <NA> NA <NA> <NA> <NA> 27 NA TRUE
#> 7 <NA> NA <NA> <NA> <NA> 3 NA TRUE
#> obs
#> 2 1, 8, 9, 14, 18, 20, 22, 24, 27, 30, 32, 33, 34, 35, 37, 38, 41, 45, 47, 52, 53, 55, 57, 60, 61, 63, 66, 68, 69, 70, 82, 85, 88, 89, 95, 98, 99, 101, 111
#> 12 2, 3, 11, 12, 25, 28, 29, 39, 40, 44, 46, 48, 49, 50, 58, 67, 71, 72, 75, 76, 77, 78, 79, 81, 84, 86, 87, 90, 91, 97, 103, 104, 108, 110, 112
#> 26 65, 83
#> 54 23, 73
#> 55 42, 92
#> 7 4, 5, 6, 7, 10, 13, 15, 16, 17, 19, 21, 26, 31, 36, 43, 51, 54, 56, 59, 62, 64, 74, 80, 93, 94, 96, 100, 102, 105, 106, 107, 109
#> path
#> 2 Petal.Length <=1.9
#> 12 !Petal.Length <=1.9 & Petal.Width <=1.7 & Petal.Length <=4.8
#> 26 !Petal.Length <=1.9 & Petal.Width <=1.7 & !Petal.Length <=4.8 & Petal.Length <=4.9
#> 54 !Petal.Length <=1.9 & Petal.Width <=1.7 & !Petal.Length <=4.8 & !Petal.Length <=4.9 & Sepal.Length <=6
#> 55 !Petal.Length <=1.9 & Petal.Width <=1.7 & !Petal.Length <=4.8 & !Petal.Length <=4.9 & !Sepal.Length <=6
#> 7 !Petal.Length <=1.9 & !Petal.Width <=1.7
#> ncat pred_val yval2.V1 yval2.V2 yval2.V3 yval2.V4 yval2.V5
#> 2 NA 1 1.00000000 39.00000000 0.00000000 0.00000000 1.00000000
#> 12 NA 2 2.00000000 0.00000000 34.00000000 1.00000000 0.00000000
#> 26 NA 2 2.00000000 0.00000000 2.00000000 0.00000000 0.00000000
#> 54 NA 2 2.00000000 0.00000000 1.00000000 1.00000000 0.00000000
#> 55 NA 3 3.00000000 0.00000000 0.00000000 2.00000000 0.00000000
#> 7 NA 3 3.00000000 0.00000000 1.00000000 31.00000000 0.00000000
#> yval2.V6 yval2.V7 yval2.nodeprob
#> 2 0.00000000 0.00000000 0.34821429
#> 12 0.97142857 0.02857143 0.31250000
#> 26 1.00000000 0.00000000 0.01785714
#> 54 0.50000000 0.50000000 0.01785714
#> 55 0.00000000 1.00000000 0.01785714
#> 7 0.03125000 0.96875000 0.28571429The plot() method renders the tree using
rpart.plot:
You can also convert the tree to rpart or
partykit formats for alternative visualizations:
# Convert to rpart
rpart_obj <- as.rpart(tree, ensemble)
# Convert to partykit (if installed)
if (requireNamespace("partykit", quietly = TRUE)) {
party_obj <- partykit::as.party(tree)
plot(party_obj)
}Use the standard predict() method on new data:
pred <- predict(tree, newdata = validation)
head(pred)
#> fit accuracy score
#> 1 setosa 1 0
#> 2 setosa 1 0
#> 3 setosa 1 0
#> 4 setosa 1 0
#> 5 setosa 1 0
#> 6 setosa 1 0Fitted values for the training data:
vi <- vimp(tree, data = training)
vi$vimp
#> # A tibble: 3 × 9
#> Variable MeanImpurityDecrease MeanAccuracyDecrease `ImpDec_ setosa`
#> <chr> <dbl> <dbl> <dbl>
#> 1 Petal.Length 0.339 8.93e- 3 0.302
#> 2 Petal.Width 0.208 -7.24e-17 NA
#> 3 Sepal.Length 0.00280 0 NA
#> # ℹ 5 more variables: `ImpDec_ versicolor` <dbl>, `ImpDec_ virginica` <dbl>,
#> # `AccDec_ setosa` <dbl>, `AccDec_ versicolor` <dbl>,
#> # `AccDec_ virginica` <dbl>
vi$g_impThe same workflow applies to regression problems. Here we use the
mtcars dataset.
data(mtcars)
set.seed(123)
smp_size <- floor(0.75 * nrow(mtcars))
train_ind <- sample(seq_len(nrow(mtcars)), size = smp_size)
training_reg <- mtcars[train_ind, ]
validation_reg <- mtcars[-train_ind, ]ensemble_reg <- randomForest(mpg ~ ., data = training_reg, ntree = 500,
importance = TRUE, proximity = TRUE)D_reg <- createDisMatrix(ensemble_reg, data = training_reg, label = "mpg",
parallel = list(active = FALSE, no_cores = 1))setting_reg <- list(impTotal = 0.1, maxDec = 1e-6, n = 2, level = 5)
tree_reg <- e2tree(mpg ~ ., training_reg, D_reg, ensemble_reg, setting_reg)
print(tree_reg)
#>
#> Explainable Ensemble Tree (E2Tree)
#> -----------------------------------
#> Task: Regression
#> Response: mpg
#> Predictors: 10 (cyl, disp, hp, drat, wt)
#> ... and 5 more
#> Observations: 24
#> Nodes: 7 (total), 4 (terminal)
#> Max depth: 3
#> Split variables: cyl, wtFor regression models, predictions include the standard deviation within each terminal node, providing a measure of prediction uncertainty:
pred_reg <- predict(tree_reg, newdata = validation_reg)
head(pred_reg)
#> fit sd
#> 1 19.82000 1.446375
#> 2 19.82000 1.446375
#> 3 14.97778 2.132943
#> 4 14.97778 2.132943
#> 5 14.97778 2.132943
#> 6 22.85000 1.226105Residuals are also available:
A fundamental question arises when using E2Tree: how well does the single interpretable tree capture the original ensemble’s structure? The E2Tree reconstructs the ensemble’s co-occurrence matrix \(\mathbf{O}\) through its terminal node structure, producing an approximation \(\hat{\mathbf{O}}_T\). Assessing the quality of this reconstruction is essential to ensure that the explanatory model faithfully represents the ensemble’s decision logic.
The eValidation() function provides two complementary
approaches to validation, selectable through the test
argument:
test = "mantel": The Mantel test, a
classical non-parametric test of association between similarity
matrices.test = "measures": A family of
divergence and similarity measures that assess agreement
between the matrices, with permutation-based inference.test = "both" (default): Performs
both.The distinction between these two approaches mirrors the classical distinction between correlation and concordance in method comparison studies (Bland & Altman, 1986; Lin, 1989). Two proximity matrices can be perfectly correlated (\(r = 1\)) and yet systematically disagree: if \(\hat{\mathbf{O}}_T = c \cdot \mathbf{O}\) for any constant \(c \neq 1\), the Mantel test would declare perfect association, yet the actual proximity values would not be faithfully reproduced.
This distinction matters in the E2Tree context. The ensemble matrix \(\mathbf{O}\) contains continuous values in \((0, 1)\), reflecting varying degrees of co-occurrence across the ensemble’s trees. The E2Tree matrix \(\hat{\mathbf{O}}_T\), by contrast, has a crisp block-diagonal structure: observations within the same terminal node share a common co-occurrence value, while observations in different nodes have zero co-occurrence. Even when the block structure perfectly matches the grouping pattern of \(\mathbf{O}\), the element-wise values will differ because \(\mathbf{O}\) is fuzzy and \(\hat{\mathbf{O}}_T\) is crisp. A scale-sensitive divergence measure can quantify this discrepancy; a correlation-based measure cannot.
The Mantel test evaluates whether the E2Tree proximity matrix is associated with the ensemble proximity matrix. It computes a correlation-like statistic between the two matrices and assesses significance through permutation.
val_mantel <- eValidation(training, tree, D, test = "mantel", graph = FALSE)
print(val_mantel)
#>
#> ##############################################################################
#> E2Tree Validation
#> ##############################################################################
#>
#> Matrix dimension: 112 x 112
#> Pairs: 6216
#>
#> Mantel test: z = 1512.22, p = 0.0010
#>
#> ##############################################################################A significant Mantel test confirms that E2Tree preserves the overall pattern of the ensemble’s proximity structure. However, it does not tell us how closely the actual proximity values are reproduced, nor does it indicate where the reconstruction fails.
To assess agreement rather than mere association, we use a family of five measures, each capturing a distinct aspect of reconstruction quality:
| Measure | Type | Range | What it captures |
|---|---|---|---|
| nLoI (normalized Loss of Interpretability) | divergence | [0, 1] | Scale-sensitive per-pair discrepancy with diagnostic decomposition |
| Hellinger distance | divergence | [0, 1] | Variance-stabilized element-wise difference (a true metric) |
| wRMSE (weighted Root Mean Squared Error) | divergence | [0, 1] | Weighted average discrepancy emphasizing high-proximity regions |
| RV coefficient | similarity | [0, 1] | Global structural similarity (matrix-level correlation) |
| SSIM (Structural Similarity Index) | similarity | [-1, 1] | Local spatial pattern similarity (luminance, contrast, structure) |
For divergence measures, lower values indicate better reconstruction. For similarity measures, higher values indicate better reconstruction.
Statistical significance is assessed through a unified permutation testing framework based on simultaneous row/column permutation of \(\hat{\mathbf{O}}_T\). This preserves the block-diagonal structure of the E2Tree matrix while breaking the correspondence between observation labels and node assignments, providing the appropriate null hypothesis: under \(H_0\), E2Tree groups observations randomly with respect to the ensemble structure.
val_meas <- eValidation(training, tree, D, test = "measures",
graph = FALSE, n_perm = 499)
print(val_meas)
#>
#> ##############################################################################
#> E2Tree Validation
#> ##############################################################################
#>
#> Matrix dimension: 112 x 112
#> Pairs: 6216
#>
#> ------------------------------------------------------------------------------
#> Measure Type Observed Null mean Z-stat p-value
#> ------------------------------------------------------------------------------
#> nLoI [div] 0.0468 0.4060 -74.99 0.0020 **
#> Hellinger [div] 0.2063 0.6243 -106.18 0.0020 **
#> wRMSE [div] 0.2002 0.8320 -184.50 0.0020 **
#> RV [sim] 0.9624 0.3273 +76.04 0.0020 **
#> SSIM [sim] 0.6718 0.0076 +148.36 0.0020 **
#> ------------------------------------------------------------------------------
#> Permutations: 499 (row/column), conf.level: 95%
#>
#> LoI Decomposition (per-pair avg): mean_in = 0.020614, mean_out = 0.057709
#>
#> [div] = divergence (lower=better), [sim] = similarity (higher=better)
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1
#>
#> ##############################################################################All divergence measures are significantly lower than their null expectations (negative Z-statistics), while all similarity measures are significantly higher (positive Z-statistics), confirming that the E2Tree faithfully reconstructs the ensemble’s proximity structure.
measures(val_meas)
#> method type observed null_mean null_sd z_stat p_value
#> 1 nLoI divergence 0.04675804 0.405974055 0.004789926 -74.99407 0.002
#> 2 Hellinger divergence 0.20634450 0.624258879 0.003936005 -106.17731 0.002
#> 3 wRMSE divergence 0.20024399 0.832018752 0.003424183 -184.50378 0.002
#> 4 RV similarity 0.96244104 0.327255499 0.008352769 76.04491 0.002
#> 5 SSIM similarity 0.67183834 0.007606083 0.004477240 148.35753 0.002
#> ci_lower ci_upper
#> 1 0.04044819 0.05828068
#> 2 0.20092189 0.21610662
#> 3 0.19557892 0.20859867
#> 4 0.94198847 0.97359096
#> 5 0.66025940 0.67907518The plot() method for eValidation objects
provides a visual summary including heatmaps of both proximity matrices,
the null distribution of nLoI (when permutation tests are performed),
and the LoI decomposition:
val_full <- eValidation(training, tree, D, test = "both",
graph = FALSE, n_perm = 499)
plot(val_full)Among the divergence measures, the nLoI deserves special attention because of its unique decomposability into within-node and between-node components.
The nLoI is defined as: \[\text{nLoI}(\mathbf{O}, \hat{\mathbf{O}}_T) = \frac{1}{M} \sum_{i<j} \frac{(o_{ij} - \hat{o}_{ij})^2}{\max(o_{ij}, \hat{o}_{ij})}\] where \(M = n(n-1)/2\) is the number of unique pairs.
This statistic is connected to the Cressie-Read power divergence family at \(\lambda = -2\) (Neyman-type statistic), with a robustified denominator that avoids singularities when \(\hat{o}_{ij} = 0\) (which is common in E2Tree due to the block-diagonal structure of \(\hat{\mathbf{O}}_T\)).
The loi() function computes the nLoI and its
decomposition directly from two proximity matrices:
prox <- proximity(val_full)
result <- loi(prox$ensemble, prox$e2tree)
summary(result)
#>
#> ##############################################################################
#> Loss of Interpretability (LoI) --Decomposition
#> ##############################################################################
#>
#> nLoI (normalized): 0.0468
#> LoI (raw): 290.6480
#> n = 112, pairs = 6216 (within: 1835, between: 4381)
#>
#> ------------------------------------------------------------------------------
#> Component Total Pairs Mean/pair
#> ------------------------------------------------------------------------------
#> Within-node (LoI_in) 37.8270 1835 0.020614
#> Between-node (LoI_out)252.8210 4381 0.057709
#> ------------------------------------------------------------------------------
#>
#> Per-pair interpretation (comparable across components):
#>
#> mean_in = 0.020614 (avg calibration error within nodes)
#> mean_out = 0.057709 (avg ensemble proximity lost by separation)
#>
#> Diagnostic: LOW mean_out. The partition correctly separates pairs
#> that have low ensemble proximity --the tree structure is well-placed.
#>
#> Diagnostic: MODERATE mean_in. Some within-node calibration error,
#> typical of the fuzzy-to-crisp structural transition.
#>
#> ##############################################################################The LoI decomposes into two interpretable components:
Within-node component (\(\text{LoI}_{in}\)): Measures reconstruction fidelity for pairs that E2Tree groups together. It captures the calibration error — whether the single tree assigns co-occurrence values that match the ensemble’s.
Between-node component (\(\text{LoI}_{out}\)): Measures the cost of the partition. It accumulates the ensemble co-occurrence values (\(o_{ij}\)) for pairs that E2Tree separates into different terminal nodes (where \(\hat{o}_{ij} = 0\)), representing irrecoverable loss.
Since between-node pairs vastly outnumber within-node pairs
(especially with many terminal nodes), the raw totals are not directly
comparable. The per-pair averages (mean_in and
mean_out) provide the meaningful diagnostic:
A high mean_out (e.g., > 0.3)
indicates that E2Tree is separating pairs with substantial ensemble
proximity. The practitioner should consider increasing the tree’s
complexity (more terminal nodes) or relaxing pruning
constraints.
A high mean_in (e.g., > 0.1)
indicates poor within-node calibration: the partition boundaries are
well-placed, but the within-node proximity values deviate from the
ensemble’s. This typically reflects the inherent fuzzy-to-crisp
structural transition.
Low values of both confirm that the E2Tree faithfully captures the ensemble structure — the partition is well-placed and the calibration is accurate.
This diagnostic capability is fundamentally impossible with the Mantel test or any other scalar association measure, which can only report that the overall reconstruction is “good” or “poor” without indicating the source of the discrepancy.
The loi_perm() function provides a standalone
permutation test for the nLoI, useful when a quick assessment of
reconstruction significance is needed without computing all five
measures:
perm <- loi_perm(prox$ensemble, prox$e2tree, n_perm = 499, seed = 42)
print(perm)
#>
#> ==============================================================================
#> Permutation Test for Loss of Interpretability (LoI)
#> ==============================================================================
#>
#> Observed nLoI: 0.0468
#> Null mean: 0.4059
#> Null SD: 0.0048
#> Z-statistic: -75.4053
#>
#> ------------------------------------------------------------------------------
#> Hypothesis Test (H1: nLoI < expected by chance)
#> ------------------------------------------------------------------------------
#> p-value: 0.0020 **
#> 95% CI: [0.0402, 0.0590]
#> Permutations: 499 (row/column)
#>
#> ------------------------------------------------------------------------------
#> Decomposition (per-pair averages)
#> ------------------------------------------------------------------------------
#> mean_in (within): 0.020614 (n_pairs = 1835)
#> mean_out (between): 0.057709 (n_pairs = 4381)
#>
#> ==============================================================================
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1
plot(perm)The same validation framework applies to regression E2Trees:
val_reg <- eValidation(training_reg, tree_reg, D_reg, test = "measures",
graph = FALSE, n_perm = 499)
print(val_reg)
#>
#> ##############################################################################
#> E2Tree Validation
#> ##############################################################################
#>
#> Matrix dimension: 24 x 24
#> Pairs: 276
#>
#> ------------------------------------------------------------------------------
#> Measure Type Observed Null mean Z-stat p-value
#> ------------------------------------------------------------------------------
#> nLoI [div] 0.1412 0.3381 -13.54 0.0020 **
#> Hellinger [div] 0.3357 0.5414 -14.84 0.0020 **
#> wRMSE [div] 0.3956 0.6971 -21.39 0.0020 **
#> RV [sim] 0.8533 0.3466 +13.81 0.0020 **
#> SSIM [sim] 0.5259 0.1525 +9.93 0.0020 **
#> ------------------------------------------------------------------------------
#> Permutations: 499 (row/column), conf.level: 95%
#>
#> LoI Decomposition (per-pair avg): mean_in = 0.178400, mean_out = 0.129262
#>
#> [div] = divergence (lower=better), [sim] = similarity (higher=better)
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1
#>
#> ##############################################################################Regression E2Trees typically show higher nLoI and Hellinger values than classification, consistent with the greater complexity of regression proximity structures and the typically smaller sample sizes. Nonetheless, all measures should achieve significant p-values, confirming that the reconstruction captures genuine structure.
sessionInfo()
#> R version 4.6.0 (2026-04-24)
#> Platform: aarch64-apple-darwin23
#> Running under: macOS Tahoe 26.5
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> locale:
#> [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> time zone: Europe/Rome
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] future_1.70.0 randomForest_4.7-1.2 e2tree_1.2.0
#>
#> loaded via a namespace (and not attached):
#> [1] gmp_0.7-5.1 utf8_1.2.6 tidyr_1.3.2
#> [4] sass_0.4.10 generics_0.1.4 lattice_0.22-9
#> [7] inum_1.0-5 listenv_0.10.1 digest_0.6.39
#> [10] magrittr_2.0.5 evaluate_1.0.5 grid_4.6.0
#> [13] RColorBrewer_1.1-3 mvtnorm_1.3-7 fastmap_1.2.0
#> [16] jsonlite_2.0.0 Matrix_1.7-5 ape_5.8-1
#> [19] Formula_1.2-5 survival_3.8-6 rpart.plot_3.1.4
#> [22] purrr_1.2.2 scales_1.4.0 codetools_0.2-20
#> [25] jquerylib_0.1.4 Rdpack_2.6.6 cli_3.6.6
#> [28] rlang_1.2.0 rbibutils_2.4.1 parallelly_1.47.0
#> [31] future.apply_1.20.2 splines_4.6.0 withr_3.0.2
#> [34] cachem_1.1.0 yaml_2.3.12 otel_0.2.0
#> [37] tools_4.6.0 parallel_4.6.0 polynom_1.4-1
#> [40] dplyr_1.2.1 ggplot2_4.0.3 partitions_1.10-9
#> [43] globals_0.19.1 vctrs_0.7.3 R6_2.6.1
#> [46] rpart_4.1.27 lifecycle_1.0.5 libcoin_1.0-12
#> [49] partykit_1.2-27 pkgconfig_2.0.3 pillar_1.11.1
#> [52] bslib_0.10.0 gtable_0.3.6 glue_1.8.1
#> [55] Rcpp_1.1.1-1.1 xfun_0.57 tibble_3.3.1
#> [58] tidyselect_1.2.1 rstudioapi_0.18.0 knitr_1.51
#> [61] farver_2.1.2 nlme_3.1-169 htmltools_0.5.9
#> [64] labeling_0.4.3 rmarkdown_2.31 compiler_4.6.0
#> [67] S7_0.2.2These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.