<p>This answer is based on the reference that professor @AchimZeileis provided in his article (<a href="https://arxiv.org/abs/1906.10179" rel="nofollow noreferrer">https://arxiv.org/abs/1906.10179</a>), and it is devoted to the second part of my original question, which was regarding the question: <em><strong>How to count the correctly specified models (trees)?</strong></em></p>
<h1>The short answer.</h1>
<p>The article divides the problem into two different types of data generating process (DGP). In the first one, the data has only one break in one variable (&quot;<em>stump</em>&quot; case), and the authors count the number of correctly identified models based on the number of times that the M-fluctuation test identified correctly the variable that was generating the break (just one real break in one variable and 9 noisy candidates to be splitting variable with no break). The second DGP was a model with two breaks (<em>&quot;tree&quot;</em> case), and they used the <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">Adjusted Rand Index</a> (ARI) to assess the performance of the model as a metric of the similarity of the real tree to the predicted one.</p>
<h1>The <s>very</s> long answer.</h1>
<p>Let's break down the <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> for 6 different illustrative possible trees that can be obtained at different sample sizes. The code used here is highly based on the supplemental material of the <a href="https://arxiv.org/abs/1906.10179" rel="nofollow noreferrer">article</a> recommended by @AchimZeileis.</p>
<h2>Data generating process: Tree structure</h2>
<p>The real dgp has 2 breaks, as illustrated in the picture below. The first one is generated by the variable <code>z2</code> and the second one by <code>z1</code>. In the snippet of the code below, delta is equal to 1. The threshold value for the first break (depending on <code>z2</code>) is equal to 0.3, and  the threshold value for the second break (depending on <code>z1</code>) is equal to -0.3 (the values can be seen in the object <code>xi = c(-0.3, 0.3)</code>)</p>
<p><a href="https://i.stack.imgur.com/mpT5n.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mpT5n.png" alt="Figure from   " /></a></p>
<pre><code>#function from https://arxiv.org/src/1906.10179v1/anc

dgp_tree &lt;- function(nobs = 1000, delta = 1, xi = c(-0.3, 0.3),  
                     sigma = 1, seed = 7,  
                     changetype = &quot;abrupt&quot;,
                     variation = &quot;all&quot;,
                     beta0 = NULL, beta1 = NULL)
{
  # check input values
  if(variation != &quot;all&quot;) stop(&quot;variation can only be set to 'all' in dgp_tree&quot;)
  if(changetype != &quot;abrupt&quot;) stop(&quot;changetype can only be abrupt in dgp_tree&quot;)
  if(!is.null(beta0) | !is.null(beta1)) warning(&quot;values for beta0 or beta1 are ignored since variation='all' for dgp_tree&quot;)
  
  set.seed(seed)
  
  if(length(xi)==1){
    xi1 &lt;- xi2 &lt;- xi
  } else {
    xi1 &lt;- xi[1]
    xi2 &lt;- xi[2]
  }
  
  z1 &lt;- runif(nobs,-1,1)
  z2 &lt;- runif(nobs,-1,1) 
  z3 &lt;- rnorm(nobs, 0, 1)
  z4 &lt;- rnorm(nobs, 0, 1)
  z5 &lt;- rnorm(nobs, 0, 1)
  z6 &lt;- rnorm(nobs, 0, 1)
  z7 &lt;- rnorm(nobs, 0, 1)
  z8 &lt;- runif(nobs, -1, 1)
  z9 &lt;- runif(nobs, -1, 1)
  z10 &lt;- runif(nobs, -1, 1)
  
  id &lt;- numeric(length(z1))
  
  x &lt;- runif(nobs, min = -1, max = 1)
  
  beta0 &lt;- delta * (-1)^(z1&lt;xi1) * 0^(z2&lt;xi2)
  beta1 &lt;- delta * (-1)^(z2&gt;=xi2)
  
  id &lt;- 1 + (z2&gt;=xi2) + (z2&gt;=xi2)*(z1&gt;=xi1)
  
  mu &lt;- beta0 + beta1 * x
  
  y &lt;- rnorm(nobs, mu, sigma)
  d &lt;- data.frame(y = y, x = x, 
                  z1 = z1, z2 = z2, z3 = z3, z4 = z4, z5 = z5, z6 = z6, z7 = z7, z8 = z8, z9 = z9, z10 = z10,
                  beta0 = beta0, beta1 = beta1, mu = mu, sigma = rep.int(sigma, times = length(y)), id = id)
  
  return(d)
}

</code></pre>
<h2>The <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">Adjusted Rand Index</a></h2>
<p>Among the functions included in the <a href="https://arxiv.org/abs/1906.10179" rel="nofollow noreferrer">article</a>, there is one to compute the <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a>, and it is listed below to be used in the following examples. It resembles almost exactly letter by letter the notation used <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">here</a>.</p>
<pre><code># function to compute adjusted Rand Index from https://arxiv.org/src/1906.10179v1/anc
adj_rand_index &lt;- function(x, y) {
  tab &lt;- table(x, y)
  a &lt;- rowSums(tab)
  b &lt;- colSums(tab)
  
  M &lt;- sum(choose(tab, 2))
  N &lt;- choose(length(x), 2)
  A &lt;- sum(choose(a, 2))
  B &lt;- sum(choose(b, 2))
  
  c(ARI = (M - (A * B) / N) / (0.5 * (A + B) - (A * B) / N))
}

</code></pre>
<h2>Simulating the data</h2>
<pre><code>library(partykit)
library(future.apply) ## for parallel stuff
plan(multisession)    ## use all available cores

ols_formula &lt;- y ~ x | z1 + z2 +z3 +z4 + z5 +z6 +z7+ z8 +z9 +z10
ols &lt;- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {lm(y ~ 0 + x)} 

sim_ari &lt;- function(n){
  tree_data  &lt;- dgp_tree(nobs = n)
  
  ols_mob    &lt;- mob(ols_formula,
                    data = tree_data,
                    fit = ols)
  
  prednode   &lt;- predict(ols_mob , 
                        type = &quot;node&quot;)
  
  cross_table &lt;- table(prednode,tree_data$id)
  ari         &lt;- adj_rand_index(prednode, 
                        tree_data$id)
  
  print(n)
  print(ari)
  return(
    list(
      ols_mob = ols_mob,
      cross_table = cross_table,
      ari=ari, 
      data = tree_data)
  )
}


n_levels &lt;- c(55,  ## no break
              87,  ## only one break
              123, ## Correct structure, but poor performance  
              199, ## Nested break in second leaf
              667, ## Additional break in first leaf
              5000 ## Perfect model
              )

ari &lt;- future_lapply(n_levels, sim_ari, future.seed = 1234L)

</code></pre>
<h1>A Tale of Six Trees.</h1>
<p>The following six cases are analyzed in terms of how the <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> can accurately capture the degree of similarity between the correct and the estimated tree. The key to compare the trees is <code>id</code>, which shows which leaf each observation should belong in the tree. For example, if an observation has an <code>id</code> value of <code>1</code>, it meets the requirements assigned to node number 2 in the figure above. On the other hand, if <code>id</code> is equal to 2, the observation should be assigned to node number 4 in the same picture. Finally, if <code>id</code> is equal to 3, it is assigned to node number 5. You can check this reasoning in the following line <code>id &lt;- 1 + (z2&gt;=xi2) + (z2&gt;=xi2)*(z1&gt;=xi1)</code></p>
<h3>The First Tree (n=55): No breaks</h3>
<p>The first case analyzed corresponds when no breaks are identified. Here, in this case, the ARI is equal to 0.</p>
<pre><code>##### First Tree (n=55): No break ####
ari[[1]][[1]]

## Fitted party:
##   [1] root: n = 55
## x(Intercept)           xx 
## -0.01309586   0.39291089  
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1
## Number of parameters per node: 2
## Objective function: 95.58631

</code></pre>
<p>Here it is interesting to note that all the observations are assigned to the root node. Therefore, when crosstable the predicted nodes <code>prednode_1</code>, we see that all possible <code>id</code> values belong to the root node <code>[1]</code> of the predicted tree (basically, because there is no other option.) By using the function <code>adj_rand_index()</code>, you can check that this leads to an ARI equal to 0.</p>
<pre><code>#data first tree (n=55)
data_1 &lt;- ari[[1]][[4]]
#predicted node first iteration
data_1$prednode_1     &lt;- predict(ari[[1]][[1]], type = &quot;node&quot;)
#Cross table
with(data_1, table(prednode_1  ,id))

##             id
## prednode_1  1   2  3
##          1  37  7 11

#adj_rand_index
ari[[1]][[3]]
</code></pre>
<h3>The second tree (n=87): Just one break identified</h3>
<p>This case is interesting because it partially identifies the tree's structure (i.e., the break on <code>z1</code> is missing).</p>
<pre><code>##### Second Tree (n=87): Extra partition in node[5] ####
ari[[2]][[1]]

# Fitted party:
#   [1] root
# |   [2] z2 &lt;= 0.29288: n = 57
# |       x(Intercept)           xx 
# |           0.133293     1.082701 
# |   [3] z2 &gt; 0.29288: n = 30
# |       x(Intercept)           xx 
# |          0.2598309   -1.8014133 
# 
# Number of inner nodes:    1
# Number of terminal nodes: 2
# Number of parameters per node: 2
# Objective function: 122.0116

</code></pre>
<p>Additionally, we can check that when crosstable the predicted and the real nodes, we see that some observations meet the criteria even in this non-perfect tree. Meaning there are <code>57</code> observations correctly assigned to the first node and <code>9</code> that were correctly assigned to the second branch. Finally, <code>30</code> where misassigned because the last node was not identified at all. This lead to an ARI equal to <code>0.8577366</code>, which is a huge improvement from the first tree.</p>
<pre><code>#data second iteration (n=87)
data_2 &lt;- ari[[2]][[4]]
#predicted node first iteration
data_2$prednode_2     &lt;- predict(ari[[2]][[1]], type = &quot;node&quot;)
#Cross table
with(data_2, table(prednode_2  ,id))
#             id
# prednode_2  1  2  3
#          2 57  0  0
#          3  1  9 20

#adj_rand_index
ari[[2]][[3]]

# &gt; ari[[2]][[3]]
#       ARI 
# 0.8577366
</code></pre>
<h3>The third tree (n=123): Correct structure but poor performance</h3>
<p>This case is interesting because it <strong>does</strong> recover the real tree structure, but it has worse performance than the last three that only partially identified its structure.</p>
<pre><code>##### Third Tree (n=123): Correct structure but poor performance ####
ari[[3]][[1]]
# Fitted party:
#   [1] root
# |   [2] z2 &lt;= 0.07319: n = 60
# |       x(Intercept)           xx 
# |         -0.1723388    1.1071878 
# |   [3] z2 &gt; 0.07319
# |   |   [4] z1 &lt;= -0.35485: n = 22
# |   |       x(Intercept)           xx 
# |   |         -0.7166565   -0.6791717 
# |   |   [5] z1 &gt; -0.35485: n = 41
# |   |       x(Intercept)           xx 
# |   |          0.7096033   -0.8605967 
# 
# Number of inner nodes:    2
# Number of terminal nodes: 3
# Number of parameters per node: 2
# Objective function: 156.4397

</code></pre>
<p>Below we can see that when we crosstable predicted and real nodes, we see that <code>16</code> (<code>10 + 6</code>) observations were incorrectly classified, and this fact leads to an ARI of <code>0.6117612</code>.</p>
<pre><code>#data third iteration (n=123)
data_3 &lt;- ari[[3]][[4]]
#predicted node first iteration
data_3$prednode_3     &lt;- predict(ari[[3]][[1]], type = &quot;node&quot;)
#Cross table
with(data_3, table(prednode_3  ,id))
# id
# prednode_3  1  2  3
#          2  60  0  0
#          4   6 16  0
#          5  10  0 31

#adj_rand_index
ari[[3]][[3]]
# &gt; ari[[3]][[3]]
#       ARI 
# 0.6117612

</code></pre>
<h3>The fourth Tree: Forth Tree (n=199): Extra leaf at node <code>[5]</code></h3>
<p>The tree identified here deviated from the original because it has an extra leaf from <code>node[5]</code>, which is unexisting in the real data.</p>
<pre><code>##### Forth Tree (n=199): Extra leaf at node[5] ####
ari[[4]][[1]]
# Fitted party:
#   [1] root
# |   [2] z2 &lt;= -0.19806: n = 79
# |       x(Intercept)           xx 
# |         0.06455217   1.51512672 
# |   [3] z2 &gt; -0.19806
# |   |   [4] z1 &lt;= -0.27127: n = 44
# |   |       x(Intercept)           xx 
# |   |         -0.4863122   -0.3860951 
# |   |   [5] z1 &gt; -0.27127
# |   |   |   [6] z2 &lt;= 0.17481: n = 23
# |   |   |       x(Intercept)           xx 
# |   |   |         -0.1335096    0.2046050 
# |   |   |   [7] z2 &gt; 0.17481: n = 53
# |   |   |       x(Intercept)           xx 
# |   |   |          1.0868488   -0.0290925 
# 
# Number of inner nodes:    3
# Number of terminal nodes: 4
# Number of parameters per node: 2
# Objective function: 282.6727

</code></pre>
<p>Here the count of the crosstable of the real and predicted nodes is interesting because nodes <code>[6]</code> and <code>[7]</code> are inexistent in the real data, but they are getting observations that should, for example, be assigned to the node <code>[1]</code> (<code>23</code> and <code>7</code> observations respectively.) This misallocation diminished the ARI index down to <code>0.4649789</code>.</p>
<pre><code>#data forth iteration (n=199)
data_4 &lt;- ari[[4]][[4]]
#predicted node first iteration
data_4$prednode_4     &lt;- predict(ari[[4]][[1]], type = &quot;node&quot;)
#Cross table
with(data_4, table(prednode_4  ,id))
#             id
# prednode_4  1  2  3
#          2 79  0  0
#          4 16 27  1
#          6 23  0  0
#          7  7  0 46
#adj_rand_index
ari[[4]][[3]]
#     ARI 
# 0.4649789 

</code></pre>
<h3>The fifth Tree (n=667): Extra leaf at node <code>[2]</code></h3>
<p>This is another example of a tree with an incorrect structure where an extra leaf (based on a partition on <code>z5</code> which is incorrect(!)) is attached to the node <code>[2]</code>.</p>
<pre><code>##### Fifth Tree (n=667): Extra leaf at node[2] ####
ari[[5]][[1]]
# Fitted party:
#   [1] root
# |   [2] z2 &lt;= 0.28476
# |   |   [3] z5 &lt;= 0.76285: n = 322
# |   |       x(Intercept)           xx 
# |   |         -0.1322881    0.9535337 
# |   |   [4] z5 &gt; 0.76285: n = 96
# |   |       x(Intercept)           xx 
# |   |          0.1686863    1.3878776 
# |   [5] z2 &gt; 0.28476
# |   |   [6] z1 &lt;= -0.32001: n = 89
# |   |       x(Intercept)           xx 
# |   |         -0.9139858   -0.7957158 
# |   |   [7] z1 &gt; -0.32001: n = 160
# |   |       x(Intercept)           xx 
# |   |          0.7661154   -0.8656553 
# 
# Number of inner nodes:    3
# Number of terminal nodes: 4
# Number of parameters per node: 2
# Objective function: 927.9088
</code></pre>
<p>The crosstable from predicted and correct nodes shows us that most of the observations (<code>322</code>) that, in reality, belong to the first node <code>[1]</code> were assigned to the predicted node <code>[3]</code>. Finally, this poor structure leads to an ARI of <code>0.6932132</code>.`</p>
<pre><code>#data third iteration (n=667)
data_5 &lt;- ari[[5]][[4]]
#predicted node first iteration
data_5$prednode_5     &lt;- predict(ari[[5]][[1]], type = &quot;node&quot;)
#Cross table
with(data_5, table(prednode_5  ,id))
#              id
# prednode_5   1   2   3
#          3 322   0   0
#          4  96   0   0
#          6   0  89   0
#          7   3   3 154

#adj_rand_index
ari[[5]][[3]]
#     ARI 
# 0.6932132 
</code></pre>
<h3>The sixth tree (n=5000): The Golden Tree!</h3>
<p>This final tree recovers the data perfectly, both in the tree structure and in allocating the observation to each leaf.</p>
<pre><code>##### Sixth Tree (n=5000): Extra leaf at node[2] ####
ari[[6]][[1]]
# Fitted party:
#   [1] root
# |   [2] z2 &lt;= 0.29971: n = 3187
# |       x(Intercept)           xx 
# |       -0.008719923  1.022232280 
# |   [3] z2 &gt; 0.29971
# |   |   [4] z1 &lt;= -0.30286: n = 609
# |   |       x(Intercept)           xx 
# |   |         -0.9488846   -0.9813765 
# |   |   [5] z1 &gt; -0.30286: n = 1204
# |   |       x(Intercept)           xx 
# |   |          1.0281410   -0.9565637 
# 
# Number of inner nodes:    2
# Number of terminal nodes: 3
# Number of parameters per node: 2
# Objective function: 6992.848
</code></pre>
<p>Here we can see from the crosstable of the predicted and real nodes that it allocates <em>perfectly</em> each observation where it does belong, leading to an ARI equal to <code>1</code>.</p>
<pre><code>#data sixt iteration (n=5000)
data_6 &lt;- ari[[6]][[4]]
#predicted node first iteration
data_6$prednode_6     &lt;- predict(ari[[6]][[1]], type = &quot;node&quot;)
#Cross table
with(data_6, table(prednode_6  ,id))
#               id
# prednode_6    1    2    3
#          2 3187    0    0
#          4    0  609    0
#          5    0    0 1204

#adj_rand_index
ari[[6]][[3]]
# ARI 
#  1 
</code></pre>
<h3>The conclusions.</h3>
<p>Some important takeaways can be recovered from the illustration above.</p>
<p>1.- The <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> is useful to assess the degree of similarity of a predicted tree that can have a very different structure from the real tree in the data generating process.</p>
<p>2.- Recover the tree's correct structure does not lead to an <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> equal to one.</p>
<p>3.- Incorrect trees not necessarily will an <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> equal to zero.</p>
<h3>A final Simulation.</h3>
<p>To conclude, here is a small simulation to see how the <a href="https://en.wikipedia.org/wiki/Rand_index" rel="nofollow noreferrer">ARI</a> index behaves when the sample size increases.</p>
<pre><code>
### Final simulation 
n_levels &lt;-seq(from= 10, to= 2000, by= 5)

ari  &lt;- lapply(n_levels, sim_ari)

ari_models&lt;- function(i){
  ari  &lt;- ari_sim[[i]]$ari
  n    &lt;- nobs(ari_sim[[i]]$ols_mob)  
  return(
    list(ari = ari , n= n )
  )
}


ari_n_list &lt;- lapply(1:length(ari_sim), ari_models)
df &lt;- data.frame(matrix(unlist(ari_n_list), nrow=length(ari_n_list), byrow=T))

colnames(df) &lt;- c(&quot;ARI&quot; , &quot;N&quot;)

library(ggplot2)
ggplot(df, aes(N)) + 
  geom_line(aes(y = ARI, colour = &quot;ARI&quot;)) 

</code></pre>
<p><a href="https://i.stack.imgur.com/6pClY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6pClY.png" alt="enter image description here" /></a></p>
Montecarlo Simulation using mob() algorithm (partykit package) to recover the count of the correctly identified models
<p>I am using the <code>mob()</code> function from <code>partykit</code> package and I am getting some problems when parsing the obtained model.</p>
<p>My main aim is to check <em>approximately</em> how large a sample size needs to be in order to detect the real
structure of a data generating process (DGP) when breaks are present.</p>
<p>The code below performs a Montecarlo simulation of data with breaks and tries to identify if the break was captured by the M-fluctuation test or not.</p>
<p>More specifically, I want to make a count on the number of times over the total number of simulations (<code>nreps</code>) that the model actually captures the DGP, conditional on a fixed sample size (<code>N</code>) to get a feeling of how many data should I need to capture the real DGP.</p>
<p>At the end of the code, you can see the list that I get out of my simulations. The problem is that I cannot recover the information displayed on the console.</p>
<p>Additionally, I have some doubts about how to make the count of the &quot;correctly identified models&quot;. For now, what I have in mind is to count as positive if the model has a break into the correct variable (<code>z1</code>) at the specified region (<code>z1&gt;0</code>) with some tolerance into the break region for example if the break is at <code>z1&gt;0.1</code> or <code>z1&gt;-0.4</code> it is also valid as a positive for me. Therefore, is there any simple way of counting the models that have the stated characteristics?</p>
<p>I hope my example is clear enough for you to help me out. Thank you a lot in advance.</p>
<h3>Simulate model</h3>
<ol>
<li>Ingredients to generate the DGP.</li>
</ol>
<pre><code>library(&quot;partykit&quot;)
library(data.table)   ## optional, but what I'll use to coerce the list into a DT
library(future.apply) ## for parallel stuff
plan(multisession)    ## use all available cores

#sample size
N &lt;- 300
#coeficients
betas &lt;- list()

betas$b0 &lt;- 1

betas$b1_up   &lt;- 2.4
betas$b1_down &lt;- 2

betas$b2_up   &lt;- 2.4
betas$b2_down &lt;- 2

#mob() ingredients
ols_formula &lt;- y ~ x1 + x2 | z1 + z2
# the &quot;&quot;0 +&quot;&quot; ---&gt;  supress the 'double' interecept
ols &lt;- function(y, x, start = NULL, weights = NULL, offset = NULL, ...) {lm(y ~ 0 + x)} 
</code></pre>
<ol start="2">
<li>Function that generates the data and fit OLS using mob algorithm.</li>
</ol>
<pre><code>reg_simulation_mob &lt;- function(...){
  #data
  data &lt;- data.frame(
    x1 = rnorm(N),
    x2 = rnorm(N),
    z1 = rnorm(N),
    z2 = rnorm(N),
    e  = rnorm(N))
  
  #dependent variable
  data$y &lt;-   betas$b0 + with(data,  ifelse(z1&gt;0,
                         betas$b1_up   * x1 + betas$b2_up   * x2 ,
                         betas$b1_down * x1 + betas$b2_down * x2 ) 
                        + e )
  
  
    #Estimate mob()-OLS
  ols_mob &lt;- mob(ols_formula,
                 data = data, 
                 fit = ols)
  
  # return(ols$coefficients)
  return(ols_mob)
}
</code></pre>
<ol start="3">
<li>Montecarlo simulation (only 2 trials) of the above-described setup.</li>
</ol>
<pre><code># N repetitions
nreps &lt;- 2

## Parallel version
results  &lt;- future_lapply(1:nreps, reg_simulation_mob, future.seed = 1234L)

</code></pre>
<h3>Obtained result</h3>
<p>As you can see below in the first trial (<code>results[[1]]</code>), the model finds the correct break but in the second (<code>results[[2]]</code>) it fails to find it.</p>
<pre><code>&gt; results
[[1]]
Model-based recursive partitioning (ols)

Model formula:
y ~ x1 + x2 | z1 + z2

Fitted party:
[1] root
|   [2] z1 &lt;= 0.00029: n = 140
|       x(Intercept)          xx1          xx2 
|          0.9597894    1.7552122    2.1360788 
|   [3] z1 &gt; 0.00029: n = 160
|       x(Intercept)          xx1          xx2 
|          0.9371795    2.4745728    2.5087608 

Number of inner nodes:    1
Number of terminal nodes: 2
Number of parameters per node: 3
Objective function: 422.2329

[[2]]
Model-based recursive partitioning (ols)

Model formula:
y ~ x1 + x2 | z1 + z2

Fitted party:
[1] root: n = 300
    x(Intercept)          xx1          xx2 
        1.015224     2.175625     2.200746  

Number of inner nodes:    0
Number of terminal nodes: 1
Number of parameters per node: 3
Objective function: 422.3085

</code></pre>
<p>In the picture below, you can observe the structure of the list <code>results</code>, where I cannot find the information displayed on the console (i.e. number of nodes, parameters, threshold values, etc..)
<a href="https://i.stack.imgur.com/lhz7Q.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lhz7Q.png" alt="enter image description here" /></a></p>