From a67f9113e6bfb23c6fb236169dd7db9aee737e33 Mon Sep 17 00:00:00 2001 From: Jose Mora <109150320+josemoracard@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:43:43 +0200 Subject: [PATCH 1/3] Update decision-trees.md --- 06-ml_algos/decision-trees.md | 52 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/06-ml_algos/decision-trees.md b/06-ml_algos/decision-trees.md index ced8d92..02e8425 100644 --- a/06-ml_algos/decision-trees.md +++ b/06-ml_algos/decision-trees.md @@ -1,14 +1,14 @@ ## Decision trees -A **decision tree** is a model widely used in Machine Learning to solve both regression and classification problems. It is a graphical model that mimics human decision making, i.e. it is based on a series of questions to reach a conclusion. +A **decision tree** is a model widely used in Machine Learning to solve both regression and classification problems. It is a graphical model that mimics human decision making, i.e., it is based on a series of questions to reach a conclusion. The main idea behind decision trees is to divide data into smaller and smaller groups (called nodes) based on different criteria until a final result or decision is reached. These criteria are selected in such a way that the elements of each node are as similar as possible to each other. ### Structure -The structure of a decision tree resembles that of an inverted tree. It starts with a node called **root node** that contains all the data. This node is split into two or more child nodes based on some criterion. These are the **decision nodes**. This process is repeated for each child node, creating what are called **branches**, until a node is reached that is no longer split. These final nodes are called **leaf nodes** and represent the final decision or prediction of the tree. +The structure of a decision tree resembles that of an inverted tree. It starts with a node called **root node**, which contains all the data. This node is split into two or more child nodes based on some criterion. These are the **decision nodes**. This process is repeated for each child node, creating what are called **branches**, until a node is reached that is no longer split. These final nodes are called **leaf nodes** and represent the final decision or prediction of the tree. -![decision_tree_structure](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/decision_tree_structure.jpg?raw=true) +![Decision tree structure](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/decision_tree_structure.jpg?raw=true) An important aspect of decision trees is that they are very interpretable models. You can visualize the entire tree and follow the decisions it makes, which is not possible in many other types of models. However, they can be prone to overfitting, especially if the tree is allowed to grow too large. @@ -16,51 +16,51 @@ An important aspect of decision trees is that they are very interpretable models Let's imagine we are building a decision tree to decide whether we should play soccer based on weather conditions. We have the following data (in spanish): -| Clima | Viento | ¿Jugar al fútbol? | -|-------|--------|-------------------| -| Soleado | Fuerte | No | -| Lluvioso | Débil | Sí | -| Soleado | Débil | Sí | -| Lluvioso | Fuerte | No | +| Weather | Wind | Play Soccer? | +|---------|------|-----------------| +| Sunny | Strong | No | +| Rainy | Weak | Yes | +| Sunny | Weak | Yes | +| Rainy | Strong | No | -We start with a single node containing all the data. We need to decide what our first splitting criterion will be, i.e., which of the two features (`Clima` or `Viento`) we should use to split the data. This criterion is usually decided based on the **purity** of the resulting nodes. For a classification problem, a node is pure if all its data belong to the same class. In a regression problem, a node is pure if all the data of that node have the same value for the target variable. +We start with a single node containing all the data. We need to decide what our first splitting criterion will be, i.e., which of the two features (`Weather` or `Wind`) we should use to split the data. This criterion is usually decided based on the **purity** of the resulting nodes. For a classification problem, a node is pure if all its data belong to the same class. In a regression problem, a node is pure if all the data of that node have the same value for the target variable. The purpose of splits in a decision tree is to increase the purity of the child nodes. For example, if you have a node that contains spam and non-spam email data, you could split it based on whether the email contains the word "win". This could increase the purity if it turns out that most of the emails that contain the word "win" are spam and most of the emails that do not contain the word "win" are non-spam. -In this case, for simplicity, suppose we decide to divide by `Clima` first. Then, we split the data into two child nodes: one for sunny days and one for rainy days: +In this case, for simplicity, suppose we decide to divide by `Weather` first. Then, we split the data into two child nodes: one for sunny days and one for rainy days: -![decision_tree_structure](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/starting_tree.png?raw=true) +![Decision tree soccer example part 1](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/starting_tree.png?raw=true) Now we have two child nodes, each with a part of the data: -- In the "Soleado" (sunny) node, we have the following data: +- In the "Sunny" node, we have the following data: -| Clima | Viento | ¿Jugar al fútbol? | -|-------|--------|-------------------| -| Soleado | Fuerte | No | -| Soleado | Débil | Sí | +| Weather | Wind | Play Soccer? | +|---------|------|-----------------| +| Sunny | Strong | No | +| Sunny | Weak | Yes | -- In the "Lluvioso" (rainy) node, we have the following data: +- In the "Rainy" node, we have the following data: -| Clima | Viento | ¿Jugar al fútbol? | -|-------|--------|-------------------| -| Lluvioso | Débil | Sí | -| Lluvioso | Fuerte | No | +| Weather | Wind | Play Soccer? | +|---------|------|-----------------| +| Rainy | Weak | Yes | +| Rainy | Strong | No | Each of these child nodes is divided again, this time according to wind speed: -![derivated_tree](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/derivated_tree.png?raw=true) +![Decision tree soccer example part 2](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/derivated_tree.png?raw=true) Now, each of the child nodes (which are now leaf nodes, since they will not be split anymore because they are pure) represents a final decision based on the weather conditions. For example, if the weather is sunny and the wind is weak, the decision is to play soccer. ### Model hyperparameterization -We can easily build a decision tree in Python using the `scikit-learn` library and the `DecisionTreeClassifier` and `DecisionTreeRegressor` functions. Some of its most important hyperparameters and the first ones we should focus on are: +We can easily build a decision tree in Python using the `scikit-learn` library and the `DecisionTreeClassifier` and `DecisionTreeRegressor` functions. Some of its most important hyperparameters, and the first ones we should focus on are: - `max_depth`: The maximum depth of the tree. This limits how many splits it can have, which is useful to prevent overfitting. If this value is `None`, then nodes are expanded until leaves are pure or until all leaves contain fewer samples than `min_samples_split`. - `min_samples_split`: The minimum number of samples needed to split a node. If a node has less samples than `min_samples_split`, then it will not be split, even if it is not pure. Helps prevent overfitting. - `min_samples_leaf`: The minimum number of samples that must be in a leaf node. A node will split if doing so creates at least `min_samples_leaf` samples in each of the children. This also helps to prevent overfitting. - `max_features`: The maximum number of features to consider when looking for the best split. If `max_features` is `None`, then all features will be considered. Reducing this number may make the model simpler and faster to train, but may also cause it to miss some important relationships. -- Criterion: The function to measure the quality of a split. Depending on the nature of the tree (sort or return), the options vary. This hyperparameter is in charge of choosing which variable to branch. +- `criterion`: The function to measure the quality of a split. Depending on the nature of the tree (sort or return), the options vary. This hyperparameter is in charge of choosing which variable to branch. -Another very important hyperparameter is the `random_state`, which controls the random generation seed. This attribute is crucial to ensure replicability. \ No newline at end of file +Another very important hyperparameter is the `random_state`, which controls the random generation seed. This attribute is crucial to ensuring replicability. From 37bf7c29826ac339785b56f3ad25c56c11908c4c Mon Sep 17 00:00:00 2001 From: Jose Mora <109150320+josemoracard@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:12:47 +0200 Subject: [PATCH 2/3] Update decision-trees.es.md --- 06-ml_algos/decision-trees.es.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/06-ml_algos/decision-trees.es.md b/06-ml_algos/decision-trees.es.md index a4d53bb..aff8df8 100644 --- a/06-ml_algos/decision-trees.es.md +++ b/06-ml_algos/decision-trees.es.md @@ -2,13 +2,13 @@ Un **árbol de decisión** (*decision tree*) es un modelo ampliamente utilizado en Machine Learning y que permite resolver problemas tanto de regresión como de clasificación. Es un modelo gráfico que imita la toma de decisiones humanas, es decir, se basa en una serie de preguntas para llegar a una conclusión. -La idea principal detrás de los árboles de decisión es dividir los datos en grupos cada vez más pequeños (llamados nodos) basándose en diferentes criterios hasta llegar a un resultado o decisión final. Estos criterios se seleccionan de tal manera que los elementos de cada nodo sean lo más similares posibles entre sí. +La idea principal detrás de los árboles de decisión es dividir los datos en grupos cada vez más pequeños (llamados nodos) basándose en diferentes criterios hasta llegar a un resultado o decisión final. Estos criterios se seleccionan de tal manera que los elementos de cada nodo sean lo más similares posible entre sí. ### Estructura -La estructura de un árbol de decisión se asemeja a la de un árbol invertido. Comienza con un nodo llamado **nodo raíz** (*root node*) que contiene todos los datos. Este nodo se divide en dos o más nodos hijos basándose en algún criterio. Son los **nodos de decisión** (*decision node*). Este proceso se repite en cada nodo hijo, creando lo que se llaman **ramas** (*branches*), hasta que se llega a un nodo que no se divide más. Estos nodos finales se llaman **nodos hoja** (*leaf nodes*) y represen tan la decisión final o la predicción del árbol. +La estructura de un árbol de decisión se asemeja a la de un árbol invertido. Comienza con un nodo llamado **nodo raíz** (*root node*) que contiene todos los datos. Este nodo se divide en dos o más nodos hijos basándose en algún criterio. Son los **nodos de decisión** (*decision node*). Este proceso se repite en cada nodo hijo, creando lo que se llaman **ramas** (*branches*), hasta que se llega a un nodo que no se divide más. Estos nodos finales se llaman **nodos hoja** (*leaf nodes*) y representan la decisión final o la predicción del árbol. -![decision_tree_structure](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/decision_tree_structure.jpg?raw=true) +![Estructura de un árbol de decisión](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/decision_tree_structure.jpg?raw=true) Un aspecto importante de los árboles de decisión es que son modelos muy interpretables. Puedes visualizar el árbol completo y seguir las decisiones que toma, lo cual no es posible en muchos otros tipos de modelos. Sin embargo, pueden ser propensos al sobreajuste, especialmente si el árbol se deja crecer demasiado. @@ -25,11 +25,11 @@ Imaginemos que estamos construyendo un árbol de decisión para decidir si debem Empezamos con un único nodo que contiene todos los datos. Necesitamos decidir cuál será nuestro primer criterio de división, es decir, cuál de las dos características (`Clima` o `Viento`) deberíamos usar para dividir los datos. Este criterio se decide generalmente basándose en la **pureza** de los nodos resultantes. Para un problema de clasificación, un nodo es puro si todos sus datos pertenecen a la misma clase. En un problema de regresión, un nodo es puro si todos los datos de ese nodo tienen el mismo valor para la variable objetivo. -El objetivo de las divisiones en un árbol de decisión es aumentar la pureza de los nodos hijos. Por ejemplo, si tienes un nodo que contiene datos de emails spam y no spam, podrías dividirlo en base a si el email contiene la palabra "ganar". Esto podría aumentar la pureza si resulta que la mayoría de los emails que contienen la palabra "ganar" son spam y la maytoría de los que no la contienen son no spam. +El objetivo de las divisiones en un árbol de decisión es aumentar la pureza de los nodos hijos. Por ejemplo, si tienes un nodo que contiene datos de emails spam y no spam, podrías dividirlo en base a si el email contiene la palabra "ganar". Esto podría aumentar la pureza si resulta que la mayoría de los emails que contienen la palabra "ganar" son spam y la mayoría de los que no la contienen no son spam. En este caso, por simplicidad, supongamos que decidimos dividir por `Clima` primero. Entonces, dividimos los datos en dos nodos hijos: uno para los días soleados y otro para los días lluviosos: -![starting_tree](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/starting_tree.png?raw=true) +![Árbol de decisión ejemplo de fútbol parte 1](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/starting_tree.png?raw=true) Ahora tenemos dos nodos hijos, cada uno con una parte de los datos: @@ -49,7 +49,7 @@ Ahora tenemos dos nodos hijos, cada uno con una parte de los datos: Cada uno de estos nodos hijos se divide de nuevo, esta vez en función de la velocidad del viento: -![derivated_tree](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/derivated_tree.png?raw=true) +![Árbol de decisión ejemplo de fútbol parte 2](https://github.com/4GeeksAcademy/machine-learning-content/blob/master/assets/derivated_tree.png?raw=true) Ahora, cada uno de los nodos hijos (que ahora son nodos hoja, ya que no se dividirán más porque son puros) representa una decisión final basada en las condiciones climáticas. Por ejemplo, si el clima es soleado y el viento es débil, la decisión es jugar al fútbol. @@ -63,4 +63,4 @@ Podemos construir un árbol de decisión fácilmente en Python utilizando la lib - `max_features`: El número máximo de características a considerar al buscar la mejor división. Si `max_features` es `None`, entonces se considerarán todas las características. Reducir este número puede hacer que el modelo sea más simple y rápido de entrenar, pero también puede hacer que pase por alto algunas relaciones importantes. - `criterion`: La función para medir la calidad de una división. Dependiendo de la naturaleza del árbol (clasificar o regresar), las opciones varían. Este hiperparámetro es el encargado de elegir qué variable se va a ramificar. -Otro hiperparámetro muy importante es el `random_state`, que controla la semilla de generación aleatoria. Este atributo es crucial para asegurar la replicabilidad. \ No newline at end of file +Otro hiperparámetro muy importante es el `random_state`, que controla la semilla de generación aleatoria. Este atributo es crucial para asegurar la replicabilidad. From 3d5ecda8e8915825de8f9b12c935731ef54ab7a7 Mon Sep 17 00:00:00 2001 From: Jose Mora <109150320+josemoracard@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:16:20 +0200 Subject: [PATCH 3/3] Added translated images in english para el archivo /06-ml_algos/decision-trees.md --- assets/derivated_tree_english.png | Bin 0 -> 18249 bytes assets/starting_tree_english.png | Bin 0 -> 8530 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/derivated_tree_english.png create mode 100644 assets/starting_tree_english.png diff --git a/assets/derivated_tree_english.png b/assets/derivated_tree_english.png new file mode 100644 index 0000000000000000000000000000000000000000..b16acf15e55766c8a052b905d1c1fe0344bcd866 GIT binary patch literal 18249 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 Yw||Ffnnqae;2EdVBQ=FmxfcQd54j(XF8}}l literal 0 HcmV?d00001 diff --git a/assets/starting_tree_english.png b/assets/starting_tree_english.png new file mode 100644 index 0000000000000000000000000000000000000000..db06941e2156c16a600d5f9ac437e5b02876bd70 GIT binary patch literal 8530 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 f|L}l&_z1!%Fu)c6c|0DR70^<