A step-by-step walkthrough of how a decision tree chooses where to split a node. Un recorrido paso a paso de cómo un árbol de decisión elige dónde dividir un nodo.
A tiny vocabulary, to make the rest of the page readable. Everything else is built from these.
We will build everything else (RSS, greedy, the algorithm) from scratch in the panels below.
Un vocabulario breve, para que el resto de la página se lea con soltura. Todo lo demás se construye a partir de estas ideas.
El resto (RSS, la idea de voraz, el algoritmo completo) lo iremos construyendo desde cero en los paneles siguientes.
Here is the full tree we will build on the 5-point dataset, for reference. Most of this page is about one choice: the threshold at the root (the “?”).
The whole page is about choosing the value of s at one node, the root. After we pick it, each child runs the exact same procedure on its own data. That is how the tree grows.
Aquí está, para tenerlo a la vista, el árbol completo que construiremos sobre el conjunto de 5 puntos. Casi toda la página gira en torno a una sola elección: el umbral en la raíz (el “?”).
Toda la página trata de elegir el valor de s en un solo nodo, la raíz. Una vez elegido, cada hijo ejecuta exactamente el mismo procedimiento con sus propios datos. Así crece el árbol.
A decision tree predicts a number y from a number x. It does this by cutting the data into groups and assigning a single prediction to each group: the group's average y.
The cut is made one question at a time: “is x ≤ s?”. Observations that answer yes go into one group, the rest into the other. Each group can be cut again by the same kind of question, and again, until we stop.
Every cut needs a threshold, a specific number s. This page answers exactly one question: given 5 data points, which s is best, and why?
The plan is honest brute force. List every threshold worth trying. For each one, split the data and score how tightly the two resulting groups cluster around their own averages. Keep the threshold with the best score.
Un árbol de decisión predice un número y a partir de un número x. Lo hace cortando los datos en grupos y asignándole a cada grupo una sola predicción: el promedio de y dentro de ese grupo.
El corte se hace una pregunta a la vez: “¿es x ≤ s?”. Las observaciones que responden sí se van a un grupo, y el resto al otro. Cada grupo puede volver a cortarse con una pregunta del mismo tipo, y otra vez, hasta que nos detengamos.
Cada corte necesita un umbral, un número concreto s. Esta página contesta una única pregunta: dados 5 puntos, ¿cuál es la mejor s, y por qué?
El plan es fuerza bruta, sin disimulos. Enumerar todos los umbrales que valga la pena probar. Para cada uno, dividir los datos y medir qué tan apretados quedan los dos grupos alrededor de su propio promedio. Quedarse con el umbral de mejor puntaje.
Five (x, y) observations, one feature. Notice that the x values themselves form two clumps, {1, 2, 3} and {7, 8}, with a wide gap in between, and the y values grow with x. You can see the clumps on the scatter plot further down the page.
Before any split, our best single prediction for the node is = 14. The Parent RSS (490) is the total squared error we pay for using that one number. Splitting should shrink this number.
Cinco observaciones (x, y), una sola variable. Fíjese en que los valores de x forman dos cúmulos, {1, 2, 3} y {7, 8}, con un hueco ancho entre ambos, y que los valores de y crecen con x. Los cúmulos se aprecian en el diagrama de dispersión que aparece más adelante.
Antes de cualquier división, la mejor predicción única para el nodo es = 14. El RSS del padre (490) es el error cuadrático total que pagamos por usar ese solo número. La división debería achicar esa cifra.
A threshold is just a number. In principle we could try infinitely many. Why only four?
Because between any two consecutive x-values, the split is identical. Any s in the open interval (3, 7), whether 3.1, 5, or 6.999, puts {1, 2, 3} on the left and {7, 8} on the right. Same groups, same RSS. So we only need one threshold per gap.
The standard convention is the midpoint of the gap. Sorted unique x values are 1, 2, 3, 7, 8. Four gaps, four midpoints:
With n unique x values there are n − 1 candidate thresholds. The algorithm tries every one of them.
Un umbral no es más que un número. En principio podríamos probar una infinidad. ¿Por qué nada más cuatro?
Porque entre dos valores consecutivos de x, la división es siempre la misma. Cualquier s en el intervalo abierto (3, 7), ya sea 3.1, 5 o 6.999, deja {1, 2, 3} a la izquierda y {7, 8} a la derecha. Mismos grupos, mismo RSS. Basta, entonces, con un umbral por cada hueco.
La convención habitual es tomar el punto medio del hueco. Los valores únicos de x, ordenados, son 1, 2, 3, 7, 8. Cuatro huecos, cuatro puntos medios:
Con n valores únicos de x hay n − 1 umbrales candidatos. El algoritmo los prueba todos.
RSS stands for Residual Sum of Squares. For a group of y-values with mean :
In words: pick the mean as the group’s representative, measure how far each member is from that mean, square those distances, add them up.
When we split, we want each child to be as pure as possible, which means both RSSL and RSSR should be small. So we minimize their sum: RSSL + RSSR.
Why squared, not absolute? Because squaring is the partner of the mean. If we pick a single number c to represent a group of y-values and score it by Σ (yi − c)², then setting the derivative to zero gives −2 Σ (yi − c) = 0, i.e. c = . So: minimize sum of squares → best summary is the mean. The two choices are locked together. (If we minimized Σ |yi − c| instead, the best c would be the median, and that would give a different kind of tree.)
RSS viene del inglés Residual Sum of Squares, la suma de cuadrados residuales. Para un grupo de valores de y con media :
En palabras: se toma la media como representante del grupo, se mide qué tan lejos queda cada miembro de esa media, se elevan esas distancias al cuadrado y se suman.
Al dividir queremos que cada hijo sea lo más puro posible, lo que equivale a que tanto RSSL como RSSR sean chicos. Por eso minimizamos su suma: RSSL + RSSR.
¿Por qué al cuadrado y no el valor absoluto? Porque elevar al cuadrado y la media van de la mano. Si elegimos un solo número c para representar al grupo y lo puntuamos con Σ (yi − c)², al derivar e igualar a cero queda −2 Σ (yi − c) = 0, es decir, c = . Así que: minimizar la suma de cuadrados → el mejor resumen es la media. Las dos decisiones están amarradas. (Si en cambio minimizáramos Σ |yi − c|, la mejor c sería la mediana, y eso daría un árbol distinto.)
Now that we have the words (threshold, split, RSS) we can write the whole procedure down:
With p features instead of one, step 1 also loops over j = 1, …, p, and the winner is the pair (j*, s*). Here p = 1, so we can ignore j.
Con el vocabulario listo (umbral, división, RSS) podemos escribir todo el procedimiento:
Con p variables en lugar de una, el paso 1 también recorre j = 1, …, p, y el ganador es la pareja (j*, s*). Aquí p = 1, así que podemos olvidarnos de j.
To see what the algorithm actually does, we compute every number by hand. For each threshold: form the two groups, take each group’s mean, compute each group’s RSS, add them.
Move the threshold one gap to the right. Now the left group gains a point and the right loses one.
Jump across the big gap in x. Both groups are now tightly clustered.
Push the threshold too far right. The left group is forced to mix small and large y-values again.
Para ver qué hace realmente el algoritmo, calculamos todo a mano. Para cada umbral: armamos los dos grupos, sacamos la media de cada uno, calculamos su RSS y los sumamos.
Recorremos el umbral un hueco a la derecha. Ahora el grupo de la izquierda gana un punto y el de la derecha pierde uno.
Saltamos el hueco grande en x. Los dos grupos quedan ahora bien apretados.
Empujamos el umbral demasiado a la derecha. El grupo de la izquierda se ve obligado a mezclar valores chicos y grandes de y otra vez.
Stack the four post-split RSS values next to each other:
The winner is s* = 5. The total squared error drops from 490 at the parent down to 10 after the split, a reduction of about 98%. In plain language: nearly all of the spread that the single parent mean failed to capture is explained once we let each side of the split use its own mean.
The algorithm never “sees” the visible gap between x = 3 and x = 7. It only compares four numbers. But those four numbers tell the same story the eye does: the cleanest split is the one that respects where the data already clumps.
Pongamos los cuatro valores de RSS (tras la división) uno al lado del otro:
El ganador es s* = 5. El error cuadrático total cae de 490 en el padre a 10 tras la división, una reducción cercana al 98%. Dicho en palabras llanas: casi toda la dispersión que la media única del padre no alcanzaba a explicar queda explicada en cuanto dejamos que cada lado de la división use su propia media.
El algoritmo nunca “ve” el hueco visible entre x = 3 y x = 7. Solo compara cuatro números. Y sin embargo, esos cuatro números cuentan la misma historia que cuenta el ojo: la división más limpia es la que respeta el lugar donde los datos ya se agrupan por su cuenta.
Press Play to watch the algorithm step through the four candidates in order. Or drag the slider to move the threshold freely. Points recolor into the left or right group, each group's mean redraws as a dashed line, and the numbers below update live.
Oprima Reproducir para ver cómo el algoritmo recorre los cuatro candidatos en orden. O arrastre el deslizador para mover el umbral libremente. Los puntos cambian de color según caigan en el grupo izquierdo o derecho, la media de cada grupo se redibuja como línea punteada, y los números de abajo se actualizan en vivo.
| threshold sumbral s | Left yy de la izquierda | Right yy de la derecha | RSSL | RSSR | Post-split RSSRSS tras la división |
|---|
Each horizontal step is one of the four candidate thresholds. The step is flat because any s inside a single gap between two x values produces the same split: the same two groups, and therefore the same RSS. The step drops and rises as the threshold crosses data points. The lowest step is the winner. Toggle to Advanced mode to see a denser version of the same picture, a V-shape whose trough points at where the data naturally separates.Cada escalón horizontal es uno de los cuatro umbrales candidatos. El escalón sale plano porque cualquier s dentro de un mismo hueco entre dos valores de x produce la misma división: los mismos dos grupos y, por lo tanto, el mismo RSS. El escalón baja o sube conforme el umbral cruza puntos. El escalón más bajo es el ganador. Cambie al modo avanzado para ver una versión más densa del mismo dibujo, una forma de V cuyo fondo apunta justo al lugar donde los datos se separan de manera natural.
We have picked s* = 5 at the root. The root is done. Each child now becomes a new node with its own data, and the same procedure runs on it from scratch:
Each child picks its own s*, splits, and its grand-children repeat the procedure. A stopping rule (typically a minimum node size or a maximum depth) decides when a node becomes a leaf instead of splitting again.
Nothing on this page changes for the children. The recipe (enumerate midpoints, compute RSS for each split, pick the smallest) is what the tree runs at every node.
Ya elegimos s* = 5 en la raíz. La raíz queda lista. Cada hijo se vuelve ahora un nodo nuevo con sus propios datos, y el mismo procedimiento corre sobre él desde cero:
Cada hijo elige su propia s*, se divide, y sus nietos repiten el procedimiento. Una regla de paro (por lo general un tamaño mínimo de nodo o una profundidad máxima) decide cuándo un nodo se convierte en hoja en lugar de volver a partirse.
Nada de lo que vimos en esta página cambia para los hijos. La receta (enumerar los puntos medios, calcular el RSS de cada división, quedarse con el más chico) es lo que el árbol ejecuta en cada nodo.
We just ran the search for one node. Once we commit to s* = 5, the two children become new nodes: {4, 6, 8} on the left and {25, 27} on the right. Each child runs the same exhaustive search, using only its own data. The tree grows one node at a time.
The algorithm never looks ahead. It does not ask “would a slightly worse split now lead to cleaner splits later?”. It just picks the best s for the node in front of it. That is the meaning of greedy: locally optimal, globally unverified.
This is sometimes suboptimal. A root split that scores slightly worse could unlock much cleaner child splits later. But searching every possible whole tree is computationally intractable (the number of candidate trees explodes very quickly), so in practice we accept the greedy approximation, and empirically it performs well enough to be the standard recipe.
Acabamos de correr la búsqueda para un solo nodo. Una vez que nos comprometemos con s* = 5, los dos hijos se vuelven nodos nuevos: {4, 6, 8} a la izquierda y {25, 27} a la derecha. Cada hijo corre la misma búsqueda exhaustiva, usando solo sus propios datos. El árbol crece nodo a nodo.
El algoritmo nunca se asoma hacia adelante. No se pregunta “¿una división un poco peor ahora me daría divisiones más limpias después?”. Simplemente elige la mejor s para el nodo que tiene enfrente. En eso consiste ser voraz: óptimo en lo local, sin garantía de ser óptimo en lo global.
A veces esto sale subóptimo. Una división raíz que puntúe algo peor podría destrabar divisiones mucho más limpias después. Pero buscar entre todos los árboles completos posibles es computacionalmente inalcanzable (la cantidad de árboles candidatos explota rapidísimo), así que en la práctica aceptamos la aproximación voraz, y en los hechos rinde lo suficiente como para ser la receta estándar.
Everything on this page used one feature. Real datasets have many. A mortality table carries age, sex, policy year, duration, smoker status, geography. A claims-severity model can easily have dozens of predictors. How does the algorithm change when p > 1?
Very little, in fact. With p features x1, x2, …, xp, the inner loop of step 1 now runs over both the feature index j and the threshold s:
At each node the tree asks one question: “out of all possible splits on any feature, which one purifies the children most?” The winner might be age at the root, policy duration at the left child, smoker status four levels down. Every node picks its own feature-threshold pair from its own data.
One tree is noisy. Small changes in the training data can swing the root split, which cascades into very different leaves. The fix, once computers got fast enough to afford it, is to build many trees and average them.
A Random Forest does two things to make the trees differ from each other:
Hundreds of such trees are built. A new observation gets a prediction from each one, and the forest's answer is the average (for regression) or the majority vote (for classification). The two layers of randomization make the trees weakly correlated, so averaging them shrinks variance without raising bias much.
Boosting is the other common extension. Trees are grown sequentially, each one fitting the residuals the previous trees missed. Gradient boosting (XGBoost, LightGBM) is what dominates on tabular data today.
All of these methods inherit the same split-search recipe we built on this page. The greedy choice at one node, with RSS as the score, is the building block every tree-based method is constructed from. Everything else is extra machinery on top.
Todo lo que vimos usó una sola variable. Los conjuntos de datos reales tienen muchas. Una tabla de mortalidad carga edad, sexo, año de póliza, duración, condición de fumador y región geográfica. Un modelo de severidad de siniestros puede fácilmente arrastrar decenas de variables predictoras. ¿Cómo cambia el algoritmo cuando p > 1?
Poco, en realidad. Con p variables x1, x2, …, xp, el ciclo interno del paso 1 ahora recorre tanto el índice de variable j como el umbral s:
En cada nodo el árbol hace una sola pregunta: “entre todas las divisiones posibles, sobre cualquier variable, ¿cuál purifica más a los hijos?”. El ganador puede ser la edad en la raíz, la duración de la póliza en el hijo izquierdo, la condición de fumador cuatro niveles más abajo. Cada nodo elige su propia pareja variable-umbral a partir de sus propios datos.
Un solo árbol es ruidoso. Cambios chicos en los datos de entrenamiento pueden mover la división de la raíz, y eso se propaga en cascada hasta producir hojas muy distintas. La solución, una vez que las computadoras fueron lo bastante rápidas como para permitírselo, es construir muchos árboles y promediarlos.
Un bosque aleatorio (Random Forest) hace dos cosas para que los árboles se diferencien entre sí:
Se construyen cientos de árboles así. Una observación nueva recibe una predicción de cada uno, y la respuesta del bosque es el promedio (en regresión) o el voto mayoritario (en clasificación). Las dos capas de aleatorización hacen que los árboles queden débilmente correlacionados, de modo que al promediarlos se reduce la varianza sin aumentar mucho el sesgo.
El boosting es la otra extensión común. Los árboles se construyen en secuencia: cada uno ajusta los residuales que dejaron los árboles anteriores. El gradient boosting (XGBoost, LightGBM) es hoy lo que domina sobre datos tabulares.
Todos estos métodos heredan la misma receta de búsqueda de divisiones que armamos en esta página. La elección voraz en un nodo, con el RSS como criterio, es la pieza básica con la que se construye cualquier método basado en árboles. El resto es maquinaria extra montada encima.