<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>BIT</title>
<link>https://biitt.com/es/blog/deep-learning/</link>
<atom:link href="https://biitt.com/es/blog/deep-learning/index.xml" rel="self" type="application/rss+xml"/>
<description>BIT — Business Innovation Technology. Estadística, Machine Learning, Deep Learning, Big Data, MLOps e IoT: notebooks y artículos técnicos de Wilder Ramírez Delgado.</description>
<generator>quarto-1.8.27</generator>
<lastBuildDate>Mon, 31 Aug 2026 05:00:00 GMT</lastBuildDate>
<item>
  <title>Perceptrón y MLP: de la neurona simple a las redes multicapa</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/</link>
  <description><![CDATA[ 




<section id="perceptrón-y-mlp-de-la-neurona-simple-a-las-redes-multicapa" class="level1">
<h1>Perceptrón y MLP: de la neurona simple a las redes multicapa</h1>
<p><a href="TODO_URL_GITHUB"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"></a></p>
<p>En este notebook exploramos los fundamentos de las redes neuronales artificiales, desde su inspiración en las neuronas biológicas hasta su implementación computacional. Analizamos el modelo del Perceptrón, su estructura y funcionamiento, así como su capacidad para resolver problemas linealmente separables. También discutimos sus limitaciones y la evolución hacia redes neuronales multicapa, que permiten abordar problemas más complejos mediante funciones de activación no lineales y algoritmos de optimización avanzados.</p>
<section id="sobre-el-autor" class="level2">
<h2 class="anchored" data-anchor-id="sobre-el-autor">👋 Sobre el autor</h2>
<p>Wilder Ramírez Delgado es Científico de Datos, Arquitecto de IA, Ingeniero Electrónico y Magíster en Analítica de Datos. CEO y fundador de Business Innovation Technology (BIT), consultor y docente universitario, trabaja en la intersección entre Data Science, Inteligencia Artificial, Big Data e IoT, transformando problemas reales en soluciones aplicadas.</p>
<p>De la teoría a la práctica, un problema a la vez.</p>
</section>
</section>
<section id="ejemplo-introductorio-implementación-de-un-perceptrón-simple-desde-cero" class="level1">
<h1>Ejemplo introductorio: Implementación de un perceptrón simple desde cero</h1>
<div id="cell-4" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Implementa un perceptron desde cero, lo entrena con OR y muestra predicciones.</span></span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo introductorio: Implementación de un perceptrón simple desde cero</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-6"></span>
<span id="cb1-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Función de activación escalón</span></span>
<span id="cb1-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> step_function(x):</span>
<span id="cb1-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb1-10"></span>
<span id="cb1-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación de una neurona Perceptrón</span></span>
<span id="cb1-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> PerceptronSimple:</span>
<span id="cb1-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, learning_rate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, epochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>):</span>
<span id="cb1-14">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.learning_rate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> learning_rate</span>
<span id="cb1-15">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.epochs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> epochs</span>
<span id="cb1-16">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.weights <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb1-17">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.bias <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb1-18"></span>
<span id="cb1-19">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> fit(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X, y):</span>
<span id="cb1-20">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Entrena el perceptrón."""</span></span>
<span id="cb1-21">        n_features <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]</span>
<span id="cb1-22">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.weights <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros(n_features)</span>
<span id="cb1-23">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.bias <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb1-24"></span>
<span id="cb1-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.epochs):</span>
<span id="cb1-26">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> xi, target <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(X, y):</span>
<span id="cb1-27">                output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.predict(xi)</span>
<span id="cb1-28">                error <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> output</span>
<span id="cb1-29">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.weights <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.learning_rate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> error <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> xi</span>
<span id="cb1-30">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.bias <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.learning_rate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> error</span>
<span id="cb1-31"></span>
<span id="cb1-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> predict(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X):</span>
<span id="cb1-33">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Realiza predicciones con la función escalón."""</span></span>
<span id="cb1-34">        linear_output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.dot(X, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.weights) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.bias</span>
<span id="cb1-35">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> step_function(linear_output)</span>
<span id="cb1-36"></span>
<span id="cb1-37"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Datos de entrenamiento: Tabla OR</span></span>
<span id="cb1-38">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]])</span>
<span id="cb1-39">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Salidas esperadas para la función OR</span></span>
<span id="cb1-40"></span>
<span id="cb1-41"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear y entrenar el perceptrón</span></span>
<span id="cb1-42">perceptron <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PerceptronSimple(learning_rate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, epochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb1-43">perceptron.fit(X, y)</span>
<span id="cb1-44"></span>
<span id="cb1-45"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Probar predicciones</span></span>
<span id="cb1-46">predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [perceptron.predict(x) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> X]</span>
<span id="cb1-47"></span>
<span id="cb1-48"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Mostrar resultados</span></span>
<span id="cb1-49"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, (x, pred) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(X, predictions)):</span>
<span id="cb1-50">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Entrada: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> -&gt; Predicción: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>pred<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada: [0 0] -&gt; Predicción: 0
Entrada: [0 1] -&gt; Predicción: 1
Entrada: [1 0] -&gt; Predicción: 1
Entrada: [1 1] -&gt; Predicción: 1</code></pre>
</div>
</div>
<section id="explicación-del-ejemplo-introductorio-perceptrón-desde-cero-con-or" class="level2">
<h2 class="anchored" data-anchor-id="explicación-del-ejemplo-introductorio-perceptrón-desde-cero-con-or">Explicación del ejemplo introductorio (Perceptrón desde cero con OR)</h2>
<p>Esta explicación corresponde solo al bloque anterior, donde se entrena un perceptrón desde cero para aprender la compuerta OR.</p>
<section id="implementación-del-perceptrón-simple" class="level3">
<h3 class="anchored" data-anchor-id="implementación-del-perceptrón-simple">1. Implementación del perceptrón simple</h3>
<p>Primero se define la función de activación escalón: devuelve 1 si la entrada es positiva y 0 en caso contrario.</p>
<p>Luego se crea la clase PerceptronSimple con estos elementos: - Pesos (weights), inicializados en 0. - Bias, inicializado en 0. - Tasa de aprendizaje (learning_rate), que se puede ajustar. - Número de iteraciones (epochs) para el entrenamiento.</p>
<section id="en-términos-simples-qué-es-la-tasa-de-ajuste" class="level4">
<h4 class="anchored" data-anchor-id="en-términos-simples-qué-es-la-tasa-de-ajuste">En términos simples: ¿qué es la tasa de ajuste?</h4>
<p>La tasa de ajuste (learning_rate) indica qué tan grande es cada corrección cuando el modelo se equivoca. - Si es alta, corrige con pasos grandes (puede pasarse). - Si es baja, corrige con pasos pequeños (aprende más lento).</p>
</section>
<section id="qué-es-cada-cosa" class="level4">
<h4 class="anchored" data-anchor-id="qué-es-cada-cosa">¿Qué es cada cosa?</h4>
<ul>
<li>X: matriz de entradas (cada fila es un ejemplo y cada columna una característica).</li>
<li>y: salida esperada para cada ejemplo.</li>
<li>weights: importancia de cada característica de entrada.</li>
<li>bias: término independiente que desplaza la frontera de decisión.</li>
<li>learning_rate: tamaño del ajuste en cada actualización.</li>
<li>epochs: cuántas veces se recorre todo el conjunto de entrenamiento.</li>
<li>xi: una fila de X (un ejemplo individual).</li>
<li>target: valor real esperado para xi.</li>
<li>predict(xi): salida estimada por el modelo para xi.</li>
<li>error = target - output: diferencia entre valor real y valor predicho.</li>
</ul>
</section>
</section>
<section id="entrenamiento-del-perceptrón" class="level3">
<h3 class="anchored" data-anchor-id="entrenamiento-del-perceptrón">2. Entrenamiento del perceptrón</h3>
<p>Se recorren los datos de entrenamiento varias veces (epochs).</p>
<p>En cada iteración: - Se calcula la salida de la neurona (predict). - Se compara con la salida esperada (y). - Se actualizan los pesos y el bias según el error de predicción.</p>
</section>
<section id="predicción-y-evaluación" class="level3">
<h3 class="anchored" data-anchor-id="predicción-y-evaluación">3. Predicción y evaluación</h3>
<p>Se entrena el modelo con la tabla OR (X e y).</p>
<p>Luego se prueba con los mismos datos y se imprime la predicción para cada entrada.</p>
</section>
</section>
</section>
<section id="ejemplo-1-iris---clasificación-de-setosa-vs-no-setosa" class="level1">
<h1>Ejemplo 1: Iris - Clasificación de Setosa vs No Setosa</h1>
<p>A partir de aquí empieza un ejemplo distinto al de OR.</p>
<p>El conjunto de datos Iris es un dataset clásico de aprendizaje automático que contiene mediciones de flores de tres especies de iris (Setosa, Versicolor y Virginica). Cada registro incluye variables como largo y ancho del sépalo y del pétalo, y se usa para practicar tareas de clasificación.</p>
<div id="cell-7" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario (Ejemplo 1 - parte A): Carga Iris, entrena un perceptron binario (Setosa vs no Setosa) y realiza una prediccion puntual.</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1) Importar librerias necesarias</span></span>
<span id="cb3-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb3-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_iris</span>
<span id="cb3-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Perceptron</span>
<span id="cb3-7"></span>
<span id="cb3-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2) Cargar el dataset Iris (150 flores, 3 especies)</span></span>
<span id="cb3-9">iris <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_iris()</span>
<span id="cb3-10"></span>
<span id="cb3-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3) Definir variables de entrada (X)</span></span>
<span id="cb3-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Usamos solo 2 caracteristicas para simplificar:</span></span>
<span id="cb3-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># - columna 2: longitud del petalo</span></span>
<span id="cb3-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># - columna 3: ancho del petalo</span></span>
<span id="cb3-15">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> iris.data[:, (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)]</span>
<span id="cb3-16"></span>
<span id="cb3-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4) Definir la variable objetivo (y) en formato binario</span></span>
<span id="cb3-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># y = 1 si la flor es Setosa</span></span>
<span id="cb3-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># y = 0 si la flor NO es Setosa (Versicolor o Virginica)</span></span>
<span id="cb3-20">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (iris.target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb3-21"></span>
<span id="cb3-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 5) Crear y entrenar el modelo Perceptron</span></span>
<span id="cb3-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># random_state fija la semilla para reproducibilidad</span></span>
<span id="cb3-24">per_clf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Perceptron(random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb3-25">per_clf.fit(X, y)</span>
<span id="cb3-26"></span>
<span id="cb3-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6) Probar el modelo con una flor nueva</span></span>
<span id="cb3-28"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo: petalo de longitud 2.0 cm y ancho 0.5 cm</span></span>
<span id="cb3-29">muestra_nueva <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [[<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>]]</span>
<span id="cb3-30">prediccion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> per_clf.predict(muestra_nueva)[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb3-31"></span>
<span id="cb3-32"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 7) Mostrar resultado numerico y su interpretacion</span></span>
<span id="cb3-33">etiqueta <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Setosa"</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> prediccion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No Setosa"</span></span>
<span id="cb3-34"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada:"</span>, muestra_nueva[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="cb3-35"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Prediccion numerica:"</span>, prediccion)</span>
<span id="cb3-36"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Interpretacion:"</span>, etiqueta)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada: [2.0, 0.5]
Prediccion numerica: 1
Interpretacion: Setosa</code></pre>
</div>
</div>
</section>
<section id="ejemplo-1-continuación-visualización-de-la-frontera-de-decisión-en-iris" class="level1">
<h1>Ejemplo 1 (continuación): Visualización de la frontera de decisión en Iris</h1>
<p><strong>Objetivo</strong> Entrenar un <strong>Perceptrón</strong> con Iris para clasificar si una flor es <strong>Setosa (1)</strong> o <strong>no Setosa (0)</strong>, y visualizar cómo el modelo separa ambas clases.</p>
<section id="qué-se-hizo-en-este-ejemplo-paso-a-paso" class="level2">
<h2 class="anchored" data-anchor-id="qué-se-hizo-en-este-ejemplo-paso-a-paso">¿Qué se hizo en este ejemplo? (paso a paso)</h2>
<ol type="1">
<li><p><strong>Se cargó el dataset Iris</strong> Se usó <code>load_iris()</code> de scikit-learn, que trae 150 flores etiquetadas en 3 especies.</p></li>
<li><p><strong>Se seleccionaron 2 variables de entrada</strong> De las 4 variables originales, se tomaron solo:</p></li>
</ol>
<ul>
<li>Longitud del pétalo</li>
<li>Ancho del pétalo</li>
</ul>
<p>Esto se hace para poder graficar en 2D y entender mejor la frontera de decisión.</p>
<ol start="3" type="1">
<li><strong>Se convirtió el problema a clasificación binaria</strong> La variable objetivo se transformó así:</li>
</ol>
<ul>
<li><code>1</code> si la flor es <strong>Iris Setosa</strong></li>
<li><code>0</code> si es <strong>Versicolor</strong> o <strong>Virginica</strong></li>
</ul>
<ol start="4" type="1">
<li><p><strong>Se creó y entrenó el modelo</strong> Se entrenó <code>Perceptron(random_state=42)</code> con <code>X</code> e <code>y</code>. El modelo aprende una combinación lineal de las variables para separar las dos clases.</p></li>
<li><p><strong>Se probó una predicción puntual</strong> Se evaluó el modelo con una flor de ejemplo <code>[[2, 0.5]]</code> para ver si la clasifica como Setosa o no.</p></li>
<li><p><strong>Se construyó una malla de puntos para visualizar</strong> Se generó una cuadrícula (<code>meshgrid</code>) que cubre el rango de los datos. En cada punto de esa malla, el modelo predice clase 0 o 1.</p></li>
<li><p><strong>Se graficó la frontera de decisión</strong></p></li>
</ol>
<ul>
<li>El fondo coloreado muestra la clase que el modelo asigna en cada zona.</li>
<li>Los puntos reales del dataset muestran dónde caen las flores observadas.</li>
<li>La transición de color entre zonas representa la frontera de decisión lineal del Perceptrón.</li>
</ul>
</section>
<section id="lectura-rápida-del-resultado" class="level2">
<h2 class="anchored" data-anchor-id="lectura-rápida-del-resultado">Lectura rápida del resultado</h2>
<p>Si la mayoría de puntos Setosa quedan en una zona y los no Setosa en otra, el modelo está separando bien para este caso. Si hay mezcla fuerte de colores y puntos, la separación no es buena con un modelo lineal.</p>
</section>
</section>
<section id="ejemplo-1---parte-b-entrena-perceptron-en-iris-y-visualiza-su-frontera-de-decision-en-2d." class="level1">
<h1>Ejemplo 1 - parte B: Entrena perceptron en Iris y visualiza su frontera de decision en 2D.</h1>
<div id="cell-9" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario (Ejemplo 1 - parte B): Entrena perceptron en Iris y visualiza su frontera de decision en 2D.</span></span>
<span id="cb5-2"></span>
<span id="cb5-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Importar librerías necesarias</span></span>
<span id="cb5-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb5-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb5-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_iris</span>
<span id="cb5-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Perceptron</span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cargar el conjunto de datos Iris</span></span>
<span id="cb5-10">iris <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_iris()</span>
<span id="cb5-11">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> iris.data[:, (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Seleccionar características: Longitud y Ancho del pétalo</span></span>
<span id="cb5-12">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (iris.target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Convertir a clasificación binaria: 1 si es Setosa, 0 en otro caso</span></span>
<span id="cb5-13"></span>
<span id="cb5-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear y entrenar el modelo Perceptrón con hiperparámetros ajustados</span></span>
<span id="cb5-15">per_clf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Perceptron(eta0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb5-16">per_clf.fit(X, y)</span>
<span id="cb5-17"></span>
<span id="cb5-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear una malla para visualizar la frontera de decisión</span></span>
<span id="cb5-19">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb5-20">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb5-21">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb5-22"></span>
<span id="cb5-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Predecir sobre la malla</span></span>
<span id="cb5-24">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> per_clf.predict(np.c_[xx.ravel(), yy.ravel()])</span>
<span id="cb5-25">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Z.reshape(xx.shape)</span>
<span id="cb5-26"></span>
<span id="cb5-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Graficar la frontera de decisión</span></span>
<span id="cb5-28">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb5-29">plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb5-30">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>, s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">80</span>)</span>
<span id="cb5-31">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón para Iris Setosa"</span>)</span>
<span id="cb5-32">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Longitud del Pétalo (cm)"</span>)</span>
<span id="cb5-33">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ancho del Pétalo (cm)"</span>)</span>
<span id="cb5-34">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-4-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<section id="explicación-simple-del-concepto-de-frontera-de-decisión" class="level2">
<h2 class="anchored" data-anchor-id="explicación-simple-del-concepto-de-frontera-de-decisión">Explicación Simple del Concepto de Frontera de Decisión</h2>
<p>La <strong>frontera de decisión</strong> es la <strong>línea (o superficie) que separa</strong> diferentes categorías en un problema de clasificación.</p>
<section id="cómo-funciona" class="level3">
<h3 class="anchored" data-anchor-id="cómo-funciona">¿Cómo funciona?</h3>
<p>Imagina que tienes un conjunto de datos con dos tipos de puntos:<br>
🔴 <strong>Rojos</strong> (Clase A)<br>
🔵 <strong>Azules</strong> (Clase B)</p>
<p>Un modelo de clasificación, como un <strong>Perceptrón</strong>, intenta encontrar una <strong>línea</strong> que divida los puntos rojos de los azules. Esta línea es la <strong>frontera de decisión</strong>.</p>
</section>
<section id="ejemplo-visual" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-visual"><strong>🖼 Ejemplo Visual</strong></h3>
<p>Si los datos son simples y pueden separarse con una línea recta, la frontera de decisión luce así:</p>
<pre><code>🔴 🔴 🔴 | 🔵 🔵 🔵
🔴 🔴 🔴 | 🔵 🔵 🔵
🔴 🔴 🔴 | 🔵 🔵 🔵</code></pre>
<p>La <strong>línea vertical</strong> <code>|</code> es la <strong>frontera de decisión</strong>, que divide las dos clases.</p>
</section>
<section id="aplicación-en-machine-learning" class="level3">
<h3 class="anchored" data-anchor-id="aplicación-en-machine-learning"><strong>Aplicación en Machine Learning</strong></h3>
<ul>
<li><strong>Perceptrón</strong> → Encuentra una <strong>línea recta</strong> como frontera de decisión.<br>
</li>
<li><strong>Redes Neuronales</strong> → Pueden aprender fronteras <strong>curvas y complejas</strong>.<br>
</li>
<li><strong>SVM (Máquinas de Soporte Vectorial)</strong> → Encuentran la <strong>mejor frontera</strong> con el mayor margen entre clases.</li>
</ul>
<p><strong>Conclusión:</strong><br>
🔹 La <strong>frontera de decisión</strong> es <strong>la separación matemática entre clases</strong>.<br>
🔹 En datos simples, es <strong>una línea recta</strong>.<br>
🔹 En problemas complejos, puede ser <strong>una curva o superficie tridimensional</strong>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-10-1-image.png" class="img-fluid figure-img"></p>
<figcaption>image.png</figcaption>
</figure>
</div>
<p><strong>Explicación del Gráfico</strong></p>
<p>1️⃣ <strong>Los puntos representan datos</strong>:<br>
- 🔴 <strong>Rojos (Clase 0)</strong><br>
- 🔵 <strong>Azules (Clase 1)</strong></p>
<p>2️⃣ <strong>La frontera de decisión</strong> es la línea que separa ambas clases.<br>
- Todo lo que cae en un lado de la línea se clasifica como <strong>Clase 0</strong>.<br>
- Todo lo que cae en el otro lado se clasifica como <strong>Clase 1</strong>.</p>
<p>3️⃣ <strong>La región sombreada</strong> indica cómo el modelo divide el espacio:<br>
- <strong>Rojo claro</strong> → Zonas donde el modelo predice <strong>Clase 0</strong>.<br>
- <strong>Azul claro</strong> → Zonas donde el modelo predice <strong>Clase 1</strong>.</p>
<p><strong>Interpretación</strong></p>
<p>Si los datos son <strong>linealmente separables</strong>, el <strong>Perceptrón</strong> puede encontrar una <strong>línea recta</strong> para dividirlos.</p>
<p>Si los datos <strong>no son separables linealmente</strong>, el Perceptrón fallará, y será necesario usar un <strong>Perceptrón Multicapa (MLP)</strong>.</p>
<p><strong>Conclusión:</strong></p>
<p>La <strong>frontera de decisión</strong> es la separación matemática entre las clases. Este gráfico nos permite ver cómo un modelo divide los datos en función de su aprendizaje. 🚀</p>
</section>
</section>
<section id="implementación-de-la-neurona-de-mcculloch-pitts-para-la-función-and" class="level2">
<h2 class="anchored" data-anchor-id="implementación-de-la-neurona-de-mcculloch-pitts-para-la-función-and">Implementación de la Neurona de McCulloch-Pitts para la función AND</h2>
<div id="cell-12" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Simula una neurona de McCulloch-Pitts para la compuerta logica AND.</span></span>
<span id="cb7-2"></span>
<span id="cb7-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb7-4"></span>
<span id="cb7-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> mcculloch_pitts_neuron(inputs, weights, threshold<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="cb7-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb7-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Implementa la neurona de McCulloch-Pitts con función escalón.</span></span>
<span id="cb7-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb7-9">    weighted_sum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.dot(inputs, weights)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Producto punto entre entradas y pesos</span></span>
<span id="cb7-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> weighted_sum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> threshold <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb7-11"></span>
<span id="cb7-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Prueba con la compuerta lógica AND</span></span>
<span id="cb7-13">weights <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pesos asignados a las entradas</span></span>
<span id="cb7-14">test_cases <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>), (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>), (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entradas posibles</span></span>
<span id="cb7-15"></span>
<span id="cb7-16"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada  -&gt;  Salida"</span>)</span>
<span id="cb7-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> test_cases:</span>
<span id="cb7-18">    output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mcculloch_pitts_neuron(x, weights)</span>
<span id="cb7-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>x<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> -&gt; </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>output<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada  -&gt;  Salida
(0, 0) -&gt; 0
(0, 1) -&gt; 0
(1, 0) -&gt; 0
(1, 1) -&gt; 1</code></pre>
</div>
</div>
<section id="explicación-del-código-implementación-de-la-neurona-de-mcculloch-pitts-para-la-función-and" class="level3">
<h3 class="anchored" data-anchor-id="explicación-del-código-implementación-de-la-neurona-de-mcculloch-pitts-para-la-función-and">Explicación del Código: Implementación de la Neurona de McCulloch-Pitts para la función AND</h3>
<p>Este código implementa una <strong>neurona de McCulloch-Pitts</strong>, un modelo simple de neurona artificial basado en <strong>cálculo de sumas ponderadas</strong> y una <strong>función escalón</strong> para la activación.</p>
</section>
<section id="cómo-funciona-1" class="level3">
<h3 class="anchored" data-anchor-id="cómo-funciona-1"><strong>¿Cómo Funciona?</strong></h3>
<p>1️⃣ <strong>Define la función <code>mcculloch_pitts_neuron</code></strong>, que:<br>
- Calcula el <strong>producto punto</strong> entre las entradas y los pesos.<br>
- Aplica la función de activación <strong>escalón</strong> (si la suma ponderada es mayor o igual al umbral, devuelve <code>1</code>, si no, <code>0</code>).</p>
<p>2️⃣ <strong>Asigna pesos y define casos de prueba</strong>:<br>
- Usa la compuerta lógica <strong>AND</strong>, con pesos <code>[0.5, 0.5]</code>.<br>
- Prueba con todas las combinaciones posibles de <code>0</code> y <code>1</code> en las entradas.</p>
<p>3️⃣ <strong>Ejecuta el modelo y muestra los resultados</strong>:<br>
- Para cada combinación de entrada <code>(x1, x2)</code>, calcula la salida de la neurona y la imprime.</p>
</section>
<section id="resultado-esperado-compuerta-lógica-and" class="level3">
<h3 class="anchored" data-anchor-id="resultado-esperado-compuerta-lógica-and"><strong>Resultado Esperado (Compuerta Lógica AND)</strong></h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Entrada <code>(x1, x2)</code></th>
<th>Salida <code>y</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>(0, 0)</code></td>
<td><code>0</code></td>
</tr>
<tr class="even">
<td><code>(0, 1)</code></td>
<td><code>0</code></td>
</tr>
<tr class="odd">
<td><code>(1, 0)</code></td>
<td><code>0</code></td>
</tr>
<tr class="even">
<td><code>(1, 1)</code></td>
<td><code>1</code></td>
</tr>
</tbody>
</table>
<hr>
</section>
<section id="explicación-de-los-resultados" class="level3">
<h3 class="anchored" data-anchor-id="explicación-de-los-resultados"><strong>Explicación de los Resultados</strong></h3>
<p>El código sigue el funcionamiento de la compuerta <strong>AND</strong>, que devuelve <code>1</code> <strong>solo cuando ambas entradas son <code>1</code></strong>.</p>
<section id="ejemplo-de-cálculo-para-11" class="level4">
<h4 class="anchored" data-anchor-id="ejemplo-de-cálculo-para-11"><strong>Ejemplo de Cálculo para (1,1):</strong></h4>
<p><strong>Producto punto</strong>:</p>
<p>(1 * 0.5) + (1 * 0.5) = 0.5 + 0.5 = 1</p>
<p><strong>Comparación con el umbral (<code>threshold=1</code>)</strong>:<br>
✅ <strong>1 &gt;= 1 → Se activa la neurona (Salida = 1)</strong></p>
<p>🔴 <strong>Para todas las demás combinaciones, la suma ponderada es menor a 1</strong>, por lo que la salida es <code>0</code>.</p>
</section>
</section>
<section id="conclusión" class="level3">
<h3 class="anchored" data-anchor-id="conclusión"><strong>Conclusión</strong></h3>
<ul>
<li><strong>Este código implementa una neurona artificial básica</strong> siguiendo el modelo de McCulloch-Pitts.<br>
</li>
<li><strong>Solo puede resolver problemas linealmente separables</strong>, como la compuerta AND.<br>
</li>
<li><strong>No puede aprender</strong> porque los pesos son fijos (no hay retropropagación ni ajuste de pesos).<br>
</li>
<li><strong>Si se usara para XOR, fallaría</strong>, ya que <strong>XOR no es linealmente separable</strong>.</li>
</ul>
</section>
</section>
</section>
<section id="perceptrón-entrenado-con-la-función-lógica-or" class="level1">
<h1>Perceptrón entrenado con la función lógica OR</h1>
<div id="cell-15" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Entrena un perceptron para OR y grafica la frontera de decision lineal.</span></span>
<span id="cb9-2"></span>
<span id="cb9-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  Implementación de un Perceptrón para la Función OR con Visualización de la Frontera de Decisión</span></span>
<span id="cb9-4"></span>
<span id="cb9-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb9-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb9-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Perceptron</span>
<span id="cb9-8"></span>
<span id="cb9-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  1. Datos de entrada (X) y etiquetas esperadas (y) para la compuerta OR</span></span>
<span id="cb9-10">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entradas binarias</span></span>
<span id="cb9-11">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Salidas esperadas (función OR)</span></span>
<span id="cb9-12"></span>
<span id="cb9-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  2. Crear y entrenar el perceptrón</span></span>
<span id="cb9-14">perceptron <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Perceptron(max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, eta0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb9-15">perceptron.fit(X, y)</span>
<span id="cb9-16"></span>
<span id="cb9-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  3. Evaluación del modelo</span></span>
<span id="cb9-18">predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> perceptron.predict(X)</span>
<span id="cb9-19"></span>
<span id="cb9-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  4. Imprimir resultados de las predicciones</span></span>
<span id="cb9-21"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada -&gt; Salida (predicción)"</span>)</span>
<span id="cb9-22"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(X)):</span>
<span id="cb9-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> -&gt; </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>predictions[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb9-24"></span>
<span id="cb9-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  5. Crear una malla para visualizar la frontera de decisión</span></span>
<span id="cb9-26">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb9-27">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb9-28">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb9-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6. Predecir sobre la malla</span></span>
<span id="cb9-30">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> perceptron.predict(np.c_[xx.ravel(), yy.ravel()])</span>
<span id="cb9-31">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Z.reshape(xx.shape)</span>
<span id="cb9-32"></span>
<span id="cb9-33"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  7. Graficar la frontera de decisión</span></span>
<span id="cb9-34">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb9-35">plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb9-36">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>, s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">150</span>)</span>
<span id="cb9-37">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón para la función OR"</span>)</span>
<span id="cb9-38">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X1"</span>)</span>
<span id="cb9-39">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X2"</span>)</span>
<span id="cb9-40">plt.show()</span>
<span id="cb9-41"></span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada -&gt; Salida (predicción)
[0 0] -&gt; 0
[0 1] -&gt; 1
[1 0] -&gt; 1
[1 1] -&gt; 1</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-6-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="cell-16" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Intenta resolver XOR con perceptron lineal para evidenciar su limitacion.</span></span>
<span id="cb11-2"></span>
<span id="cb11-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación de un Perceptrón para la Función XOR con Visualización de la Frontera de Decisión</span></span>
<span id="cb11-4"></span>
<span id="cb11-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb11-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb11-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Perceptron</span>
<span id="cb11-8"></span>
<span id="cb11-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Datos de entrada (X) y etiquetas esperadas (y) para la compuerta XOR</span></span>
<span id="cb11-10">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entradas binarias</span></span>
<span id="cb11-11">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Salidas esperadas (función XOR)</span></span>
<span id="cb11-12"></span>
<span id="cb11-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Crear y entrenar el perceptrón</span></span>
<span id="cb11-14">perceptron <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Perceptron(max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, eta0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-15">perceptron.fit(X, y)</span>
<span id="cb11-16"></span>
<span id="cb11-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Evaluación del modelo</span></span>
<span id="cb11-18">predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> perceptron.predict(X)</span>
<span id="cb11-19"></span>
<span id="cb11-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Imprimir resultados de las predicciones</span></span>
<span id="cb11-21"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada -&gt; Salida (predicción)"</span>)</span>
<span id="cb11-22"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(X)):</span>
<span id="cb11-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> -&gt; </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>predictions[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb11-24"></span>
<span id="cb11-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 5. Crear una malla para visualizar la frontera de decisión</span></span>
<span id="cb11-26">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb11-27">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb11-28">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb11-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6. Predecir sobre la malla</span></span>
<span id="cb11-30">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> perceptron.predict(np.c_[xx.ravel(), yy.ravel()])</span>
<span id="cb11-31">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Z.reshape(xx.shape)</span>
<span id="cb11-32"></span>
<span id="cb11-33"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 7. Graficar la frontera de decisión</span></span>
<span id="cb11-34">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb11-35">plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb11-36">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>, s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">150</span>)</span>
<span id="cb11-37">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón para la función XOR"</span>)</span>
<span id="cb11-38">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X1"</span>)</span>
<span id="cb11-39">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X2"</span>)</span>
<span id="cb11-40">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada -&gt; Salida (predicción)
[0 0] -&gt; 0
[0 1] -&gt; 0
[1 0] -&gt; 0
[1 1] -&gt; 0</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-7-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<section id="explicación-del-resultado-perceptrón-en-la-función-xor" class="level3">
<h3 class="anchored" data-anchor-id="explicación-del-resultado-perceptrón-en-la-función-xor"><strong>Explicación del Resultado: Perceptrón en la Función XOR</strong></h3>
<p>🔴 <strong>El Perceptrón falla en aprender la función XOR</strong>.</p>
<hr>
</section>
<section id="qué-está-pasando" class="level3">
<h3 class="anchored" data-anchor-id="qué-está-pasando"><strong>¿Qué está pasando?</strong></h3>
<p>1️⃣ <strong>Resultados esperados de la función XOR</strong><br>
| Entrada <code>(x1, x2)</code> | Salida esperada <code>y</code> | Predicción del Perceptrón | |——————–|——————|———————-| | <code>(0,0)</code> | <code>0</code> | <code>0</code> ✅ | | <code>(0,1)</code> | <code>1</code> | <code>0</code> ❌ | | <code>(1,0)</code> | <code>1</code> | <code>0</code> ❌ | | <code>(1,1)</code> | <code>0</code> | <code>0</code> ✅ |</p>
<p>2️⃣ <strong>La frontera de decisión es incorrecta</strong><br>
- El Perceptrón <strong>clasifica todas las entradas como <code>0</code></strong>.<br>
- <strong>No separa correctamente las clases</strong>, porque <strong>XOR no es linealmente separable</strong>.</p>
<p>3️⃣ <strong>¿Por qué falla el Perceptrón?</strong><br>
- El Perceptrón <strong>solo puede aprender fronteras de decisión lineales</strong>.<br>
- XOR <strong>requiere una frontera de decisión más compleja (no lineal)</strong>.<br>
- <strong>Se necesita una Red Neuronal con más de una capa</strong> (Perceptrón Multicapa - MLP).</p>
<hr>
</section>
<section id="solución-usar-un-perceptrón-multicapa-mlp" class="level3">
<h3 class="anchored" data-anchor-id="solución-usar-un-perceptrón-multicapa-mlp"><strong>Solución: Usar un Perceptrón Multicapa (MLP)</strong></h3>
<p>✅ Para resolver XOR, usar <strong>una red neuronal con capas ocultas</strong> y activaciones no lineales como <strong>ReLU o Sigmoid</strong>.</p>
<div id="cell-19" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Usa un MLP para resolver XOR y mostrar una frontera no lineal.</span></span>
<span id="cb13-2"></span>
<span id="cb13-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación de un Perceptrón Multicapa (MLP) para la Función XOR</span></span>
<span id="cb13-4"></span>
<span id="cb13-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb13-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb13-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.neural_network <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> MLPClassifier</span>
<span id="cb13-8"></span>
<span id="cb13-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Datos de entrada (X) y etiquetas esperadas (y) para la compuerta XOR</span></span>
<span id="cb13-10">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entradas binarias</span></span>
<span id="cb13-11">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Salidas esperadas (función XOR)</span></span>
<span id="cb13-12"></span>
<span id="cb13-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Crear y entrenar un Perceptrón Multicapa (MLP) con parámetros ajustados</span></span>
<span id="cb13-14">mlp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MLPClassifier(hidden_layer_sizes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>), activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tanh'</span>, solver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'adam'</span>, </span>
<span id="cb13-15">                    alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.001</span>, max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20000</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, tol<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-7</span>)</span>
<span id="cb13-16">mlp.fit(X, y)</span>
<span id="cb13-17"></span>
<span id="cb13-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Evaluación del modelo</span></span>
<span id="cb13-19">predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mlp.predict(X)</span>
<span id="cb13-20"></span>
<span id="cb13-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Imprimir resultados de las predicciones</span></span>
<span id="cb13-22"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada -&gt; Salida (predicción)"</span>)</span>
<span id="cb13-23"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(X)):</span>
<span id="cb13-24">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> -&gt; </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>predictions[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb13-25"></span>
<span id="cb13-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 5. Crear una malla para visualizar la frontera de decisión</span></span>
<span id="cb13-27">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb13-28">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb13-29">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb13-30"></span>
<span id="cb13-31"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6. Predecir sobre la malla</span></span>
<span id="cb13-32">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mlp.predict(np.c_[xx.ravel(), yy.ravel()])</span>
<span id="cb13-33">Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Z.reshape(xx.shape)</span>
<span id="cb13-34"></span>
<span id="cb13-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 7. Graficar la frontera de decisión</span></span>
<span id="cb13-36">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb13-37">plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb13-38">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>, s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">150</span>)</span>
<span id="cb13-39">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón Multicapa para la función XOR"</span>)</span>
<span id="cb13-40">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X1"</span>)</span>
<span id="cb13-41">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Entrada X2"</span>)</span>
<span id="cb13-42">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Entrada -&gt; Salida (predicción)
[0 0] -&gt; 0
[0 1] -&gt; 1
[1 0] -&gt; 1
[1 1] -&gt; 0</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-8-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="ejemplos-varios-con-perceptrones" class="level1">
<h1>Ejemplos varios con perceptrones</h1>
<section id="clasificación-binaria-con-perceptrón-simple" class="level2">
<h2 class="anchored" data-anchor-id="clasificación-binaria-con-perceptrón-simple">Clasificación Binaria con Perceptrón Simple</h2>
<p>Usar el perceptrón para resolver un problema de clasificación binaria simple: la clasificación de puntos en el plano (2D) según si están por encima o por debajo de una línea recta</p>
<div id="cell-22" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Entrena un perceptron simple en PyTorch con datos 2D y visualiza resultados.</span></span>
<span id="cb15-2"></span>
<span id="cb15-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb15-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb15-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb15-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.nn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> nn</span>
<span id="cb15-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.optim <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> optim</span>
<span id="cb15-8"></span>
<span id="cb15-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Generación de datos de ejemplo</span></span>
<span id="cb15-10">np.random.seed(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb15-11">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.randn(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb15-12">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> X])</span>
<span id="cb15-13"></span>
<span id="cb15-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Convertir a tensores</span></span>
<span id="cb15-15">X_tensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(X, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb15-16">y_tensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(y, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32).view(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb15-17"></span>
<span id="cb15-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Definición del perceptrón simple</span></span>
<span id="cb15-19"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Perceptron(nn.Module):</span>
<span id="cb15-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb15-21">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(Perceptron, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb15-22">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.linear <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb15-23"></span>
<span id="cb15-24">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x):</span>
<span id="cb15-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> torch.sigmoid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.linear(x))</span>
<span id="cb15-26"></span>
<span id="cb15-27">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Perceptron()</span>
<span id="cb15-28">criterion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.BCELoss()</span>
<span id="cb15-29">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> optim.SGD(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>)</span>
<span id="cb15-30"></span>
<span id="cb15-31"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entrenamiento del perceptrón</span></span>
<span id="cb15-32">epochs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span></span>
<span id="cb15-33"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(epochs):</span>
<span id="cb15-34">    optimizer.zero_grad()</span>
<span id="cb15-35">    outputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(X_tensor)</span>
<span id="cb15-36">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> criterion(outputs, y_tensor)</span>
<span id="cb15-37">    loss.backward()</span>
<span id="cb15-38">    optimizer.step()</span>
<span id="cb15-39"></span>
<span id="cb15-40"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualización de resultados</span></span>
<span id="cb15-41">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb15-42">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb15-43">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.arange(x_min, x_max, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>), np.arange(y_min, y_max, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>))</span>
<span id="cb15-44">grid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb15-45">probs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(grid).detach().numpy().reshape(xx.shape)</span>
<span id="cb15-46"></span>
<span id="cb15-47">plt.contourf(xx, yy, probs, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb15-48">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'k'</span>)</span>
<span id="cb15-49">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Frontera de decisión del Perceptrón Simple'</span>)</span>
<span id="cb15-50">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-9-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>En este ejemplo, se crea un Perceptrón Simple usando PyTorch para clasificar puntos en un plano según si están por encima o por debajo de una línea. Primero, se generan datos aleatorios en 2D y se asigna una etiqueta (0 o 1) según la posición del punto. Luego, se define el modelo del perceptrón como una red muy simple que toma dos números como entrada y devuelve una probabilidad usando la función sigmoide. El entrenamiento se realiza ajustando los pesos para que el modelo acierte lo más posible, usando una técnica llamada Gradiente Descendente Estocástico (SGD). PyTorch facilita el manejo de estos cálculos automáticamente. Finalmente, se visualiza cómo el modelo aprendió a separar los puntos mostrando una línea de decisión en el gráfico.</p>
</section>
</section>
<section id="proceso-de-datos-en-forma-de-espiral" class="level1">
<h1>Proceso de datos en forma de espiral</h1>
<div id="cell-25" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Genera datos en espiral y entrena un MLP en PyTorch para clasificacion no lineal.</span></span>
<span id="cb16-2"></span>
<span id="cb16-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb16-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb16-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb16-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.nn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> nn</span>
<span id="cb16-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.optim <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> optim</span>
<span id="cb16-8"></span>
<span id="cb16-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Generación de datos en forma de espiral</span></span>
<span id="cb16-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> generate_spiral_data(points, classes):</span>
<span id="cb16-11">    X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> classes, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>np.float32)</span>
<span id="cb16-12">    y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> classes, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>np.float32)</span>
<span id="cb16-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> class_number <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(classes):</span>
<span id="cb16-14">        ix <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> class_number, points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb16-15">        r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, points)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Radio</span></span>
<span id="cb16-16">        t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, (class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, points) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.random.randn(points) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ángulo</span></span>
<span id="cb16-17">        X[ix] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.c_[r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.sin(t), r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.cos(t)]</span>
<span id="cb16-18">        y[ix] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb16-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> X, y</span>
<span id="cb16-20"></span>
<span id="cb16-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear el conjunto de datos</span></span>
<span id="cb16-22">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> generate_spiral_data(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb16-23">X_tensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(X, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb16-24">y_tensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(y, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb16-25"></span>
<span id="cb16-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Definición del MLP para clasificar los puntos en espiral</span></span>
<span id="cb16-27"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> SpiralMLP(nn.Module):</span>
<span id="cb16-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb16-29">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(SpiralMLP, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb16-30">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hidden <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.Sequential(</span>
<span id="cb16-31">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>),</span>
<span id="cb16-32">            nn.ReLU(),</span>
<span id="cb16-33">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>),</span>
<span id="cb16-34">            nn.ReLU(),</span>
<span id="cb16-35">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb16-36">            nn.Sigmoid()</span>
<span id="cb16-37">        )</span>
<span id="cb16-38"></span>
<span id="cb16-39">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x):</span>
<span id="cb16-40">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hidden(x)</span>
<span id="cb16-41"></span>
<span id="cb16-42">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SpiralMLP()</span>
<span id="cb16-43">criterion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.BCELoss()</span>
<span id="cb16-44">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>)</span>
<span id="cb16-45"></span>
<span id="cb16-46"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entrenamiento del modelo</span></span>
<span id="cb16-47"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>):</span>
<span id="cb16-48">    optimizer.zero_grad()</span>
<span id="cb16-49">    outputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(X_tensor)</span>
<span id="cb16-50">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> criterion(outputs, y_tensor)</span>
<span id="cb16-51">    loss.backward()</span>
<span id="cb16-52">    optimizer.step()</span>
<span id="cb16-53"></span>
<span id="cb16-54"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualización de la frontera de decisión</span></span>
<span id="cb16-55">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb16-56">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb16-57">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb16-58">grid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb16-59">probs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(grid).detach().numpy().reshape(xx.shape)</span>
<span id="cb16-60"></span>
<span id="cb16-61">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>))</span>
<span id="cb16-62">plt.contourf(xx, yy, probs, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb16-63">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y.ravel(), cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>)</span>
<span id="cb16-64">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón Multicapa para Datos en Espiral"</span>)</span>
<span id="cb16-65">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-10-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<section id="ejemplo-práctico-clasificación-de-puntos-en-espiral-usando-un-perceptrón-multicapa-mlp" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-práctico-clasificación-de-puntos-en-espiral-usando-un-perceptrón-multicapa-mlp">Ejemplo Práctico: Clasificación de Puntos en Espiral usando un Perceptrón Multicapa (MLP)</h3>
<section id="qué-queremos-lograr" class="level4">
<h4 class="anchored" data-anchor-id="qué-queremos-lograr">¿Qué queremos lograr?</h4>
<p>Resolver un problema complejo de clasificación en el que los puntos de diferentes clases están dispuestos en forma de <strong>espiral</strong>. Este tipo de datos es un ejemplo típico de problema <strong>no lineal</strong> donde un perceptrón simple falla, pero un MLP con múltiples capas ocultas puede tener éxito.</p>
<hr>
</section>
<section id="paso-1-generación-de-datos-en-forma-de-espiral" class="level4">
<h4 class="anchored" data-anchor-id="paso-1-generación-de-datos-en-forma-de-espiral">Paso 1: Generación de Datos en Forma de Espiral</h4>
<p>El objetivo es crear dos conjuntos de puntos que forman espirales intercaladas. Esto crea un problema de clasificación difícil porque las clases están enredadas entre sí.</p>
<section id="código-generación-de-datos" class="level5">
<h5 class="anchored" data-anchor-id="código-generación-de-datos">Código: Generación de datos</h5>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> generate_spiral_data(points, classes):</span>
<span id="cb17-2">    X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> classes, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>np.float32)</span>
<span id="cb17-3">    y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> classes, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>np.float32)</span>
<span id="cb17-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> class_number <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(classes):</span>
<span id="cb17-5">        ix <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> class_number, points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb17-6">        r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, points)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Radio creciente</span></span>
<span id="cb17-7">        t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, (class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, points) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.random.randn(points) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ángulo</span></span>
<span id="cb17-8">        X[ix] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.c_[r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.sin(t), r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.cos(t)]</span>
<span id="cb17-9">        y[ix] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> class_number <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Alterna entre 0 y 1</span></span>
<span id="cb17-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> X, y</span></code></pre></div></div>
<ul>
<li><strong>Datos en espiral</strong>: Los puntos están organizados en <strong>dos espirales intercaladas</strong>.<br>
</li>
<li><strong>Radio</strong>: Aumenta progresivamente para formar una curva.<br>
</li>
<li><strong>Ángulo</strong>: Se desplaza según la clase, más un pequeño ruido para aleatoriedad.</li>
</ul>
<hr>
</section>
</section>
<section id="paso-2-definición-del-perceptrón-multicapa-mlp" class="level4">
<h4 class="anchored" data-anchor-id="paso-2-definición-del-perceptrón-multicapa-mlp">Paso 2: Definición del Perceptrón Multicapa (MLP)</h4>
<p>El modelo consta de <strong>tres capas</strong>:<br>
1. <strong>Capa oculta 1:</strong> 16 neuronas con activación ReLU.<br>
2. <strong>Capa oculta 2:</strong> 8 neuronas con activación ReLU.<br>
3. <strong>Capa de salida:</strong> 1 neurona con activación Sigmoid (para clasificación binaria).</p>
<section id="código-modelo-mlp" class="level5">
<h5 class="anchored" data-anchor-id="código-modelo-mlp">Código: Modelo MLP</h5>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> SpiralMLP(nn.Module):</span>
<span id="cb18-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb18-3">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(SpiralMLP, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb18-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hidden <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.Sequential(</span>
<span id="cb18-5">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>),</span>
<span id="cb18-6">            nn.ReLU(),</span>
<span id="cb18-7">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>),</span>
<span id="cb18-8">            nn.ReLU(),</span>
<span id="cb18-9">            nn.Linear(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>),</span>
<span id="cb18-10">            nn.Sigmoid()</span>
<span id="cb18-11">        )</span>
<span id="cb18-12"></span>
<span id="cb18-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x):</span>
<span id="cb18-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hidden(x)</span></code></pre></div></div>
<ul>
<li><strong>Arquitectura en capas</strong>: El modelo tiene múltiples capas ocultas para aprender la complejidad de la forma de espiral.<br>
</li>
<li><strong>Funciones de activación ReLU</strong>: Proporcionan no linealidad, esencial para aprender el patrón complejo.<br>
</li>
<li><strong>Salida Sigmoid</strong>: Devuelve una probabilidad entre 0 y 1.</li>
</ul>
<hr>
</section>
</section>
<section id="paso-3-entrenamiento-del-modelo" class="level4">
<h4 class="anchored" data-anchor-id="paso-3-entrenamiento-del-modelo">Paso 3: Entrenamiento del Modelo</h4>
<ul>
<li><strong>Optimización</strong>: Se utiliza el optimizador <strong>Adam</strong> para mejorar la eficiencia.<br>
</li>
<li><strong>Función de pérdida</strong>: <code>BCELoss</code> (Binary Cross Entropy) para problemas de clasificación binaria.<br>
</li>
<li><strong>Iteraciones</strong>: Entrenamiento durante <strong>3000 épocas</strong> para garantizar la convergencia.</li>
</ul>
<section id="código-entrenamiento" class="level5">
<h5 class="anchored" data-anchor-id="código-entrenamiento">Código: Entrenamiento</h5>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SpiralMLP()</span>
<span id="cb19-2">criterion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nn.BCELoss()</span>
<span id="cb19-3">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>)</span>
<span id="cb19-4"></span>
<span id="cb19-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>):</span>
<span id="cb19-6">    optimizer.zero_grad()</span>
<span id="cb19-7">    outputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(X_tensor)</span>
<span id="cb19-8">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> criterion(outputs, y_tensor)</span>
<span id="cb19-9">    loss.backward()</span>
<span id="cb19-10">    optimizer.step()</span></code></pre></div></div>
<ul>
<li><strong>Gradiente descendente</strong>: El modelo ajusta los pesos para minimizar la pérdida en cada época.<br>
</li>
<li><strong>Optimizador Adam</strong>: Ajusta el aprendizaje adaptativamente.</li>
</ul>
<hr>
</section>
</section>
<section id="paso-4-visualización-de-la-frontera-de-decisión" class="level4">
<h4 class="anchored" data-anchor-id="paso-4-visualización-de-la-frontera-de-decisión">Paso 4: Visualización de la Frontera de Decisión</h4>
<p>Creamos una malla de puntos en el espacio de entrada para visualizar cómo el MLP separa las dos clases en espiral.</p>
<section id="código-visualización" class="level5">
<h5 class="anchored" data-anchor-id="código-visualización">Código: Visualización</h5>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1">x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb20-2">y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span></span>
<span id="cb20-3">xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>))</span>
<span id="cb20-4">grid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.float32)</span>
<span id="cb20-5">probs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(grid).detach().numpy().reshape(xx.shape)</span>
<span id="cb20-6"></span>
<span id="cb20-7">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>))</span>
<span id="cb20-8">plt.contourf(xx, yy, probs, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb20-9">plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y.ravel(), cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k"</span>)</span>
<span id="cb20-10">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón Multicapa para Datos en Espiral"</span>)</span>
<span id="cb20-11">plt.show()</span></code></pre></div></div>
<ul>
<li><strong>Frontera de decisión</strong>: Visualiza cómo el modelo clasifica cada punto en la espiral.<br>
</li>
<li><strong>Colores</strong>: Diferencian las clases en el gráfico.</li>
</ul>
<hr>
</section>
</section>
<section id="conclusión-1" class="level4">
<h4 class="anchored" data-anchor-id="conclusión-1">Conclusión</h4>
<p>Este ejemplo muestra cómo un <strong>Perceptrón Multicapa (MLP)</strong> puede resolver problemas complejos como la clasificación de datos en espiral, que no pueden ser separados por un modelo lineal. Gracias a sus <strong>capas ocultas y funciones de activación no lineales</strong>, el MLP logra aprender la compleja estructura de los datos.</p>
</section>
</section>
</section>
<section id="generación-de-datos-sintéticos" class="level1">
<h1>Generación de datos sintéticos</h1>
<div id="cell-28" class="cell" data-execution_count="19">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Genera y visualiza varios datasets sinteticos para clasificacion.</span></span>
<span id="cb21-2"></span>
<span id="cb21-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb21-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb21-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> make_moons, make_circles, make_classification, make_blobs, make_gaussian_quantiles, make_multilabel_classification</span>
<span id="cb21-6"></span>
<span id="cb21-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Función para visualizar los datos con categorías destacadas</span></span>
<span id="cb21-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_dataset(X, y, title):</span>
<span id="cb21-9">    plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb21-10">    cmap <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.get_cmap(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Set1"</span>, np.unique(y).size)</span>
<span id="cb21-11">    scatter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>cmap, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'k'</span>, s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>)</span>
<span id="cb21-12">    plt.title(title, fontsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>)</span>
<span id="cb21-13">    plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X1"</span>)</span>
<span id="cb21-14">    plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X2"</span>)</span>
<span id="cb21-15">    plt.colorbar(scatter, ticks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(np.unique(y).size))</span>
<span id="cb21-16">    plt.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb21-17">    plt.show()</span>
<span id="cb21-18"></span>
<span id="cb21-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Generación y visualización de datos usando diferentes métodos</span></span>
<span id="cb21-20"></span>
<span id="cb21-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. make_moons - Genera dos conjuntos de datos en forma de media luna.</span></span>
<span id="cb21-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número total de puntos (aumentado a 500 para mejor separación)</span></span>
<span id="cb21-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - noise: cantidad de ruido aleatorio (0.2 para mantener variabilidad realista)</span></span>
<span id="cb21-24">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_moons(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, noise<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-25">plot_dataset(X, y, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_moons - Media Luna"</span>)</span>
<span id="cb21-26"></span>
<span id="cb21-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. make_circles - Genera dos círculos concéntricos.</span></span>
<span id="cb21-28"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número total de puntos (aumentado a 500)</span></span>
<span id="cb21-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - noise: ruido aleatorio (0.04 para mantener variabilidad moderada)</span></span>
<span id="cb21-30"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - factor: radio del círculo interno respecto al externo (0.8 para mejor visualización)</span></span>
<span id="cb21-31">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_circles(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, noise<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.04</span>, factor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-32">plot_dataset(X, y, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_circles - Círculos Concéntricos"</span>)</span>
<span id="cb21-33"></span>
<span id="cb21-34"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. make_classification - Genera datos para clasificación lineal.</span></span>
<span id="cb21-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número de muestras (500)</span></span>
<span id="cb21-36"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_features: número de características (2 para visualización 2D)</span></span>
<span id="cb21-37"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_redundant: características redundantes (0 para simplicidad)</span></span>
<span id="cb21-38"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_informative: características útiles (2 para el problema)</span></span>
<span id="cb21-39"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_clusters_per_class: número de grupos por clase (1 para mejor separación)</span></span>
<span id="cb21-40">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_classification(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, n_features<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, n_redundant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, n_informative<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, n_clusters_per_class<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-41">plot_dataset(X, y, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_classification - Clasificación Lineal"</span>)</span>
<span id="cb21-42"></span>
<span id="cb21-43"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. make_blobs - Genera varios grupos de puntos alrededor de centros.</span></span>
<span id="cb21-44"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número de puntos (500)</span></span>
<span id="cb21-45"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - centers: cantidad de grupos (3)</span></span>
<span id="cb21-46"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - cluster_std: desviación estándar del grupo (0.6 para menos solapamiento)</span></span>
<span id="cb21-47">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_blobs(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, centers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, cluster_std<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-48">plot_dataset(X, y, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_blobs - Clústeres Gaussianos"</span>)</span>
<span id="cb21-49"></span>
<span id="cb21-50"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 5. make_gaussian_quantiles - Genera datos agrupados según cuantiles gaussianos.</span></span>
<span id="cb21-51"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número de muestras (500)</span></span>
<span id="cb21-52"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_classes: número de clases (2 para clasificación binaria)</span></span>
<span id="cb21-53">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_gaussian_quantiles(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, n_classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-54">plot_dataset(X, y, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_gaussian_quantiles - Cuantiles Gaussianos"</span>)</span>
<span id="cb21-55"></span>
<span id="cb21-56"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6. make_multilabel_classification - Genera datos para problemas multietiqueta.</span></span>
<span id="cb21-57"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_samples: número de muestras (500)</span></span>
<span id="cb21-58"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_features: número de características (2 para visualización)</span></span>
<span id="cb21-59"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_classes: número de etiquetas posibles (3)</span></span>
<span id="cb21-60"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    - n_labels: promedio de etiquetas por instancia (2)</span></span>
<span id="cb21-61">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_multilabel_classification(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, n_features<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, n_classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, n_labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb21-62">plot_dataset(X, y[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"make_multilabel_classification - Clasificación Multietiqueta"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-4.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-5.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-11-output-6.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="perceptrón-y-make_moons" class="level1">
<h1>Perceptrón y make_moons</h1>
<div id="cell-31" class="cell" data-execution_count="24">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Entrena y evalua un MLP con make_moons usando separacion train/test.</span></span>
<span id="cb22-2"></span>
<span id="cb22-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb22-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb22-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> make_moons</span>
<span id="cb22-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.model_selection <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> train_test_split</span>
<span id="cb22-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.neural_network <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> MLPClassifier</span>
<span id="cb22-8"></span>
<span id="cb22-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Generación de datos make_moons</span></span>
<span id="cb22-10">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_moons(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, noise<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb22-11"></span>
<span id="cb22-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Separación en entrenamiento y prueba</span></span>
<span id="cb22-13">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(</span>
<span id="cb22-14">    X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, stratify<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y</span>
<span id="cb22-15">)</span>
<span id="cb22-16"></span>
<span id="cb22-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Creación del Perceptrón Multicapa (MLP)</span></span>
<span id="cb22-18">mlp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MLPClassifier(</span>
<span id="cb22-19">    hidden_layer_sizes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>),</span>
<span id="cb22-20">    activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'relu'</span>,</span>
<span id="cb22-21">    solver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'adam'</span>,</span>
<span id="cb22-22">    max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>,</span>
<span id="cb22-23">    random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span></span>
<span id="cb22-24">)</span>
<span id="cb22-25"></span>
<span id="cb22-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entrenamiento del modelo</span></span>
<span id="cb22-27">mlp.fit(X_train, y_train)</span>
<span id="cb22-28"></span>
<span id="cb22-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Predicción en datos de prueba</span></span>
<span id="cb22-30">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mlp.predict(X_test)</span>
<span id="cb22-31"></span>
<span id="cb22-32"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualización de la frontera de decisión</span></span>
<span id="cb22-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_decision_boundary(X, y, model):</span>
<span id="cb22-34">    x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb22-35">    y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb22-36">    xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>))</span>
<span id="cb22-37">    Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)</span>
<span id="cb22-38">    plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb22-39">    plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'k'</span>)</span>
<span id="cb22-40">    plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón Multicapa - make_moons"</span>)</span>
<span id="cb22-41">    plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X1"</span>)</span>
<span id="cb22-42">    plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X2"</span>)</span>
<span id="cb22-43">    plt.show()</span>
<span id="cb22-44"></span>
<span id="cb22-45"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Llamada a la función de visualización (sobre todo el dataset)</span></span>
<span id="cb22-46">plot_decision_boundary(X, y, mlp)</span>
<span id="cb22-47"></span>
<span id="cb22-48"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Imprimir precisión en entrenamiento y prueba</span></span>
<span id="cb22-49"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precisión en entrenamiento: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mlp<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score(X_train, y_train) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">%"</span>)</span>
<span id="cb22-50"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precisión en prueba: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mlp<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score(X_test, y_test) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">%"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-12-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Precisión en entrenamiento: 96.50%
Precisión en prueba: 91.00%</code></pre>
</div>
</div>
<section id="perceptrón-multicapa-usando-make-moons" class="level3">
<h3 class="anchored" data-anchor-id="perceptrón-multicapa-usando-make-moons">Perceptrón Multicapa usando Make Moons</h3>
<section id="introducción" class="level4">
<h4 class="anchored" data-anchor-id="introducción">Introducción</h4>
<p>Este ejemplo utiliza un <strong>Perceptrón Multicapa (MLP)</strong> para clasificar datos generados con la función <code>make_moons</code>, que produce dos conjuntos de puntos en forma de media luna intercalados. Este tipo de datos no es linealmente separable, por lo que un perceptrón simple no es suficiente. El MLP permite aprender fronteras de decisión no lineales.</p>
<hr>
</section>
<section id="generación-de-datos---make-moons" class="level4">
<h4 class="anchored" data-anchor-id="generación-de-datos---make-moons">1. Generación de Datos - Make Moons</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb24-1">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_moons(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, noise<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<ul>
<li><strong>n_samples=500</strong>: más datos para entrenar mejor.</li>
<li><strong>noise=0.1</strong>: mantiene cierta dificultad sin perder separación visual.</li>
<li><strong>random_state=0</strong>: garantiza reproducibilidad.</li>
</ul>
<hr>
</section>
<section id="separación-en-entrenamiento-y-prueba" class="level4">
<h4 class="anchored" data-anchor-id="separación-en-entrenamiento-y-prueba">2. Separación en Entrenamiento y Prueba</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb25-1">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(</span>
<span id="cb25-2">    X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, stratify<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y</span>
<span id="cb25-3">)</span></code></pre></div></div>
<ul>
<li><strong>test_size=0.2</strong>: usa 80% para entrenar y 20% para evaluar generalización.</li>
<li><strong>stratify=y</strong>: conserva la proporción de clases en ambos conjuntos.</li>
</ul>
<hr>
</section>
<section id="creación-del-perceptrón-multicapa-mlp" class="level4">
<h4 class="anchored" data-anchor-id="creación-del-perceptrón-multicapa-mlp">3. Creación del Perceptrón Multicapa (MLP)</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1">mlp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MLPClassifier(</span>
<span id="cb26-2">    hidden_layer_sizes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>),</span>
<span id="cb26-3">    activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'relu'</span>,</span>
<span id="cb26-4">    solver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'adam'</span>,</span>
<span id="cb26-5">    max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span>,</span>
<span id="cb26-6">    random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span></span>
<span id="cb26-7">)</span></code></pre></div></div>
<ul>
<li><strong>hidden_layer_sizes=(10, 5)</strong>: dos capas ocultas para capturar no linealidad.</li>
<li><strong>activation=‘relu’</strong>: mejora aprendizaje en fronteras complejas.</li>
<li><strong>solver=‘adam’</strong>: optimizador eficiente para este problema.</li>
<li><strong>max_iter=3000</strong>: más iteraciones para reducir riesgo de no convergencia.</li>
<li><strong>random_state=42</strong>: resultados reproducibles.</li>
</ul>
<hr>
</section>
<section id="entrenamiento-y-evaluación" class="level4">
<h4 class="anchored" data-anchor-id="entrenamiento-y-evaluación">4. Entrenamiento y Evaluación</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1">mlp.fit(X_train, y_train)</span>
<span id="cb27-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precisión en entrenamiento: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mlp<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score(X_train, y_train) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">%"</span>)</span>
<span id="cb27-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precisión en prueba: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mlp<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score(X_test, y_test) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">%"</span>)</span></code></pre></div></div>
<ul>
<li>La <strong>precisión en entrenamiento</strong> indica qué tan bien ajusta los datos vistos.</li>
<li>La <strong>precisión en prueba</strong> mide capacidad de generalización.</li>
</ul>
<hr>
</section>
<section id="visualización-de-la-frontera-de-decisión" class="level4">
<h4 class="anchored" data-anchor-id="visualización-de-la-frontera-de-decisión">5. Visualización de la Frontera de Decisión</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb28-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_decision_boundary(X, y, model):</span>
<span id="cb28-2">    x_min, x_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb28-3">    y_min, y_max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb28-4">    xx, yy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.meshgrid(np.linspace(x_min, x_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>), np.linspace(y_min, y_max, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>))</span>
<span id="cb28-5">    Z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)</span>
<span id="cb28-6">    plt.contourf(xx, yy, Z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm)</span>
<span id="cb28-7">    plt.scatter(X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>plt.cm.coolwarm, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'k'</span>)</span>
<span id="cb28-8">    plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Frontera de Decisión del Perceptrón Multicapa - make_moons"</span>)</span>
<span id="cb28-9">    plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X1"</span>)</span>
<span id="cb28-10">    plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X2"</span>)</span>
<span id="cb28-11">    plt.show()</span></code></pre></div></div>
<ul>
<li>Muestra cómo el modelo separa ambas clases en el plano.</li>
</ul>
<hr>
</section>
<section id="conclusión-2" class="level4">
<h4 class="anchored" data-anchor-id="conclusión-2">Conclusión</h4>
<p>El <strong>Perceptrón Multicapa (MLP)</strong> aprende una frontera no lineal adecuada para <code>make_moons</code>. La separación train/test permite una evaluación más realista del modelo y evita sobreestimar su desempeño.</p>
</section>
</section>
</section>
<section id="dígitos-escritos-a-mano" class="level1">
<h1>Dígitos escritos a mano</h1>
<div id="cell-34" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb29-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Explora el dataset de digitos y visualiza ejemplos.</span></span>
<span id="cb29-2"></span>
<span id="cb29-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb29-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_digits</span>
<span id="cb29-5"></span>
<span id="cb29-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cargar el dataset de dígitos escritos a mano</span></span>
<span id="cb29-7">digits <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_digits()</span>
<span id="cb29-8"></span>
<span id="cb29-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Mostrar información básica del dataset</span></span>
<span id="cb29-10"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Número de imágenes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(digits.images)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb29-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Dimensiones de cada imagen: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>digits<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>images[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb29-12"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Etiquetas disponibles: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(digits.target)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb29-13"></span>
<span id="cb29-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualizar los primeros 10 dígitos con tamaño más pequeño</span></span>
<span id="cb29-15">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>))</span>
<span id="cb29-16"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>):</span>
<span id="cb29-17">    plt.subplot(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb29-18">    plt.imshow(digits.images[i], cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>)</span>
<span id="cb29-19">    plt.title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>digits<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>target[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb29-20">    plt.axis(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'off'</span>)</span>
<span id="cb29-21"></span>
<span id="cb29-22">plt.suptitle(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Primeros 10 dígitos del dataset"</span>)</span>
<span id="cb29-23">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Número de imágenes: 1797
Dimensiones de cada imagen: (8, 8)
Etiquetas disponibles: {np.int64(0), np.int64(1), np.int64(2), np.int64(3), np.int64(4), np.int64(5), np.int64(6), np.int64(7), np.int64(8), np.int64(9)}</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-13-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="caras" class="level1">
<h1>Caras</h1>
<p>Nota: los siguientes ejemplos descargan datasets desde internet la primera vez. Si no hay conexión, pueden fallar temporalmente.</p>
<div id="cell-36" class="cell" data-execution_count="13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb31-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Carga y visualiza el dataset Olivetti de rostros.</span></span>
<span id="cb31-2"></span>
<span id="cb31-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb31-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> fetch_olivetti_faces</span>
<span id="cb31-5"></span>
<span id="cb31-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Nota: este dataset se descarga de internet en la primera ejecución.</span></span>
<span id="cb31-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cargar el dataset de caras humanas</span></span>
<span id="cb31-8">dataset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fetch_olivetti_faces()</span>
<span id="cb31-9">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset.images, dataset.target</span>
<span id="cb31-10"></span>
<span id="cb31-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Mostrar información básica del dataset</span></span>
<span id="cb31-12"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Número de imágenes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(X)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb31-13"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Dimensiones de cada imagen: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb31-14"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Número de personas: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(y))<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb31-15"></span>
<span id="cb31-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualizar las primeras 10 caras con tamaño pequeño</span></span>
<span id="cb31-17">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>))</span>
<span id="cb31-18"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>):</span>
<span id="cb31-19">    plt.subplot(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb31-20">    plt.imshow(X[i], cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>)</span>
<span id="cb31-21">    plt.title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>y[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb31-22">    plt.axis(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'off'</span>)</span>
<span id="cb31-23"></span>
<span id="cb31-24">plt.suptitle(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Primeras 10 caras del dataset"</span>)</span>
<span id="cb31-25">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Número de imágenes: 400
Dimensiones de cada imagen: (64, 64)
Número de personas: 40</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-14-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="cell-38" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb33-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Carga y visualiza el dataset LFW de rostros etiquetados.</span></span>
<span id="cb33-2"></span>
<span id="cb33-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb33-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> fetch_lfw_people</span>
<span id="cb33-5"></span>
<span id="cb33-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Nota: este dataset se descarga de internet en la primera ejecución.</span></span>
<span id="cb33-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cargar el dataset de caras etiquetadas en la naturaleza (LFW)</span></span>
<span id="cb33-8">faces <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fetch_lfw_people(min_faces_per_person<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span>, resize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span>)</span>
<span id="cb33-9">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> faces.images, faces.target</span>
<span id="cb33-10"></span>
<span id="cb33-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Mostrar información básica del dataset</span></span>
<span id="cb33-12"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Número de imágenes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(X)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb33-13"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Dimensiones de cada imagen: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb33-14"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Número de personas: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(faces.target_names)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb33-15"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Personas identificadas: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>faces<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>target_names<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb33-16"></span>
<span id="cb33-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualizar las primeras 10 caras con tamaño pequeño</span></span>
<span id="cb33-18">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb33-19"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>):</span>
<span id="cb33-20">    plt.subplot(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb33-21">    plt.imshow(X[i], cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>)</span>
<span id="cb33-22">    plt.title(faces.target_names[y[i]])</span>
<span id="cb33-23">    plt.axis(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'off'</span>)</span>
<span id="cb33-24"></span>
<span id="cb33-25">plt.suptitle(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Primeras 10 caras del dataset LFW"</span>)</span>
<span id="cb33-26">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Número de imágenes: 1288
Dimensiones de cada imagen: (50, 37)
Número de personas: 7
Personas identificadas: ['Ariel Sharon' 'Colin Powell' 'Donald Rumsfeld' 'George W Bush'
 'Gerhard Schroeder' 'Hugo Chavez' 'Tony Blair']</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-15-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="identificando-patrones-escritos-a-mano-con-un-perceptrón" class="level1">
<h1>Identificando patrones escritos a mano con un perceptrón</h1>
<div id="cell-40" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb35" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb35-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Entrena un MLP para reconocer digitos y reporta metricas de desempeno.</span></span>
<span id="cb35-2"></span>
<span id="cb35-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb35-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb35-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_digits</span>
<span id="cb35-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.model_selection <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> train_test_split</span>
<span id="cb35-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.neural_network <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> MLPClassifier</span>
<span id="cb35-8"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> accuracy_score, classification_report, confusion_matrix</span>
<span id="cb35-9"></span>
<span id="cb35-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cargar el conjunto de datos de dígitos escritos a mano</span></span>
<span id="cb35-11">digits <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_digits()</span>
<span id="cb35-12">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> digits.data, digits.target</span>
<span id="cb35-13"></span>
<span id="cb35-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dividir el conjunto de datos en entrenamiento y prueba</span></span>
<span id="cb35-15">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb35-16"></span>
<span id="cb35-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear el Perceptrón Multicapa (MLP) para clasificación de dígitos</span></span>
<span id="cb35-18">mlp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MLPClassifier(hidden_layer_sizes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">64</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span>), activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tanh'</span>, solver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'adam'</span>, max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb35-19"></span>
<span id="cb35-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Entrenar el modelo</span></span>
<span id="cb35-21">mlp.fit(X_train, y_train)</span>
<span id="cb35-22"></span>
<span id="cb35-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Realizar predicciones</span></span>
<span id="cb35-24">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mlp.predict(X_test)</span>
<span id="cb35-25"></span>
<span id="cb35-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Evaluación del modelo</span></span>
<span id="cb35-27">accuracy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> accuracy_score(y_test, y_pred)</span>
<span id="cb35-28"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precisión del Perceptrón Multicapa: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>accuracy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">%"</span>)</span>
<span id="cb35-29"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Reporte de Clasificación:</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>, classification_report(y_test, y_pred))</span>
<span id="cb35-30"></span>
<span id="cb35-31"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Matriz de confusión</span></span>
<span id="cb35-32">conf_matrix <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_test, y_pred)</span>
<span id="cb35-33"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Matriz de Confusión:</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>, conf_matrix)</span>
<span id="cb35-34"></span>
<span id="cb35-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualización de algunas predicciones</span></span>
<span id="cb35-36">fig, axes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>))</span>
<span id="cb35-37"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, ax <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(axes.ravel()):</span>
<span id="cb35-38">    ax.imshow(X_test[i].reshape(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>), cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>)</span>
<span id="cb35-39">    ax.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Pred: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>y_pred[i]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb35-40">    ax.axis(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'off'</span>)</span>
<span id="cb35-41">plt.suptitle(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Predicciones de Dígitos Escritos a Mano - MLP"</span>)</span>
<span id="cb35-42">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Precisión del Perceptrón Multicapa: 98.06%

Reporte de Clasificación:
               precision    recall  f1-score   support

           0       1.00      0.97      0.98        33
           1       1.00      1.00      1.00        28
           2       1.00      1.00      1.00        33
           3       1.00      0.97      0.99        34
           4       1.00      1.00      1.00        46
           5       0.92      0.98      0.95        47
           6       0.97      0.97      0.97        35
           7       0.97      0.97      0.97        34
           8       0.97      0.97      0.97        30
           9       1.00      0.97      0.99        40

    accuracy                           0.98       360
   macro avg       0.98      0.98      0.98       360
weighted avg       0.98      0.98      0.98       360


Matriz de Confusión:
 [[32  0  0  0  0  0  0  1  0  0]
 [ 0 28  0  0  0  0  0  0  0  0]
 [ 0  0 33  0  0  0  0  0  0  0]
 [ 0  0  0 33  0  1  0  0  0  0]
 [ 0  0  0  0 46  0  0  0  0  0]
 [ 0  0  0  0  0 46  1  0  0  0]
 [ 0  0  0  0  0  1 34  0  0  0]
 [ 0  0  0  0  0  1  0 33  0  0]
 [ 0  0  0  0  0  1  0  0 29  0]
 [ 0  0  0  0  0  0  0  0  1 39]]</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/index_files/figure-html/cell-16-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="taller" class="level1">
<h1>Taller</h1>
<div id="cell-42" class="cell" data-execution_count="16">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb37-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Comentario: Celda de taller para ejercicios practicos de clase.</span></span></code></pre></div></div>
</div>
<section id="te-sirvió" class="level3">
<h3 class="anchored" data-anchor-id="te-sirvió">💬 ¿Te sirvió?</h3>
<p>Deja en los comentarios <strong>una duda o un caso donde aplicarías esto</strong> — respondo todos. Sígueme para no perderte el próximo artículo de la serie y comparte con alguien que esté aprendiendo análisis de datos.</p>
<p>👉 El código completo está disponible para ejecutar directamente.</p>


</section>
</section>

 ]]></description>
  <category>deep-learning</category>
  <category>perceptron</category>
  <category>mlp</category>
  <guid>https://biitt.com/es/blog/deep-learning/01-perceptron-mlp/</guid>
  <pubDate>Mon, 31 Aug 2026 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Evaluación de modelos: predicción, clasificación y desempeño</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/</link>
  <description><![CDATA[ 




<section id="evaluación-de-modelos-predicción-clasificación-y-desempeño" class="level1">
<h1>Evaluación de modelos: predicción, clasificación y desempeño</h1>
<p><a href="TODO_URL_GITHUB"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"></a></p>
<p>En este notebook evaluamos modelos supervisados (incluye MLP y el resto de algoritmos del curso) sobre datos independientes, para no confundir un buen ajuste en entrenamiento con buena predicción. En regresión usamos MAE, MAPE, MPE y RMSE. En clasificación usamos la matriz de confusión, sensibilidad, especificidad, F1, umbral de decisión, costos de error y AUC-ROC.</p>
<section id="sobre-el-autor" class="level2">
<h2 class="anchored" data-anchor-id="sobre-el-autor">👋 Sobre el autor</h2>
<p>Wilder Ramírez Delgado es Científico de Datos, Arquitecto de IA, Ingeniero Electrónico y Magíster en Analítica de Datos. CEO y fundador de Business Innovation Technology (BIT), consultor y docente universitario, trabaja en la intersección entre Data Science, Inteligencia Artificial, Big Data e IoT, transformando problemas reales en soluciones aplicadas.</p>
<p>De la teoría a la práctica, un problema a la vez.</p>
</section>
</section>
<section id="introducción" class="level1">
<h1>1. Introducción</h1>
<p>En el aprendizaje supervisado, nos interesa predecir la variable de resultado para nuevos registros. Existen tres tipos principales de resultados de interés:</p>
<ul>
<li><strong>Valor numérico predicho</strong>: cuando la variable de resultado es numérica (por ejemplo, el precio de una casa).</li>
<li><strong>Pertenencia a una clase predicha</strong>: cuando la variable de resultado es categórica (por ejemplo, comprador/no comprador).</li>
<li><strong>Propensión</strong>: la probabilidad de pertenencia a una clase, cuando la variable de resultado es categórica (por ejemplo, la propensión a incumplir).</li>
</ul>
<p>Los métodos de predicción se utilizan para generar predicciones numéricas, mientras que los métodos de clasificación (“clasificadores”) se utilizan para generar propensiones y, usando un valor de corte en las propensiones, podemos generar pertenencias a clases predichas.</p>
<p>Es importante tener en cuenta una distinción sutil: los clasificadores tienen dos usos predictivos distintos. Uno de ellos, la clasificación, está dirigido a predecir la pertenencia a una clase para nuevos registros. El otro, el ranking, permite detectar, entre un conjunto de nuevos registros, aquellos con mayor probabilidad de pertenecer a una clase de interés.</p>
<p>En este notebook revisaremos el enfoque para evaluar modelos de <strong>predicción numérica</strong> y de <strong>clasificación</strong>, incluyendo métricas de error, matriz de confusión, umbral de decisión y curva ROC/AUC. Los ejercicios se resuelven en el notebook <code>Taller_metricas_prediccion_clasificacion.ipynb</code>.</p>
<p><strong>Idea clave:</strong> la <strong>bondad de ajuste</strong> describe cuán bien el modelo reproduce los datos de entrenamiento, mientras que la <strong>precisión predictiva</strong> mide cuán bien funciona con datos nuevos. Un modelo puede ajustarse muy bien a los datos de entrenamiento y, sin embargo, predecir mal en datos reales si está sobreajustado.</p>
</section>
<section id="evaluación-del-rendimiento-predictivo" class="level1">
<h1>2. Evaluación del Rendimiento Predictivo</h1>
<p>Primero, cabe destacar que la precisión predictiva no es lo mismo que la bondad de ajuste. La bondad de ajuste mide qué tan bien el modelo reproduce los datos con los que fue entrenado; es decir, su capacidad para describir o ajustar la información observada. En cambio, la precisión predictiva mide qué tan bien el modelo funciona sobre datos nuevos o no vistos, que es el objetivo central en minería de datos y aprendizaje automático. Medidas como el <img src="https://latex.codecogs.com/png.latex?R%5E2"> y el error estándar de la estimación son útiles para evaluar el ajuste en los datos de entrenamiento, pero no garantizan que el modelo generalice bien. Un modelo puede tener excelente bondad de ajuste y, aun así, predecir mal en datos de validación si está sobreajustado.</p>
<p>Para evaluar el rendimiento de predicción, se utilizan varias medidas. En todos los casos, las medidas se basan en el conjunto de validación, que sirve como una base más objetiva que el conjunto de entrenamiento para evaluar la precisión predictiva. Esto se debe a que los registros en el conjunto de validación son más similares a los registros futuros que se van a predecir, en el sentido de que no se utilizan para seleccionar predictores ni para estimar los parámetros del modelo. Los modelos se entrenan con los datos de entrenamiento, se aplican a los datos de validación, y luego las medidas de precisión usan los errores de predicción en ese conjunto de validación.</p>
<section id="naive-benchmark-benchmark-ingenuo-el-promedio" class="level2">
<h2 class="anchored" data-anchor-id="naive-benchmark-benchmark-ingenuo-el-promedio">Naive Benchmark (Benchmark Ingenuo): El Promedio</h2>
<p>El criterio de referencia más simple en predicción, conocido como <strong>benchmark ingenuo</strong>, consiste en utilizar el valor promedio de la variable objetivo como predicción para todos los nuevos registros. Este enfoque ignora completamente la información de los predictores y se basa únicamente en el promedio de los valores de la variable de resultado del conjunto de entrenamiento.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbar%7By%7D"></p>
<p>Por ejemplo, si estamos intentando predecir el precio de una casa, el benchmark ingenuo predice el mismo precio promedio para cada nueva casa, sin considerar factores como la ubicación, el tamaño o el estado de la propiedad. Aunque esta técnica es muy básica y no proporciona ninguna información específica de cada registro, es útil como un punto de referencia.</p>
<p>La idea es que cualquier modelo predictivo que se desarrolle debe, como mínimo, superar esta predicción promedio en términos de precisión. En otras palabras, un buen modelo debería ser capaz de captar patrones en los datos y ofrecer predicciones que reduzcan el error promedio en comparación con este benchmark ingenuo. Si un modelo no puede mejorar sustancialmente este criterio de referencia, puede ser una señal de que el modelo no está capturando suficiente información relevante de los datos de entrada.</p>
</section>
<section id="medidas-de-precisión-de-predicción" class="level2">
<h2 class="anchored" data-anchor-id="medidas-de-precisión-de-predicción">Medidas de Precisión de Predicción</h2>
<p>El error de predicción para el registro <img src="https://latex.codecogs.com/png.latex?i"> se define como la diferencia entre su valor real y su valor predicho:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ae_i%20=%20y_i%20-%20%5Chat%7By%7D_i%0A"></p>
<p>A continuación se describen las métricas más usadas para evaluar la precisión predictiva <strong>sobre el conjunto de validación</strong> (no sobre el de entrenamiento):</p>
<ul>
<li><p><strong>MAE (Error Absoluto Medio)</strong>: magnitud promedio del error, en las mismas unidades de <img src="https://latex.codecogs.com/png.latex?y">.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BMAE%7D%20=%20%5Cfrac%7B1%7D%7Bn%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20%7Ce_i%7C%0A"></p></li>
<li><p><strong>RMSE (Raíz del Error Cuadrático Medio)</strong>: también en unidades de <img src="https://latex.codecogs.com/png.latex?y">, pero penaliza más los errores grandes.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BRMSE%7D%20=%20%5Csqrt%7B%5Cfrac%7B1%7D%7Bn%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20e_i%5E2%7D%0A"></p></li>
<li><p><strong>MAPE (Error Porcentual Absoluto Medio)</strong>: error relativo promedio. Útil para comparar escalas distintas; se vuelve inestable si algún <img src="https://latex.codecogs.com/png.latex?y_i"> es cero o muy cercano a cero.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BMAPE%7D%20=%20%5Cfrac%7B100%7D%7Bn%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20%5Cleft%7C%20%5Cfrac%7Be_i%7D%7By_i%7D%20%5Cright%7C%0A"></p></li>
<li><p><strong>MPE (Error Porcentual Medio)</strong>: igual que MAPE, pero <strong>con signo</strong>. Un MPE positivo indica subestimación promedio; uno negativo, sobreestimación.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BMPE%7D%20=%20%5Cfrac%7B100%7D%7Bn%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20%5Cfrac%7Be_i%7D%7By_i%7D%0A"></p></li>
</ul>
<p><strong>Cómo leerlas juntas:</strong> si MAE es bajo y RMSE es mucho mayor, hay pocos errores pero muy grandes. Si el modelo no mejora el MAE/RMSE del <strong>benchmark ingenuo</strong> (predecir la media de entrenamiento), todavía no está aportando valor.</p>
<p>La implementación con un ejemplo numérico y la comparación contra el promedio aparecen en la celda siguiente.</p>
<section id="implementación-mae-rmse-mape-y-mpe-frente-al-benchmark-ingenuo" class="level3">
<h3 class="anchored" data-anchor-id="implementación-mae-rmse-mape-y-mpe-frente-al-benchmark-ingenuo">2.1 Implementación: MAE, RMSE, MAPE y MPE frente al benchmark ingenuo</h3>
<p>Usamos cinco observaciones para calcular las métricas a mano con código y comparar el modelo con la predicción constante igual a la <strong>media</strong> de <img src="https://latex.codecogs.com/png.latex?y">. Un modelo útil debe reducir el error respecto a ese promedio.</p>
<div id="cell-5" class="cell" data-execution_count="28">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> (</span>
<span id="cb1-4">    mean_absolute_error,</span>
<span id="cb1-5">    mean_squared_error,</span>
<span id="cb1-6">    mean_absolute_percentage_error,</span>
<span id="cb1-7">)</span>
<span id="cb1-8"></span>
<span id="cb1-9">y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">200.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">300.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">400.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">500.0</span>])</span>
<span id="cb1-10">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">110.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">190.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">310.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">405.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">495.0</span>])</span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Benchmark ingenuo: predecir la media para todos los registros</span></span>
<span id="cb1-13">media <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_real.mean()</span>
<span id="cb1-14">y_naive <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.full_like(y_real, media)</span>
<span id="cb1-15"></span>
<span id="cb1-16">detalle <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb1-17">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y_real'</span>: y_real,</span>
<span id="cb1-18">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y_modelo'</span>: y_pred,</span>
<span id="cb1-19">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y_naive'</span>: y_naive,</span>
<span id="cb1-20">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'error_modelo'</span>: y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_pred,</span>
<span id="cb1-21">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'error_naive'</span>: y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_naive,</span>
<span id="cb1-22">})</span>
<span id="cb1-23">display(detalle)</span>
<span id="cb1-24"></span>
<span id="cb1-25"></span>
<span id="cb1-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> mpe(y_true, y_hat):</span>
<span id="cb1-27">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.mean((y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_hat) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> y_true) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span></span>
<span id="cb1-28"></span>
<span id="cb1-29"></span>
<span id="cb1-30"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> resumen_metricas(y_true, y_hat, nombre):</span>
<span id="cb1-31">    mae <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mean_absolute_error(y_true, y_hat)</span>
<span id="cb1-32">    rmse <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.sqrt(mean_squared_error(y_true, y_hat))</span>
<span id="cb1-33">    mape <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mean_absolute_percentage_error(y_true, y_hat) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span></span>
<span id="cb1-34">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> {</span>
<span id="cb1-35">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'enfoque'</span>: nombre,</span>
<span id="cb1-36">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAE'</span>: mae,</span>
<span id="cb1-37">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'RMSE'</span>: rmse,</span>
<span id="cb1-38">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAPE (%)'</span>: mape,</span>
<span id="cb1-39">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MPE (%)'</span>: mpe(y_true, y_hat),</span>
<span id="cb1-40">    }</span>
<span id="cb1-41"></span>
<span id="cb1-42"></span>
<span id="cb1-43">comparacion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame([</span>
<span id="cb1-44">    resumen_metricas(y_real, y_pred, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Modelo'</span>),</span>
<span id="cb1-45">    resumen_metricas(y_real, y_naive, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Benchmark (media)'</span>),</span>
<span id="cb1-46">])</span>
<span id="cb1-47">display(comparacion.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb1-48"></span>
<span id="cb1-49">fila_modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> comparacion.loc[comparacion[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'enfoque'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Modelo'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb1-50">fila_naive <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> comparacion.loc[comparacion[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'enfoque'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Benchmark (media)'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb1-51"></span>
<span id="cb1-52"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Media usada como benchmark: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>media<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.1f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb1-53"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(</span>
<span id="cb1-54">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"El modelo reduce el MAE de </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>fila_naive[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAE'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> a </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>fila_modelo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAE'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> "</span></span>
<span id="cb1-55">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"y el RMSE de </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>fila_naive[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'RMSE'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> a </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>fila_modelo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'RMSE'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span></span>
<span id="cb1-56">)</span>
<span id="cb1-57"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(fila_modelo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'RMSE'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> fila_modelo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAE'</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>:</span>
<span id="cb1-58">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'MAE y RMSE están cercanos: no hay errores extremos en este ejemplo.'</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">y_real</th>
<th data-quarto-table-cell-role="th">y_modelo</th>
<th data-quarto-table-cell-role="th">y_naive</th>
<th data-quarto-table-cell-role="th">error_modelo</th>
<th data-quarto-table-cell-role="th">error_naive</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>100.0</td>
<td>110.0</td>
<td>300.0</td>
<td>-10.0</td>
<td>-200.0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>200.0</td>
<td>190.0</td>
<td>300.0</td>
<td>10.0</td>
<td>-100.0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>300.0</td>
<td>310.0</td>
<td>300.0</td>
<td>-10.0</td>
<td>0.0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>400.0</td>
<td>405.0</td>
<td>300.0</td>
<td>-5.0</td>
<td>100.0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>500.0</td>
<td>495.0</td>
<td>300.0</td>
<td>5.0</td>
<td>200.0</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">enfoque</th>
<th data-quarto-table-cell-role="th">MAE</th>
<th data-quarto-table-cell-role="th">RMSE</th>
<th data-quarto-table-cell-role="th">MAPE (%)</th>
<th data-quarto-table-cell-role="th">MPE (%)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>Modelo</td>
<td>8.0</td>
<td>8.367</td>
<td>4.117</td>
<td>-1.717</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>Benchmark (media)</td>
<td>120.0</td>
<td>141.421</td>
<td>63.000</td>
<td>-37.000</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Media usada como benchmark: 300.0
El modelo reduce el MAE de 120.000 a 8.000 y el RMSE de 141.421 a 8.367.
MAE y RMSE están cercanos: no hay errores extremos en este ejemplo.</code></pre>
</div>
</div>
</section>
</section>
</section>
<section id="evaluación-del-rendimiento-en-clasificación" class="level1">
<h1>3. Evaluación del Rendimiento en Clasificación</h1>
<p>En esta sección, exploramos diferentes métodos para evaluar el rendimiento de modelos de clasificación. Estos métodos ayudan a entender qué tan bien un modelo clasifica y cómo se compara con puntos de referencia simples y métricas más completas.</p>
<section id="punto-de-referencia-regla-ingenua-naive" class="level2">
<h2 class="anchored" data-anchor-id="punto-de-referencia-regla-ingenua-naive">Punto de Referencia: Regla Ingenua (Naive)</h2>
<p>La <strong>regla ingenua</strong> establece un punto de referencia básico para evaluar el rendimiento de un modelo. En el caso de modelos de regresión, esta regla consiste en predecir el valor promedio (media) de la variable objetivo para todos los casos. Para modelos de clasificación, se predice la clase más frecuente para todas las observaciones. La idea es que cualquier modelo predictivo debería superar este punto de referencia en términos de desempeño. Al comparar el modelo con esta regla, podemos verificar si el modelo está logrando capturar patrones útiles en los datos o si simplemente está imitando un enfoque básico.</p>
</section>
<section id="separación-de-clases" class="level2">
<h2 class="anchored" data-anchor-id="separación-de-clases">Separación de Clases</h2>
<p>La <strong>separación de clases</strong> mide la capacidad de un modelo para diferenciar entre distintas clases de datos. Si las predicciones de un modelo son efectivas, debería existir una clara separación entre las clases. Para evaluarlo, se pueden utilizar gráficos de dispersión y métricas que miden la distancia entre las clases, como la distancia euclidiana. Una buena separación de clases indica que el modelo puede generalizar mejor al clasificar nuevas observaciones. Además, se pueden utilizar técnicas de reducción de dimensionalidad, como <strong>PCA (Análisis de Componentes Principales)</strong> o <strong>t-SNE</strong>, para visualizar las separaciones en conjuntos de datos de alta dimensión.</p>
</section>
<section id="matriz-de-confusión-clasificación" class="level2">
<h2 class="anchored" data-anchor-id="matriz-de-confusión-clasificación">Matriz de Confusión (Clasificación)</h2>
<p>La <strong>matriz de confusión</strong> es una herramienta clave para evaluar modelos de clasificación. Organiza los resultados en cuatro categorías: - <strong>Verdaderos Positivos (TP)</strong>: Predicciones correctas de la clase positiva. - <strong>Falsos Positivos (FP)</strong>: Predicciones incorrectas donde se clasificó como positivo, pero el resultado real fue negativo. - <strong>Verdaderos Negativos (TN)</strong>: Predicciones correctas de la clase negativa. - <strong>Falsos Negativos (FN)</strong>: Predicciones incorrectas donde se clasificó como negativo, pero el resultado real fue positivo.</p>
<p>Con la matriz de confusión, podemos calcular diversas métricas importantes: - <strong>Exactitud (Accuracy)</strong>: proporción de predicciones correctas. <img src="https://latex.codecogs.com/png.latex?%0A%20%20%5Ctext%7BExactitud%7D%20=%20%5Cfrac%7BTP%20+%20TN%7D%7BTP%20+%20TN%20+%20FP%20+%20FN%7D%0A%20%20"> - <strong>Precisión de la clase positiva (Precision)</strong>: exactitud al clasificar la clase positiva. <img src="https://latex.codecogs.com/png.latex?%0A%20%20%5Ctext%7BPrecision%7D%20=%20%5Cfrac%7BTP%7D%7BTP%20+%20FP%7D%0A%20%20"> - <strong>Sensibilidad (Recall)</strong>: capacidad del modelo para capturar correctamente los casos positivos. <img src="https://latex.codecogs.com/png.latex?%0A%20%20%5Ctext%7BRecall%7D%20=%20%5Cfrac%7BTP%7D%7BTP%20+%20FN%7D%0A%20%20"></p>
<ul>
<li><strong>Especificidad</strong>: capacidad del modelo para identificar correctamente los casos negativos. <img src="https://latex.codecogs.com/png.latex?%0A%5Ctext%7BEspecificidad%7D%20=%20%5Cfrac%7BTN%7D%7BTN%20+%20FP%7D%0A"></li>
<li><strong>F1-score</strong>: combina precisión y recall para resumir el rendimiento cuando queremos equilibrar ambos aspectos. <img src="https://latex.codecogs.com/png.latex?%0AF1%20=%202%20%5Ctimes%20%5Cfrac%7B%5Ctext%7BPrecision%7D%20%5Ctimes%20%5Ctext%7BRecall%7D%7D%7B%5Ctext%7BPrecision%7D%20+%20%5Ctext%7BRecall%7D%7D%0A"></li>
</ul>
<p>La forma más común de interpretar la matriz es la siguiente: las <strong>filas representan la clase real</strong> y las <strong>columnas representan la clase predicha</strong>. Por tanto, la diagonal principal muestra los aciertos del modelo, mientras que los valores fuera de esa diagonal indican errores de clasificación.</p>
<p>En problemas de diagnóstico, por ejemplo, la clase positiva suele ser la condición de interés (por ejemplo, enfermo, fraude o incumplimiento), mientras que la clase negativa corresponde a la ausencia de esa condición.</p>
<p>Es importante recordar que la <strong>exactitud puede ser engañosa</strong> cuando las clases están desbalanceadas. Por ejemplo, si un 95% de los casos es negativo y el modelo predice siempre “negativo”, podría obtener una exactitud muy alta aunque no detecte ninguna instancia positiva. En esos casos, métricas como recall, precision, F1-score o AUC suelen ser más informativas.</p>
<p>Además, la matriz de confusión depende del <strong>umbral de decisión</strong>. Si reducimos el umbral para considerar más casos como positivos, aumentaremos la sensibilidad pero también pueden crecer los falsos positivos. Si aumentamos el umbral, se reducen los falsos positivos, pero puede perderse capacidad para detectar casos importantes. Por eso, en problemas donde los costos de error varían (por ejemplo, diagnóstico médico o detección de fraude), la elección del umbral es parte fundamental del diseño del modelo.</p>
<p>En resumen, la matriz de confusión no solo cuenta errores: muestra exactamente qué tipo de errores comete el modelo y permite decidir si el rendimiento es aceptable para el problema del negocio o la investigación.</p>
<section id="qué-significa-cada-métrica-en-términos-simples" class="level3">
<h3 class="anchored" data-anchor-id="qué-significa-cada-métrica-en-términos-simples">3.1 ¿Qué significa cada métrica en términos simples?</h3>
<p>Antes de ver ejemplos, conviene interpretar cada métrica como una “lente” distinta del modelo:</p>
<ul>
<li><strong>Exactitud (Accuracy):</strong> porcentaje total de aciertos.
<ul>
<li><strong>Alta:</strong> en general el modelo acierta mucho.</li>
<li><strong>Baja:</strong> falla con frecuencia.</li>
<li><strong>Cuidado:</strong> puede verse “alta” en datos desbalanceados aunque ignore la clase importante.</li>
</ul></li>
<li><strong>Precisión (Precision):</strong> de todo lo que el modelo marcó como positivo, ¿cuánto era realmente positivo?
<ul>
<li><strong>Alta:</strong> pocos falsos positivos.</li>
<li><strong>Baja:</strong> muchas falsas alarmas.</li>
<li><strong>Útil cuando</strong> cuesta caro acusar un positivo que no lo era (por ejemplo, alertas innecesarias).</li>
</ul></li>
<li><strong>Sensibilidad / Recall (TPR):</strong> de los positivos reales, ¿cuántos detectó el modelo?
<ul>
<li><strong>Alta:</strong> se escapan pocos positivos (pocos FN).</li>
<li><strong>Baja:</strong> se pierden muchos casos importantes.</li>
<li><strong>Útil cuando</strong> es crítico no dejar pasar positivos reales (salud, fraude).</li>
</ul></li>
<li><strong>Especificidad (TNR):</strong> de los negativos reales, ¿cuántos detectó bien como negativos?
<ul>
<li><strong>Alta:</strong> identifica bien los negativos.</li>
<li><strong>Baja:</strong> confunde negativos con positivos (más FP).</li>
</ul></li>
<li><strong>F1-score:</strong> equilibrio entre precisión y recall.
<ul>
<li><strong>Alto:</strong> buen balance entre detectar positivos y no generar muchas falsas alarmas.</li>
<li><strong>Bajo:</strong> una de las dos (o ambas) está fallando.</li>
<li><strong>Útil en datos desbalanceados</strong> cuando no alcanza mirar solo exactitud.</li>
</ul></li>
<li><strong>AUC-ROC:</strong> capacidad global de separar clases para distintos umbrales.
<ul>
<li><strong>Cerca de 1:</strong> separación excelente.</li>
<li><strong>Cerca de 0.5:</strong> parecido al azar.</li>
<li><strong>Menor que 0.5:</strong> separación muy mala (incluso invertida).</li>
</ul></li>
</ul>
</section>
<section id="qué-podemos-inferir-de-cada-métrica-por-separado" class="level3">
<h3 class="anchored" data-anchor-id="qué-podemos-inferir-de-cada-métrica-por-separado">¿Qué podemos inferir de cada métrica por separado?</h3>
<ul>
<li>Una métrica aislada responde solo una parte del problema.</li>
<li>Ejemplo: exactitud alta no garantiza buen recall en la clase positiva.</li>
<li>Por eso, cada valor individual debe leerse según el costo del error en el contexto.</li>
</ul>
</section>
<section id="qué-podemos-inferir-al-verlas-en-conjunto" class="level3">
<h3 class="anchored" data-anchor-id="qué-podemos-inferir-al-verlas-en-conjunto">¿Qué podemos inferir al verlas en conjunto?</h3>
<ul>
<li><strong>Precision alta + Recall bajo:</strong> el modelo es “estricto”; da pocas alarmas, pero deja pasar positivos.</li>
<li><strong>Recall alto + Precision baja:</strong> detecta casi todo, pero con muchas falsas alarmas.</li>
<li><strong>Exactitud alta + F1 bajo:</strong> probable desbalance de clases o rendimiento desigual entre clases.</li>
<li><strong>AUC alto + F1 moderado/bajo:</strong> el modelo separa bien, pero el umbral actual puede no ser el adecuado.</li>
<li><strong>Recall y especificidad altas:</strong> desempeño equilibrado entre positivos y negativos.</li>
</ul>
<p>En práctica, la interpretación correcta no depende de “la mejor métrica” única, sino de la combinación de métricas y del costo real de cada tipo de error.</p>
</section>
<section id="ejemplo-1-clasificación-binaria-balanceada" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-1-clasificación-binaria-balanceada">Ejemplo 1: Clasificación Binaria Balanceada</h3>
<p>Supongamos un modelo de clasificación binaria que predice si un correo electrónico es <strong>spam</strong> o <strong>no spam</strong>. El conjunto de datos está balanceado:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 27%">
<col style="width: 32%">
<col style="width: 40%">
</colgroup>
<thead>
<tr class="header">
<th></th>
<th>Predicción: Spam</th>
<th>Predicción: No Spam</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Real: Spam</strong></td>
<td>50 (TP)</td>
<td>10 (FN)</td>
</tr>
<tr class="even">
<td><strong>Real: No Spam</strong></td>
<td>5 (FP)</td>
<td>35 (TN)</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Verdaderos Positivos (TP)</strong>: 50 (Predicciones correctas de spam)</li>
<li><strong>Falsos Positivos (FP)</strong>: 5 (Correos clasificados como spam que en realidad no lo son)</li>
<li><strong>Verdaderos Negativos (TN)</strong>: 35 (Predicciones correctas de no spam)</li>
<li><strong>Falsos Negativos (FN)</strong>: 10 (Correos que son spam pero se clasificaron como no spam)</li>
</ul>
<section id="métricas-del-ejemplo-1" class="level4">
<h4 class="anchored" data-anchor-id="métricas-del-ejemplo-1">Métricas del Ejemplo 1</h4>
<ul>
<li><strong>Exactitud (Accuracy)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%20+%20TN%7D%7BTP%20+%20TN%20+%20FP%20+%20FN%7D%20=%20%5Cfrac%7B50%20+%2035%7D%7B100%7D%20=%200.85%0A"></li>
<li><strong>Precisión (Precision)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%7D%7BTP%20+%20FP%7D%20=%20%5Cfrac%7B50%7D%7B50%20+%205%7D%20=%200.91%0A"></li>
<li><strong>Sensibilidad (Recall)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%7D%7BTP%20+%20FN%7D%20=%20%5Cfrac%7B50%7D%7B50%20+%2010%7D%20=%200.83%0A"></li>
<li><strong>Especificidad (TNR)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTN%7D%7BTN%20+%20FP%7D%20=%20%5Cfrac%7B35%7D%7B35%20+%205%7D%20=%200.88%0A"></li>
<li><strong>F1-score</strong>: <img src="https://latex.codecogs.com/png.latex?%0A2%20%5Ctimes%20%5Cfrac%7B%5Cmathrm%7BPrecision%7D%20%5Ctimes%20%5Cmathrm%7BRecall%7D%7D%7B%5Cmathrm%7BPrecision%7D%20+%20%5Cmathrm%7BRecall%7D%7D%20%5Capprox%200.87%0A"></li>
</ul>
</section>
<section id="conclusión-ejemplo-1" class="level4">
<h4 class="anchored" data-anchor-id="conclusión-ejemplo-1">Conclusión Ejemplo 1</h4>
<p>El modelo tiene rendimiento <strong>alto y equilibrado</strong>. Detecta bien los spam (recall 0.83), mantiene pocas falsas alarmas (precision 0.91) y logra una exactitud general de 0.85. Es un comportamiento esperado para un caso balanceado.</p>
<hr>
</section>
</section>
<section id="ejemplo-2-clasificación-binaria-desbalanceada" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-2-clasificación-binaria-desbalanceada">Ejemplo 2: Clasificación Binaria Desbalanceada</h3>
<p>En este caso, se utiliza un modelo para diagnosticar una enfermedad rara. La mayoría de los pacientes no tienen la enfermedad (clase negativa), y solo algunos pocos casos son positivos.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 24%">
<col style="width: 34%">
<col style="width: 40%">
</colgroup>
<thead>
<tr class="header">
<th></th>
<th>Predicción: Enfermo</th>
<th>Predicción: No Enfermo</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Real: Enfermo</strong></td>
<td>3</td>
<td>12</td>
</tr>
<tr class="even">
<td><strong>Real: No Enfermo</strong></td>
<td>5</td>
<td>80</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Verdaderos Positivos (TP)</strong>: 3 (Predicciones correctas de enfermedad)</li>
<li><strong>Falsos Positivos (FP)</strong>: 5 (Personas no enfermas pero clasificadas como enfermas)</li>
<li><strong>Verdaderos Negativos (TN)</strong>: 80 (Predicciones correctas de personas no enfermas)</li>
<li><strong>Falsos Negativos (FN)</strong>: 12 (Personas que están enfermas pero fueron clasificadas como no enfermas)</li>
</ul>
<section id="métricas-del-ejemplo-2" class="level4">
<h4 class="anchored" data-anchor-id="métricas-del-ejemplo-2">Métricas del Ejemplo 2</h4>
<ul>
<li><strong>Exactitud (Accuracy)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%20+%20TN%7D%7BTP%20+%20TN%20+%20FP%20+%20FN%7D%20=%20%5Cfrac%7B3%20+%2080%7D%7B100%7D%20=%200.83%0A"></li>
<li><strong>Precisión (Precision)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%7D%7BTP%20+%20FP%7D%20=%20%5Cfrac%7B3%7D%7B3%20+%205%7D%20=%200.38%0A"></li>
<li><strong>Sensibilidad (Recall)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTP%7D%7BTP%20+%20FN%7D%20=%20%5Cfrac%7B3%7D%7B3%20+%2012%7D%20=%200.20%0A"></li>
<li><strong>Especificidad (TNR)</strong>: <img src="https://latex.codecogs.com/png.latex?%0A%5Cfrac%7BTN%7D%7BTN%20+%20FP%7D%20=%20%5Cfrac%7B80%7D%7B80%20+%205%7D%20=%200.94%0A"></li>
<li><strong>F1-score</strong>: <img src="https://latex.codecogs.com/png.latex?%0A2%20%5Ctimes%20%5Cfrac%7B%5Cmathrm%7BPrecision%7D%20%5Ctimes%20%5Cmathrm%7BRecall%7D%7D%7B%5Cmathrm%7BPrecision%7D%20+%20%5Cmathrm%7BRecall%7D%7D%20%5Capprox%200.26%0A"></li>
</ul>
</section>
<section id="conclusión-ejemplo-2" class="level4">
<h4 class="anchored" data-anchor-id="conclusión-ejemplo-2">Conclusión Ejemplo 2</h4>
<p>Aunque la exactitud parece buena (0.83), el modelo <strong>falla en lo más importante</strong>: detectar enfermos (recall 0.20). Tiene buena capacidad para reconocer sanos (especificidad 0.94), pero pierde muchos casos positivos. En problemas médicos, este rendimiento no es aceptable sin ajustar umbral, pesos de clase o técnicas de balanceo.</p>
</section>
</section>
<section id="diferencias-clave-entre-ambos-casos" class="level3">
<h3 class="anchored" data-anchor-id="diferencias-clave-entre-ambos-casos">Diferencias clave entre ambos casos</h3>
<p>Las principales diferencias entre los dos ejemplos radican en el <strong>balance de clases</strong>, el impacto de los errores y la interpretación de las métricas.</p>
<section id="balance-de-clases" class="level4">
<h4 class="anchored" data-anchor-id="balance-de-clases">1. Balance de Clases</h4>
<ul>
<li><strong>Ejemplo 1 (Balanceado):</strong> Hay una distribución relativamente equitativa entre <strong>spam</strong> y <strong>no spam</strong> (60 spam y 40 no spam).<br>
</li>
<li><strong>Ejemplo 2 (Desbalanceado):</strong> La cantidad de pacientes <strong>enfermos</strong> es mucho menor que la de <strong>no enfermos</strong> (15 enfermos y 85 no enfermos).</li>
</ul>
</section>
<section id="impacto-de-los-errores" class="level4">
<h4 class="anchored" data-anchor-id="impacto-de-los-errores">2. Impacto de los Errores</h4>
<ul>
<li><strong>Ejemplo 1:</strong> Los errores <strong>FN (10 casos)</strong> y <strong>FP (5 casos)</strong> afectan la exactitud del modelo, pero no generan un impacto crítico.<br>
</li>
<li><strong>Ejemplo 2:</strong> Los <strong>FN (12 casos)</strong> pueden ser críticos, ya que se están diagnosticando personas enfermas como sanas, lo que puede tener consecuencias graves.</li>
</ul>
</section>
<section id="exactitud-y-sensibilidad" class="level4">
<h4 class="anchored" data-anchor-id="exactitud-y-sensibilidad">3. Exactitud y Sensibilidad</h4>
<ul>
<li><strong>Ejemplo 1:</strong> La exactitud y la sensibilidad son relativamente equilibradas, ya que hay suficientes ejemplos en ambas clases.<br>
</li>
<li><strong>Ejemplo 2:</strong> La <strong>sensibilidad (TPR)</strong> es baja porque hay muchos <strong>FN</strong>, lo que significa que el modelo <strong>no está identificando bien a los enfermos</strong>. En escenarios médicos, esto es un problema grave.</li>
</ul>
</section>
<section id="estrategia-de-evaluación" class="level4">
<h4 class="anchored" data-anchor-id="estrategia-de-evaluación">4. Estrategia de Evaluación</h4>
<ul>
<li><strong>Ejemplo 1:</strong> Se pueden usar métricas estándar como <strong>exactitud</strong> y <strong>F1-score</strong> para evaluar el modelo.<br>
</li>
<li><strong>Ejemplo 2:</strong> Dado el desbalance de clases, <strong>exactitud</strong> no es una buena métrica, ya que el modelo puede parecer bueno solo por clasificar a la mayoría como <strong>no enfermos</strong>.
<ul>
<li>Es mejor usar <strong>sensibilidad (recall)</strong> o <strong>AUC-ROC</strong> para evaluar qué tan bien detecta los casos positivos.</li>
</ul></li>
</ul>
</section>
<section id="conclusión" class="level4">
<h4 class="anchored" data-anchor-id="conclusión">Conclusión</h4>
<ul>
<li><strong>En el caso balanceado</strong>, el modelo puede ser evaluado con métricas estándar como exactitud, recall y F1-score sin problemas.<br>
</li>
<li><strong>En el caso desbalanceado</strong>, se deben usar métricas que prioricen la detección de la clase minoritaria (como recall y ROC-AUC) y posiblemente aplicar estrategias de balanceo de datos como <strong>sobremuestreo</strong> o <strong>ajuste de pesos en la función de pérdida</strong> para mejorar la detección de la clase menos representada.</li>
</ul>
<hr>
</section>
</section>
<section id="ejemplo-3-clasificación-multiclase" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-3-clasificación-multiclase">Ejemplo 3: Clasificación Multiclase</h3>
<p>Supongamos un modelo que clasifica entre <strong>gato</strong>, <strong>perro</strong>, y <strong>conejo</strong>. Este es un ejemplo de clasificación multiclase:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 20%">
<col style="width: 24%">
<col style="width: 26%">
<col style="width: 28%">
</colgroup>
<thead>
<tr class="header">
<th></th>
<th>Predicción: Gato</th>
<th>Predicción: Perro</th>
<th>Predicción: Conejo</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Real: Gato</strong></td>
<td>40</td>
<td>5</td>
<td>10</td>
</tr>
<tr class="even">
<td><strong>Real: Perro</strong></td>
<td>3</td>
<td>30</td>
<td>2</td>
</tr>
<tr class="odd">
<td><strong>Real: Conejo</strong></td>
<td>4</td>
<td>6</td>
<td>50</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Gatos</strong>: 40 fueron correctamente clasificados como gatos, 5 fueron mal clasificados como perros, y 10 como conejos.</li>
<li><strong>Perros</strong>: 30 fueron correctamente clasificados como perros, 3 se confundieron con gatos, y 2 con conejos.</li>
<li><strong>Conejos</strong>: 50 fueron correctamente clasificados, 4 se confundieron con gatos, y 6 con perros.</li>
</ul>
<p>En este caso, la diagonal principal (40, 30, 50) contiene los valores de predicciones correctas para cada clase, mientras que los valores fuera de la diagonal representan los errores de clasificación.</p>
<section id="métricas-del-ejemplo-3" class="level4">
<h4 class="anchored" data-anchor-id="métricas-del-ejemplo-3">Métricas del Ejemplo 3</h4>
<p>A partir de la matriz de confusión del ejemplo:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Bbmatrix%7D%0A40%20&amp;%205%20&amp;%2010%20%5C%5C%0A3%20&amp;%2030%20&amp;%202%20%5C%5C%0A4%20&amp;%206%20&amp;%2050%0A%5Cend%7Bbmatrix%7D%0A"></p>
<ul>
<li><p>Total de muestras: <img src="https://latex.codecogs.com/png.latex?150"></p></li>
<li><p>Aciertos (diagonal): <img src="https://latex.codecogs.com/png.latex?40%20+%2030%20+%2050%20=%20120"></p></li>
<li><p><strong>Exactitud global</strong>: <img src="https://latex.codecogs.com/png.latex?%0AAccuracy%20=%20%5Cfrac%7B120%7D%7B150%7D%20=%200.80%0A"></p></li>
<li><p><strong>Clase gato</strong></p>
<ul>
<li>Precision: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B40%7D%7B40+3+4%7D%20=%20%5Cfrac%7B40%7D%7B47%7D%20%5Capprox%200.85"></li>
<li>Recall: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B40%7D%7B40+5+10%7D%20=%20%5Cfrac%7B40%7D%7B55%7D%20%5Capprox%200.73"></li>
<li>F1-score: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.78"></li>
</ul></li>
<li><p><strong>Clase perro</strong></p>
<ul>
<li>Precision: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B30%7D%7B5+30+6%7D%20=%20%5Cfrac%7B30%7D%7B41%7D%20%5Capprox%200.73"></li>
<li>Recall: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B30%7D%7B3+30+2%7D%20=%20%5Cfrac%7B30%7D%7B35%7D%20%5Capprox%200.86"></li>
<li>F1-score: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.79"></li>
</ul></li>
<li><p><strong>Clase conejo</strong></p>
<ul>
<li>Precision: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B50%7D%7B10+2+50%7D%20=%20%5Cfrac%7B50%7D%7B62%7D%20%5Capprox%200.81"></li>
<li>Recall: <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B50%7D%7B4+6+50%7D%20=%20%5Cfrac%7B50%7D%7B60%7D%20%5Capprox%200.83"></li>
<li>F1-score: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.82"></li>
</ul></li>
<li><p><strong>Promedios macro</strong></p>
<ul>
<li>Macro precision: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.80"></li>
<li>Macro recall: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.81"></li>
<li>Macro F1: <img src="https://latex.codecogs.com/png.latex?%5Capprox%200.80"></li>
</ul></li>
</ul>
</section>
<section id="conclusión-ejemplo-3" class="level4">
<h4 class="anchored" data-anchor-id="conclusión-ejemplo-3">Conclusión Ejemplo 3</h4>
<p>El modelo tiene un desempeño <strong>bueno y relativamente equilibrado</strong> en las tres clases (accuracy 0.80 y macro-F1 cercano a 0.80). La clase con más dificultad es <strong>gato</strong> en recall (0.73), lo que sugiere que algunos gatos se confunden con perro o conejo. En conjunto, el sistema clasifica bien, pero aún se puede mejorar reduciendo esas confusiones entre clases específicas.</p>
<hr>
</section>
</section>
<section id="interpretación-de-los-ejemplos" class="level3">
<h3 class="anchored" data-anchor-id="interpretación-de-los-ejemplos">Interpretación de los Ejemplos</h3>
<ul>
<li>La <strong>diagonal principal</strong> en cada matriz representa las predicciones correctas.</li>
<li>Los valores <strong>fuera de la diagonal principal</strong> son errores de predicción:
<ul>
<li>En <strong>clasificación binaria</strong>, los <strong>falsos negativos</strong> pueden indicar que el modelo omite casos importantes (por ejemplo, casos de enfermedad).</li>
<li>En <strong>clasificación multiclase</strong>, los valores fuera de la diagonal ayudan a entender en qué clases específicas el modelo tiende a confundirse.</li>
</ul></li>
</ul>
<p>Estos ejemplos muestran cómo la matriz de confusión permite evaluar y ajustar el modelo para mejorar su exactitud y sensibilidad según el contexto del problema.</p>
</section>
</section>
<section id="validación-costos-y-clases-de-distinta-importancia" class="level2">
<h2 class="anchored" data-anchor-id="validación-costos-y-clases-de-distinta-importancia">3.2 Validación, costos y clases de distinta importancia</h2>
<section id="uso-de-datos-de-validación" class="level3">
<h3 class="anchored" data-anchor-id="uso-de-datos-de-validación">Uso de datos de validación</h3>
<p>Después de entrenar, el modelo se evalúa en <strong>validación</strong> (datos no usados para ajustar parámetros). Si el error en entrenamiento es mucho menor que en validación, hay <strong>sobreajuste</strong>: el modelo memorizó el conjunto de ajuste y no generaliza.</p>
<p>En el ejemplo de Iris (apartado 3.3) se imprimen la exactitud de entrenamiento y la de prueba para ver esa brecha.</p>
</section>
<section id="costos-de-error" class="level3">
<h3 class="anchored" data-anchor-id="costos-de-error">Costos de error</h3>
<p>La exactitud trata por igual un falso positivo y un falso negativo. En la práctica no es así. Si un FN cuesta 100 y un FP cuesta 10, el costo esperado es:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AC%20=%20100%20%5Ccdot%20FN%20+%2010%20%5Ccdot%20FP%0A"></p>
<p>Conviene elegir el umbral (o el modelo) que <strong>minimiza ese costo</strong>, no el que maximiza accuracy. Cómo se pasa de una probabilidad a una etiqueta, y por qué el corte 0.50 no es sagrado, se desarrolla en la <strong>sección 4</strong>.</p>
</section>
<section id="rendimiento-con-importancia-desigual-de-clases" class="level3">
<h3 class="anchored" data-anchor-id="rendimiento-con-importancia-desigual-de-clases">Rendimiento con importancia desigual de clases</h3>
<p>Cuando falla un positivo real es especialmente grave (enfermedad, fraude), la métrica guía es la <strong>sensibilidad</strong>:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Ctext%7BSensibilidad%7D%20=%20%5Cfrac%7BTP%7D%7BTP%20+%20FN%7D%0A"></p>
<p>La <strong>especificidad</strong> resume qué tan bien se reconocen los negativos. El equilibrio entre ambas se decide con el umbral y con los costos del problema.</p>
</section>
<section id="implementación-práctica-matriz-de-confusión-multiclase-iris" class="level3">
<h3 class="anchored" data-anchor-id="implementación-práctica-matriz-de-confusión-multiclase-iris">3.3 Implementación práctica: matriz de confusión multiclase (Iris)</h3>
<p>Entrenamos un bosque aleatorio <strong>deliberadamente limitado</strong> (<code>max_depth=2</code>) sobre Iris. El objetivo no es el mejor modelo, sino ver errores reales entre <em>versicolor</em> y <em>virginica</em>, y comparar exactitud de entrenamiento frente a prueba.</p>
<div id="cell-11" class="cell" data-execution_count="29">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb3-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> confusion_matrix, classification_report, accuracy_score</span>
<span id="cb3-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb3-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb3-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_iris</span>
<span id="cb3-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.model_selection <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> train_test_split</span>
<span id="cb3-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.ensemble <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> RandomForestClassifier</span>
<span id="cb3-8"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.dummy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> DummyClassifier</span>
<span id="cb3-9"></span>
<span id="cb3-10">iris <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_iris()</span>
<span id="cb3-11">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> iris.data</span>
<span id="cb3-12">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> iris.target</span>
<span id="cb3-13"></span>
<span id="cb3-14">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(</span>
<span id="cb3-15">    X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, stratify<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>y</span>
<span id="cb3-16">)</span>
<span id="cb3-17"></span>
<span id="cb3-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Modelo limitado a propósito para que aparezcan errores en la matriz</span></span>
<span id="cb3-19">clf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> RandomForestClassifier(</span>
<span id="cb3-20">    n_estimators<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, max_depth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb3-21">)</span>
<span id="cb3-22">clf.fit(X_train, y_train)</span>
<span id="cb3-23"></span>
<span id="cb3-24">y_pred_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> clf.predict(X_train)</span>
<span id="cb3-25">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> clf.predict(X_test)</span>
<span id="cb3-26"></span>
<span id="cb3-27">naive <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> DummyClassifier(strategy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'most_frequent'</span>)</span>
<span id="cb3-28">naive.fit(X_train, y_train)</span>
<span id="cb3-29">acc_naive <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> accuracy_score(y_test, naive.predict(X_test))</span>
<span id="cb3-30">acc_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> accuracy_score(y_train, y_pred_train)</span>
<span id="cb3-31">acc_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> accuracy_score(y_test, y_pred)</span>
<span id="cb3-32"></span>
<span id="cb3-33"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Exactitud entrenamiento: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_train<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb3-34"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Exactitud prueba:        </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb3-35"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Benchmark (clase más frecuente): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_naive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb3-36"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> acc_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> acc_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>:</span>
<span id="cb3-37">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'La brecha train/prueba sugiere algo de sobreajuste o un modelo inestable.'</span>)</span>
<span id="cb3-38"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb3-39">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'La brecha train/prueba es moderada en este ejemplo.'</span>)</span>
<span id="cb3-40"></span>
<span id="cb3-41">cm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_test, y_pred)</span>
<span id="cb3-42">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb3-43">sns.heatmap(</span>
<span id="cb3-44">    cm,</span>
<span id="cb3-45">    annot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb3-46">    fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'d'</span>,</span>
<span id="cb3-47">    cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Blues'</span>,</span>
<span id="cb3-48">    xticklabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>iris.target_names,</span>
<span id="cb3-49">    yticklabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>iris.target_names</span>
<span id="cb3-50">)</span>
<span id="cb3-51">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Predicción'</span>)</span>
<span id="cb3-52">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Real'</span>)</span>
<span id="cb3-53">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Matriz de Confusión (Iris, profundidad 2)'</span>)</span>
<span id="cb3-54">plt.show()</span>
<span id="cb3-55"></span>
<span id="cb3-56">report <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> classification_report(</span>
<span id="cb3-57">    y_test,</span>
<span id="cb3-58">    y_pred,</span>
<span id="cb3-59">    target_names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>iris.target_names,</span>
<span id="cb3-60">    output_dict<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb3-61">    zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb3-62">)</span>
<span id="cb3-63"></span>
<span id="cb3-64">reporte_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(report).T</span>
<span id="cb3-65">reporte_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> reporte_df.rename(</span>
<span id="cb3-66">    columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{</span>
<span id="cb3-67">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'precision'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Precisión'</span>,</span>
<span id="cb3-68">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'recall'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Recall'</span>,</span>
<span id="cb3-69">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1-score'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'F1-score'</span>,</span>
<span id="cb3-70">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'support'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Soporte'</span></span>
<span id="cb3-71">    }</span>
<span id="cb3-72">)</span>
<span id="cb3-73">filas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(iris.target_names) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'macro avg'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weighted avg'</span>]</span>
<span id="cb3-74">reporte_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> reporte_df.loc[filas]</span>
<span id="cb3-75">reporte_df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Soporte'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> reporte_df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Soporte'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb3-76">display(reporte_df[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Precisión'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Recall'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'F1-score'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Soporte'</span>]].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb3-77"></span>
<span id="cb3-78"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">Exactitud global (prueba): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb3-79"></span>
<span id="cb3-80">macro_f1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> report[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'macro avg'</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1-score'</span>]</span>
<span id="cb3-81">recall_por_clase <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {clase: report[clase][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'recall'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> clase <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> iris.target_names}</span>
<span id="cb3-82">min_recall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>(recall_por_clase.values())</span>
<span id="cb3-83">clases_min_recall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [c <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> c, r <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> recall_por_clase.items() <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> min_recall]</span>
<span id="cb3-84"></span>
<span id="cb3-85"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Conclusión del ejemplo multiclase:'</span>)</span>
<span id="cb3-86"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'- Exactitud en prueba: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> (superó al benchmark </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_naive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">).'</span>)</span>
<span id="cb3-87"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'- F1 macro: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>macro_f1<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">.'</span>)</span>
<span id="cb3-88"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(clases_min_recall) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(iris.target_names):</span>
<span id="cb3-89">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'- Todas las clases tienen el mismo recall.'</span>)</span>
<span id="cb3-90"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb3-91">    clases_txt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span>.join(clases_min_recall)</span>
<span id="cb3-92">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(</span>
<span id="cb3-93">        <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"- La(s) clase(s) con menor recall: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>clases_txt<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>min_recall<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">). "</span></span>
<span id="cb3-94">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Ahí se concentran las confusiones (típicamente versicolor/virginica).'</span></span>
<span id="cb3-95">    )</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Exactitud entrenamiento: 0.971
Exactitud prueba:        0.889
Benchmark (clase más frecuente): 0.333
La brecha train/prueba sugiere algo de sobreajuste o un modelo inestable.</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-3-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">Precisión</th>
<th data-quarto-table-cell-role="th">Recall</th>
<th data-quarto-table-cell-role="th">F1-score</th>
<th data-quarto-table-cell-role="th">Soporte</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">setosa</th>
<td>1.000</td>
<td>1.000</td>
<td>1.000</td>
<td>15</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">versicolor</th>
<td>0.778</td>
<td>0.933</td>
<td>0.848</td>
<td>15</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">virginica</th>
<td>0.917</td>
<td>0.733</td>
<td>0.815</td>
<td>15</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">macro avg</th>
<td>0.898</td>
<td>0.889</td>
<td>0.888</td>
<td>45</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">weighted avg</th>
<td>0.898</td>
<td>0.889</td>
<td>0.888</td>
<td>45</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>
Exactitud global (prueba): 0.889

Conclusión del ejemplo multiclase:
- Exactitud en prueba: 0.889 (superó al benchmark 0.333).
- F1 macro: 0.888.
- La(s) clase(s) con menor recall: virginica (0.733). Ahí se concentran las confusiones (típicamente versicolor/virginica).</code></pre>
</div>
</div>
</section>
</section>
</section>
<section id="del-modelo-a-la-matriz-de-confusión-probabilidades-umbral-y-decisión" class="level1">
<h1>4. Del modelo a la matriz de confusión: probabilidades, umbral y decisión</h1>
<p>Junto a las métricas de la sección 3 (<strong>accuracy, precision, recall, F1</strong>), hay que ver <strong>cómo</strong> aparecen los TP, FP, FN y TN. Una confusión frecuente es pensar que el modelo predice de entrada <code>0</code> o <code>1</code>. El método <code>predict()</code> muestra clases, pero muchos clasificadores producen primero un <strong>score o una probabilidad</strong>.</p>
<p>El proceso es:</p>
<p><strong>Modelo → probabilidad → umbral → predicción (0/1) → matriz de confusión</strong></p>
<hr>
<section id="problema-que-queremos-resolver" class="level2">
<h2 class="anchored" data-anchor-id="problema-que-queremos-resolver">4.1 Problema que queremos resolver</h2>
<p>Una entidad financiera quiere estimar el <strong>riesgo de incumplimiento</strong> de sus clientes.</p>
<ul>
<li><code>0</code> → el cliente <strong>no incumple</strong>.</li>
<li><code>1</code> → el cliente <strong>incumple</strong>.</li>
</ul>
<p>Entradas típicas: ingreso, nivel de deuda, etc. El modelo estima la posibilidad de incumplimiento a partir de esas características.</p>
<hr>
</section>
<section id="entrenamiento-del-modelo" class="level2">
<h2 class="anchored" data-anchor-id="entrenamiento-del-modelo">4.2 Entrenamiento del modelo</h2>
<p>Se usan dos elementos:</p>
<ul>
<li><code>X</code>: características;</li>
<li><code>y</code>: resultado real conocido.</li>
</ul>
<pre class="text"><code>Características del cliente (X)
          │
          ▼
        MODELO
          │  aprende con y
          ▼
Resultado conocido (y)</code></pre>
<p>En Python:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1">modelo.fit(X_train, y_train)</span></code></pre></div></div>
<p><code>fit()</code> es el <strong>entrenamiento</strong>: el algoritmo busca relaciones entre <code>X_train</code> e <code>y_train</code>. Después se aplica a observaciones que <strong>no</strong> participaron en ese ajuste (validación o prueba, sección 3.2).</p>
<hr>
</section>
<section id="el-modelo-genera-probabilidades" class="level2">
<h2 class="anchored" data-anchor-id="el-modelo-genera-probabilidades">4.3 El modelo genera probabilidades</h2>
<p>Para varios clasificadores se puede pedir la probabilidad de cada clase. La de la clase positiva (incumplir) suele ser:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1">prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.predict_proba(X_test)[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]</span></code></pre></div></div>
<p>Ejemplo:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: right;">Cliente</th>
<th style="text-align: right;">Probabilidad de incumplimiento</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">1</td>
<td style="text-align: right;">0.15</td>
</tr>
<tr class="even">
<td style="text-align: right;">2</td>
<td style="text-align: right;">0.79</td>
</tr>
<tr class="odd">
<td style="text-align: right;">3</td>
<td style="text-align: right;">0.04</td>
</tr>
<tr class="even">
<td style="text-align: right;">4</td>
<td style="text-align: right;">0.91</td>
</tr>
<tr class="odd">
<td style="text-align: right;">5</td>
<td style="text-align: right;">0.42</td>
</tr>
<tr class="even">
<td style="text-align: right;">6</td>
<td style="text-align: right;">0.73</td>
</tr>
</tbody>
</table>
<p>Interpretación: el cliente 2 tiene una probabilidad estimada del <strong>79 %</strong>. Todavía <strong>no</strong> lo hemos clasificado como <code>0</code> o <code>1</code>.</p>
<pre class="text"><code>Cliente → MODELO → 0.79</code></pre>
<p>La pregunta pendiente: <strong>¿0.79 basta para declararlo incumplidor?</strong> Eso lo responde el <strong>umbral</strong>.</p>
<hr>
</section>
<section id="qué-es-el-umbral" class="level2">
<h2 class="anchored" data-anchor-id="qué-es-el-umbral">4.4 ¿Qué es el umbral?</h2>
<p>El <strong>umbral</strong> convierte la probabilidad en una decisión. Un punto de partida habitual (no obligatorio) es <code>0.50</code>:</p>
<pre class="text"><code>Probabilidad &lt;  0.50 → clase 0 (no incumple)
Probabilidad &gt;= 0.50 → clase 1 (incumple)</code></pre>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1">umbral <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span></span>
<span id="cb11-2">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> umbral).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span></code></pre></div></div>
<p><code>prob &gt;= umbral</code> produce <code>True</code>/<code>False</code>; <code>.astype(int)</code> los pasa a <code>1</code>/<code>0</code>.</p>
<hr>
</section>
<section id="de-la-probabilidad-a-la-decisión" class="level2">
<h2 class="anchored" data-anchor-id="de-la-probabilidad-a-la-decisión">4.5 De la probabilidad a la decisión</h2>
<p>Con umbral <code>0.50</code>:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: right;">Cliente</th>
<th style="text-align: right;">Probabilidad</th>
<th>Comparación</th>
<th style="text-align: right;">Predicción</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">1</td>
<td style="text-align: right;">0.15</td>
<td>0.15 &lt; 0.50</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">2</td>
<td style="text-align: right;">0.79</td>
<td>0.79 ≥ 0.50</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: right;">3</td>
<td style="text-align: right;">0.04</td>
<td>0.04 &lt; 0.50</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">4</td>
<td style="text-align: right;">0.91</td>
<td>0.91 ≥ 0.50</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: right;">5</td>
<td style="text-align: right;">0.42</td>
<td>0.42 &lt; 0.50</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">6</td>
<td style="text-align: right;">0.73</td>
<td>0.73 ≥ 0.50</td>
<td style="text-align: right;">1</td>
</tr>
</tbody>
</table>
<p>Recorrido para el cliente 2:</p>
<pre class="text"><code>MODELO → probabilidad 0.79 → ¿0.79 ≥ 0.50? → sí → predicción = 1
       → comparar con el valor real → entra en la MATRIZ DE CONFUSIÓN</code></pre>
<hr>
</section>
<section id="dónde-aparece-la-matriz-de-confusión" class="level2">
<h2 class="anchored" data-anchor-id="dónde-aparece-la-matriz-de-confusión">4.6 ¿Dónde aparece la matriz de confusión?</h2>
<p><strong>Después</strong> de convertir probabilidades en decisiones.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> confusion_matrix</span>
<span id="cb13-2">matriz <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_test, y_pred)</span></code></pre></div></div>
<p>Compara <code>y_test</code> (real) con <code>y_pred</code> (decisión). No calcula probabilidades ni elige el umbral.</p>
<blockquote class="blockquote">
<p><strong>La matriz de confusión no decide. Evalúa decisiones que ya se tomaron.</strong></p>
</blockquote>
<hr>
</section>
<section id="qué-ocurre-si-cambiamos-el-umbral" class="level2">
<h2 class="anchored" data-anchor-id="qué-ocurre-si-cambiamos-el-umbral">4.7 ¿Qué ocurre si cambiamos el umbral?</h2>
<p>Misma probabilidad <code>0.79</code>:</p>
<ul>
<li>umbral <code>0.50</code> → <code>0.79 ≥ 0.50</code> → predicción <code>1</code></li>
<li>umbral <code>0.80</code> → <code>0.79 ≥ 0.80</code> → predicción <code>0</code></li>
</ul>
<p><strong>El modelo no cambió. La probabilidad sigue siendo 0.79.</strong> Solo cambió la regla de decisión.</p>
<hr>
</section>
<section id="comparación-de-umbrales" class="level2">
<h2 class="anchored" data-anchor-id="comparación-de-umbrales">4.8 Comparación de umbrales</h2>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: right;">Probabilidad</th>
<th style="text-align: right;">Umbral 0.30</th>
<th style="text-align: right;">Umbral 0.50</th>
<th style="text-align: right;">Umbral 0.80</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">0.15</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">0.79</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: right;">0.04</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">0.91</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: right;">0.42</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: right;">0.73</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
<p>Una misma probabilidad puede producir <strong>distinta clase</strong> según el corte.</p>
<hr>
</section>
<section id="disminuir-el-umbral" class="level2">
<h2 class="anchored" data-anchor-id="disminuir-el-umbral">4.9 Disminuir el umbral</h2>
<p>Pasar de <code>0.50</code> a <code>0.30</code> hace más fácil marcar positivos. Ejemplo: <code>0.42</code> pasa de clase 0 a clase 1.</p>
<blockquote class="blockquote">
<p>Al bajar el umbral suelen aumentar las predicciones positivas: potencialmente más <strong>TP</strong> y más <strong>FP</strong> (más sensibilidad, más falsas alarmas).</p>
</blockquote>
<hr>
</section>
<section id="aumentar-el-umbral" class="level2">
<h2 class="anchored" data-anchor-id="aumentar-el-umbral">4.10 Aumentar el umbral</h2>
<p>Pasar de <code>0.50</code> a <code>0.80</code> exige más evidencia. <code>0.73</code> pasa de clase 1 a clase 0.</p>
<blockquote class="blockquote">
<p>Al subir el umbral suelen caer las predicciones positivas: potencialmente menos <strong>FP</strong> y más <strong>FN</strong>.</p>
</blockquote>
<hr>
</section>
<section id="el-umbral-depende-del-problema" class="level2">
<h2 class="anchored" data-anchor-id="el-umbral-depende-del-problema">4.11 El umbral depende del problema</h2>
<p><code>0.50</code> es una referencia, no un óptimo universal. Cuenta el <strong>costo de cada error</strong> (sección 3.2).</p>
<ul>
<li>En <strong>cribado médico</strong>, un FN (enfermo clasificado sano) suele ser muy grave: a menudo se <strong>baja</strong> el umbral y se aceptan más FP, que luego se confirman con otra prueba.</li>
<li>Si un FP tiene consecuencias graves para una persona, puede convenir un umbral <strong>más alto</strong>.</li>
</ul>
<hr>
</section>
<section id="idea-fundamental" class="level2">
<h2 class="anchored" data-anchor-id="idea-fundamental">4.12 Idea fundamental</h2>
<pre class="text"><code>DATOS → MODELO → SCORE / PROBABILIDAD → UMBRAL → DECISIÓN 0/1
      → comparación con la realidad → MATRIZ DE CONFUSIÓN
      → accuracy, precision, recall, F1, ...</code></pre>
<ul>
<li><strong>El modelo estima</strong> (score o probabilidad).</li>
<li><strong>El umbral decide</strong> (clase 0 o 1).</li>
<li><strong>La matriz evalúa</strong> (TP, TN, FP, FN).</li>
</ul>
<blockquote class="blockquote">
<p><strong>El modelo estima. El umbral decide. La matriz de confusión evalúa.</strong></p>
</blockquote>
<hr>
</section>
<section id="de-un-umbral-a-una-matriz-de-muchas-matrices-a-la-roc" class="level2">
<h2 class="anchored" data-anchor-id="de-un-umbral-a-una-matriz-de-muchas-matrices-a-la-roc">4.13 De un umbral a una matriz; de muchas matrices a la ROC</h2>
<p>Si solo se tiene la matriz de recuentos, <strong>no se recuperan</strong> las probabilidades. Esa matriz es el resultado <strong>después de un umbral</strong>. Convención habitual (como en <code>sklearn</code>): filas = clase real, columnas = clase predicha.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Bbmatrix%7D%0ATN%20&amp;%20FP%20%5C%5C%0AFN%20&amp;%20TP%0A%5Cend%7Bbmatrix%7D%0A"></p>
<p>Para probar otros cortes hay que conservar los scores o <code>predict_proba()</code>.</p>
<p>La cadena, con rigor, es esta:</p>
<ol type="1">
<li>El modelo produce un score o probabilidad <img src="https://latex.codecogs.com/png.latex?p_i"> para cada observación.</li>
<li>Un umbral <img src="https://latex.codecogs.com/png.latex?%5Ctau"> define <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D_i%20=%201"> si <img src="https://latex.codecogs.com/png.latex?p_i%20%5Cgeq%20%5Ctau">, y <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D_i%20=%200"> en caso contrario.</li>
<li>Al cambiar <img src="https://latex.codecogs.com/png.latex?%5Ctau"> cambian las predicciones <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D">.</li>
<li>Al cambiar <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"> cambian <img src="https://latex.codecogs.com/png.latex?TP">, <img src="https://latex.codecogs.com/png.latex?TN">, <img src="https://latex.codecogs.com/png.latex?FP"> y <img src="https://latex.codecogs.com/png.latex?FN">: <strong>cada umbral induce, en general, una matriz de confusión distinta</strong>.</li>
<li>De cada matriz se calculan</li>
</ol>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BTPR%7D(%5Ctau)=%5Cfrac%7BTP(%5Ctau)%7D%7BTP(%5Ctau)+FN(%5Ctau)%7D,%20%5Cqquad%0A%5Cmathrm%7BFPR%7D(%5Ctau)=%5Cfrac%7BFP(%5Ctau)%7D%7BFP(%5Ctau)+TN(%5Ctau)%7D.%0A"></p>
<ol start="6" type="1">
<li>La curva ROC es el conjunto de pares <img src="https://latex.codecogs.com/png.latex?(%5Cmathrm%7BFPR%7D(%5Ctau),%5C%20%5Cmathrm%7BTPR%7D(%5Ctau))"> al recorrer <img src="https://latex.codecogs.com/png.latex?%5Ctau">.</li>
</ol>
<blockquote class="blockquote">
<p>Una única matriz de confusión describe el comportamiento del clasificador <strong>para un umbral concreto</strong>. Para construir la curva ROC se recorren <strong>múltiples umbrales</strong>. Cada umbral produce nuevas predicciones y, por tanto, nuevos valores de TP, FP, TN y FN. A partir de ellos se calculan TPR y FPR. Cada par (FPR, TPR) corresponde a <strong>un punto</strong> de la curva ROC.</p>
</blockquote>
<p>No basta decir que «la ROC sale de la matriz»: sale de <strong>una familia de matrices</strong>, una por umbral, construidas todas con el <strong>mismo</strong> vector de scores.</p>
<hr>
</section>
<section id="hacia-la-práctica-y-hacia-la-sección-5" class="level2">
<h2 class="anchored" data-anchor-id="hacia-la-práctica-y-hacia-la-sección-5">4.14 Hacia la práctica y hacia la sección 5</h2>
<p>Si <img src="https://latex.codecogs.com/png.latex?0.50"> no tiene por qué ser el mejor corte, la pregunta operativa es: <strong>qué le ocurre a la matriz, y a TPR y FPR, cuando cambiamos <img src="https://latex.codecogs.com/png.latex?%5Ctau"></strong>. El ejemplo 4.15 lo muestra con tres cortes. Recorrer <strong>todos</strong> los cortes posibles es exactamente el objeto de la <strong>curva ROC</strong>.</p>
<section id="práctica-riesgo-de-incumplimiento-tres-umbrales-y-tres-matrices" class="level3">
<h3 class="anchored" data-anchor-id="práctica-riesgo-de-incumplimiento-tres-umbrales-y-tres-matrices">4.15 Práctica: riesgo de incumplimiento, tres umbrales y tres matrices</h3>
<p>Caso: un conjunto pequeño de clientes con <strong>ingreso</strong>, <strong>deuda</strong> e <strong>incumplió</strong> (<img src="https://latex.codecogs.com/png.latex?1"> = incumplimiento). Entrenamos una regresión logística <strong>solo para hacer visible el mecanismo</strong>. En un ejercicio de evaluación honesta se usaría validación (sección 3.2); aquí el objetivo es ver de dónde salen las <img src="https://latex.codecogs.com/png.latex?p_i"> y cómo el umbral las convierte en clase.</p>
<p>Las columnas de probabilidad salen de <code>predict_proba</code>: <strong>las produce el modelo</strong>, no la matriz de confusión. La matriz aparece <strong>después</strong>, cuando ya hay <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D">.</p>
<div id="cell-14" class="cell" data-execution_count="30">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb15-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb15-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb15-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb15-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> LogisticRegression</span>
<span id="cb15-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> confusion_matrix, precision_score, recall_score</span>
<span id="cb15-7"></span>
<span id="cb15-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Datos didácticos (reproducibles): ingreso, deuda e incumplimiento</span></span>
<span id="cb15-9">datos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb15-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso"</span>: [</span>
<span id="cb15-11">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3144</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2173</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3390</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2922</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1173</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3729</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3107</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3180</span>,</span>
<span id="cb15-12">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1272</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2206</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1975</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3588</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2767</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3286</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2186</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1559</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2508</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1085</span>,</span>
<span id="cb15-13">    ],</span>
<span id="cb15-14">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"deuda"</span>: [</span>
<span id="cb15-15">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1172</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">914</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1081</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">548</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1361</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1259</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1107</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">337</span>,</span>
<span id="cb15-16">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">696</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">138</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">284</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">982</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1063</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1357</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">510</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">569</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">700</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">330</span>,</span>
<span id="cb15-17">    ],</span>
<span id="cb15-18">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"incumplio"</span>: [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb15-19">})</span>
<span id="cb15-20"></span>
<span id="cb15-21">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> datos[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"deuda"</span>]]</span>
<span id="cb15-22">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> datos[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"incumplio"</span>]</span>
<span id="cb15-23"></span>
<span id="cb15-24">modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LogisticRegression(random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>, max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2000</span>)</span>
<span id="cb15-25">modelo.fit(X, y)</span>
<span id="cb15-26"></span>
<span id="cb15-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Probabilidades de la clase positiva: salen DEL MODELO</span></span>
<span id="cb15-28">prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.predict_proba(X)[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]</span>
<span id="cb15-29"></span>
<span id="cb15-30">detalle <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> datos.copy()</span>
<span id="cb15-31">detalle[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"real"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y.to_numpy()</span>
<span id="cb15-32">detalle[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"probabilidad"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(prob, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)</span>
<span id="cb15-33">display(detalle[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"deuda"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"real"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"probabilidad"</span>]])</span>
<span id="cb15-34"></span>
<span id="cb15-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># El modelo y las p_i se fijan; solo cambia la regla tau</span></span>
<span id="cb15-36">y_pred_30 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.30</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb15-37">y_pred_50 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb15-38">y_pred_80 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.80</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb15-39"></span>
<span id="cb15-40">comparacion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb15-41">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"real"</span>: y.to_numpy(),</span>
<span id="cb15-42">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"probabilidad"</span>: np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(prob, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>),</span>
<span id="cb15-43">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pred_umbral_0.30"</span>: y_pred_30,</span>
<span id="cb15-44">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pred_umbral_0.50"</span>: y_pred_50,</span>
<span id="cb15-45">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pred_umbral_0.80"</span>: y_pred_80,</span>
<span id="cb15-46">})</span>
<span id="cb15-47"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Misma p_i; distintas decisiones según tau:"</span>)</span>
<span id="cb15-48">display(comparacion)</span>
<span id="cb15-49"></span>
<span id="cb15-50"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(</span>
<span id="cb15-51">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">El modelo no cambió. La probabilidad no cambió. "</span></span>
<span id="cb15-52">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Solo cambió la regla de decisión."</span></span>
<span id="cb15-53">)</span>
<span id="cb15-54"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"El modelo estima. El umbral decide. La matriz de confusión evalúa."</span>)</span>
<span id="cb15-55"></span>
<span id="cb15-56"></span>
<span id="cb15-57"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> tpr_fpr(y_true, y_pred):</span>
<span id="cb15-58">    tn, fp, fn, tp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_true, y_pred, labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]).ravel()</span>
<span id="cb15-59">    tpr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (tp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> fn) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (tp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> fn) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span></span>
<span id="cb15-60">    fpr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (fp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> tn) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (fp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> tn) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span></span>
<span id="cb15-61">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> {</span>
<span id="cb15-62">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TN"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(tn),</span>
<span id="cb15-63">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FP"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(fp),</span>
<span id="cb15-64">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FN"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(fn),</span>
<span id="cb15-65">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TP"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(tp),</span>
<span id="cb15-66">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"precision"</span>: precision_score(y_true, y_pred, zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb15-67">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"recall"</span>: recall_score(y_true, y_pred, zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb15-68">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TPR"</span>: tpr,</span>
<span id="cb15-69">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FPR"</span>: fpr,</span>
<span id="cb15-70">    }</span>
<span id="cb15-71"></span>
<span id="cb15-72"></span>
<span id="cb15-73">umbrales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0.30"</span>: y_pred_30, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0.50"</span>: y_pred_50, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0.80"</span>: y_pred_80}</span>
<span id="cb15-74">fig, axes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.6</span>))</span>
<span id="cb15-75">filas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb15-76"></span>
<span id="cb15-77"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> ax, (nombre, pred) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(axes, umbrales.items()):</span>
<span id="cb15-78">    cm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y, pred, labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])</span>
<span id="cb15-79">    sns.heatmap(</span>
<span id="cb15-80">        cm,</span>
<span id="cb15-81">        annot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb15-82">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"d"</span>,</span>
<span id="cb15-83">        cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Blues"</span>,</span>
<span id="cb15-84">        ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax,</span>
<span id="cb15-85">        cbar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>,</span>
<span id="cb15-86">        xticklabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pred. 0"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pred. 1"</span>],</span>
<span id="cb15-87">        yticklabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Real 0"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Real 1"</span>],</span>
<span id="cb15-88">    )</span>
<span id="cb15-89">    ax.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Matriz (umbral = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>nombre<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb15-90">    m <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tpr_fpr(y, pred)</span>
<span id="cb15-91">    m[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"umbral"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nombre</span>
<span id="cb15-92">    filas.append(m)</span>
<span id="cb15-93"></span>
<span id="cb15-94">plt.tight_layout()</span>
<span id="cb15-95">plt.show()</span>
<span id="cb15-96"></span>
<span id="cb15-97">resumen <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(filas)[</span>
<span id="cb15-98">    [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"umbral"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TN"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FP"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FN"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TP"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"precision"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"recall"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FPR"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TPR"</span>]</span>
<span id="cb15-99">]</span>
<span id="cb15-100"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cada umbral: una matriz, un par (FPR, TPR) que sería un punto de la ROC."</span>)</span>
<span id="cb15-101">display(resumen.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">ingreso</th>
<th data-quarto-table-cell-role="th">deuda</th>
<th data-quarto-table-cell-role="th">real</th>
<th data-quarto-table-cell-role="th">probabilidad</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>3144</td>
<td>1172</td>
<td>1</td>
<td>0.921</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>2173</td>
<td>914</td>
<td>1</td>
<td>0.934</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>3390</td>
<td>1081</td>
<td>1</td>
<td>0.829</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>2922</td>
<td>548</td>
<td>1</td>
<td>0.373</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>1173</td>
<td>1361</td>
<td>1</td>
<td>0.999</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">5</th>
<td>3729</td>
<td>1259</td>
<td>1</td>
<td>0.879</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">6</th>
<td>3107</td>
<td>1107</td>
<td>0</td>
<td>0.898</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">7</th>
<td>3180</td>
<td>337</td>
<td>0</td>
<td>0.113</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">8</th>
<td>1272</td>
<td>696</td>
<td>1</td>
<td>0.949</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">9</th>
<td>2206</td>
<td>138</td>
<td>0</td>
<td>0.174</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">10</th>
<td>1975</td>
<td>284</td>
<td>0</td>
<td>0.399</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">11</th>
<td>3588</td>
<td>982</td>
<td>1</td>
<td>0.675</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">12</th>
<td>2767</td>
<td>1063</td>
<td>1</td>
<td>0.923</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">13</th>
<td>3286</td>
<td>1357</td>
<td>1</td>
<td>0.962</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">14</th>
<td>2186</td>
<td>510</td>
<td>1</td>
<td>0.613</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">15</th>
<td>1559</td>
<td>569</td>
<td>1</td>
<td>0.856</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">16</th>
<td>2508</td>
<td>700</td>
<td>0</td>
<td>0.723</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">17</th>
<td>1085</td>
<td>330</td>
<td>1</td>
<td>0.780</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Misma p_i; distintas decisiones según tau:</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">real</th>
<th data-quarto-table-cell-role="th">probabilidad</th>
<th data-quarto-table-cell-role="th">pred_umbral_0.30</th>
<th data-quarto-table-cell-role="th">pred_umbral_0.50</th>
<th data-quarto-table-cell-role="th">pred_umbral_0.80</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>1</td>
<td>0.921</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>1</td>
<td>0.934</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>1</td>
<td>0.829</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>1</td>
<td>0.373</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>1</td>
<td>0.999</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">5</th>
<td>1</td>
<td>0.879</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">6</th>
<td>0</td>
<td>0.898</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">7</th>
<td>0</td>
<td>0.113</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">8</th>
<td>1</td>
<td>0.949</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">9</th>
<td>0</td>
<td>0.174</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">10</th>
<td>0</td>
<td>0.399</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">11</th>
<td>1</td>
<td>0.675</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">12</th>
<td>1</td>
<td>0.923</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">13</th>
<td>1</td>
<td>0.962</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">14</th>
<td>1</td>
<td>0.613</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">15</th>
<td>1</td>
<td>0.856</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">16</th>
<td>0</td>
<td>0.723</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">17</th>
<td>1</td>
<td>0.780</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>
El modelo no cambió. La probabilidad no cambió. Solo cambió la regla de decisión.
El modelo estima. El umbral decide. La matriz de confusión evalúa.</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-4-output-5.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Cada umbral: una matriz, un par (FPR, TPR) que sería un punto de la ROC.</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">umbral</th>
<th data-quarto-table-cell-role="th">TN</th>
<th data-quarto-table-cell-role="th">FP</th>
<th data-quarto-table-cell-role="th">FN</th>
<th data-quarto-table-cell-role="th">TP</th>
<th data-quarto-table-cell-role="th">precision</th>
<th data-quarto-table-cell-role="th">recall</th>
<th data-quarto-table-cell-role="th">FPR</th>
<th data-quarto-table-cell-role="th">TPR</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>0.30</td>
<td>2</td>
<td>3</td>
<td>0</td>
<td>13</td>
<td>0.812</td>
<td>1.000</td>
<td>0.6</td>
<td>1.000</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>0.50</td>
<td>3</td>
<td>2</td>
<td>1</td>
<td>12</td>
<td>0.857</td>
<td>0.923</td>
<td>0.4</td>
<td>0.923</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>0.80</td>
<td>4</td>
<td>1</td>
<td>4</td>
<td>9</td>
<td>0.900</td>
<td>0.692</td>
<td>0.2</td>
<td>0.692</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<p><strong>Lectura de las tres matrices (mismo modelo, mismas <img src="https://latex.codecogs.com/png.latex?p_i">).</strong></p>
<ul>
<li><strong>Umbral bajo (0.30).</strong> Tiende a haber <strong>más</strong> predicciones positivas: potencialmente más TP y <strong>potencialmente</strong> más FP. El recall suele subir; la precision puede deteriorarse si entran falsas alarmas.</li>
<li><strong>Umbral intermedio (0.50).</strong> Es solo un corte de referencia, no un óptimo. La matriz es <strong>otra</strong> (en general) que la de 0.30 y la de 0.80.</li>
<li><strong>Umbral alto (0.80).</strong> Tiende a haber <strong>menos</strong> predicciones positivas: potencialmente menos FP y <strong>potencialmente</strong> más FN. El recall suele bajar; la precision puede mejorar.</li>
</ul>
<p>Ese patrón es el <strong>comportamiento típico</strong>, no una identidad que valga para cualquier muestra. Por eso se habla de «tiende a» y «potencialmente».</p>
<blockquote class="blockquote">
<p><strong>El modelo estima. El umbral decide. La matriz de confusión evalúa.</strong></p>
</blockquote>
<p><strong>Precision y recall (sección 3) en este mismo experimento.</strong> Al bajar <img src="https://latex.codecogs.com/png.latex?%5Ctau"> suele ser más fácil predecir la clase positiva: el recall (TPR) <strong>normalmente aumenta</strong> y pueden crecer los FP, con lo que la precision <strong>puede</strong> caer. Al subir <img src="https://latex.codecogs.com/png.latex?%5Ctau"> somos más exigentes: el recall <strong>generalmente disminuye</strong>, pueden reducirse los FP y la precision <strong>puede</strong> mejorar.</p>
<p>Cada fila de la tabla de FPR y TPR es <strong>un punto</strong> <img src="https://latex.codecogs.com/png.latex?(FPR,%5C%20TPR)"> asociado a un <img src="https://latex.codecogs.com/png.latex?%5Ctau">. Con tres umbrales tenemos tres puntos. Aún no es la curva completa.</p>
<hr>
<p><strong>Pregunta.</strong> Si cada umbral genera una matriz de confusión diferente, <strong>¿qué ocurriría si probáramos sistemáticamente todos los umbrales posibles?</strong></p>
<p><strong>Respuesta.</strong> Eso es precisamente lo que permite estudiar la <strong>curva ROC</strong>.</p>
<p><code>roc_curve(y, prob)</code> necesita los <strong>valores reales</strong> y los <strong>scores/probabilidades</strong> del modelo. <strong>No</strong> debe recibir únicamente un <code>y_pred</code> obtenido con un solo umbral: ese vector ya colapsó todas las <img src="https://latex.codecogs.com/png.latex?p_i"> a una frontera.</p>
<p><strong>¿Por qué <code>roc_curve()</code> recibe probabilidades y no <code>y_pred</code>?</strong> Porque <code>y_pred</code> corresponde a <strong>una</strong> frontera de decisión, mientras que la ROC necesita <strong>evaluar muchos umbrales</strong> sobre el mismo ranking.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Elemento</th>
<th>Función</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Modelo</td>
<td>Aprende patrones a partir de <img src="https://latex.codecogs.com/png.latex?X"> e <img src="https://latex.codecogs.com/png.latex?y"></td>
</tr>
<tr class="even">
<td>Score / probabilidad</td>
<td>Grado de pertenencia a la clase positiva (sale del modelo)</td>
</tr>
<tr class="odd">
<td>Umbral <img src="https://latex.codecogs.com/png.latex?%5Ctau"></td>
<td>Convierte el score en una decisión 0/1</td>
</tr>
<tr class="even">
<td>Predicción <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"></td>
<td>Clase asignada por esa regla</td>
</tr>
<tr class="odd">
<td>Matriz de confusión</td>
<td>Compara <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"> con la realidad, para un umbral fijo</td>
</tr>
<tr class="even">
<td>Precision, recall, F1, accuracy</td>
<td>Aspectos de esa matriz</td>
</tr>
<tr class="odd">
<td>ROC</td>
<td>Recorre muchos umbrales y grafica los pares (FPR, TPR)</td>
</tr>
<tr class="even">
<td>AUC</td>
<td>Resume la capacidad discriminativa global del ranking</td>
</tr>
</tbody>
</table>
</section>
</section>
</section>
<section id="curva-roc" class="level1">
<h1>5. Curva ROC</h1>
<p>En la sección 4 vimos que <strong>una</strong> matriz de confusión corresponde a <strong>un</strong> umbral <img src="https://latex.codecogs.com/png.latex?%5Ctau">. La <strong>curva ROC</strong> (<em>Receiver Operating Characteristic</em>) no sustituye esa matriz: <strong>recorre</strong> <img src="https://latex.codecogs.com/png.latex?%5Ctau"> y, para cada valor, calcula un punto en el plano <img src="https://latex.codecogs.com/png.latex?(FPR,%5C%20TPR)">.</p>
<p>Formalmente, dado un ranking <img src="https://latex.codecogs.com/png.latex?p_1,%5Cldots,p_n"> y etiquetas <img src="https://latex.codecogs.com/png.latex?y_i%20%5Cin%20%5C%7B0,1%5C%7D">,</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BTPR%7D(%5Ctau)=%5Cfrac%7BTP(%5Ctau)%7D%7BTP(%5Ctau)+FN(%5Ctau)%7D,%20%5Cqquad%0A%5Cmathrm%7BFPR%7D(%5Ctau)=%5Cfrac%7BFP(%5Ctau)%7D%7BFP(%5Ctau)+TN(%5Ctau)%7D.%0A"></p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BTPR%7D"> es la <strong>sensibilidad</strong> y el <strong>recall de la clase positiva</strong>: de los positivos reales, qué fracción se detecta con ese <img src="https://latex.codecogs.com/png.latex?%5Ctau">. <img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BFPR%7D"> es la fracción de <strong>negativos reales</strong> que se marcan (incorrectamente) como positivos. Equivale a <img src="https://latex.codecogs.com/png.latex?1%20-%20%5Cmathrm%7Bespecificidad%7D">, porque</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7Bespecificidad%7D(%5Ctau)=%5Cfrac%7BTN(%5Ctau)%7D%7BTN(%5Ctau)+FP(%5Ctau)%7D=1-%5Cmathrm%7BFPR%7D(%5Ctau).%0A"></p>
<p><strong>Conexión con la matriz.</strong> <img src="https://latex.codecogs.com/png.latex?TP"> y <img src="https://latex.codecogs.com/png.latex?FN"> salen de los positivos reales; <img src="https://latex.codecogs.com/png.latex?FP"> y <img src="https://latex.codecogs.com/png.latex?TN">, de los negativos reales. Sin fijar <img src="https://latex.codecogs.com/png.latex?%5Ctau"> no hay <img src="https://latex.codecogs.com/png.latex?TP"> ni <img src="https://latex.codecogs.com/png.latex?FP"> que sumar. Cada <img src="https://latex.codecogs.com/png.latex?%5Ctau"> produce un par <img src="https://latex.codecogs.com/png.latex?(%5Cmathrm%7BFPR%7D(%5Ctau),%5C%20%5Cmathrm%7BTPR%7D(%5Ctau))">; <strong>ese par es un punto de la ROC</strong>. Unir esos puntos (en el orden de umbrales decrecientes, como hace <code>sklearn</code>) produce la curva.</p>
<p>Ejemplo numérico <strong>para un solo umbral</strong>: si <img src="https://latex.codecogs.com/png.latex?TP=80">, <img src="https://latex.codecogs.com/png.latex?FN=20">, <img src="https://latex.codecogs.com/png.latex?FP=10">, <img src="https://latex.codecogs.com/png.latex?TN=90">,</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cmathrm%7BTPR%7D=%5Cfrac%7B80%7D%7B100%7D=0.80,%20%5Cqquad%20%5Cmathrm%7BFPR%7D=%5Cfrac%7B10%7D%7B100%7D=0.10.%0A"></p>
<p>Eso es <strong>un</strong> punto <img src="https://latex.codecogs.com/png.latex?(0.10,%5C%200.80)">, no la curva. La curva aparece cuando se repite el cálculo para muchos <img src="https://latex.codecogs.com/png.latex?%5Ctau">.</p>
<p>En código, <code>roc_curve(y, prob)</code> recibe etiquetas y <strong>scores</strong>. Un modelo ideal sube rápido hacia la esquina superior izquierda (mucho TPR con poco FPR). La diagonal <img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BTPR%7D=%5Cmathrm%7BFPR%7D"> es el clasificador aleatorio (<img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BAUC%7D=0.5">).</p>
<section id="interpretación-de-la-curva-y-del-auc" class="level3">
<h3 class="anchored" data-anchor-id="interpretación-de-la-curva-y-del-auc">Interpretación de la curva y del AUC</h3>
<p>El <strong>AUC</strong> (<em>area under the curve</em>) es el área bajo la ROC. Dos anclas:</p>
<ul>
<li><strong>AUC = 0.5</strong>: capacidad discriminativa equivalente al <strong>azar</strong> (el ranking no ordena mejor que una moneda).</li>
<li><strong>AUC = 1</strong>: discriminación <strong>perfecta</strong> (existe un umbral que separa por completo positivos y negativos en la muestra evaluada).</li>
</ul>
<p>En el intervalo <img src="https://latex.codecogs.com/png.latex?(0.5,%5C%201)">, <strong>cuanto mayor es el AUC, mayor es la capacidad general de colocar observaciones positivas por encima de las negativas</strong> en el ranking. Una interpretación probabilística útil:</p>
<blockquote class="blockquote">
<p>El AUC es la probabilidad de que el modelo asigne un score <strong>mayor</strong> a una observación positiva elegida al azar que a una observación negativa elegida al azar.</p>
</blockquote>
<p>No hay umbrales universales del tipo «0.90 = excelente» o «0.80–0.90 = bueno» que valgan para todo dominio. Un AUC de 0.78 puede ser valioso en un problema difícil y insuficiente en otro. <strong>Si un AUC es “bueno” o “suficiente” lo decide el contexto</strong> (prevalencia, costos, alternativa clínica o de negocio).</p>
</section>
<section id="auc-no-elige-el-umbral-operativo" class="level3">
<h3 class="anchored" data-anchor-id="auc-no-elige-el-umbral-operativo">AUC no elige el umbral operativo</h3>
<p>El AUC evalúa la <strong>calidad global del ranking</strong>. No selecciona <img src="https://latex.codecogs.com/png.latex?%5Ctau">. Hay que mantener separados dos conceptos:</p>
<ul>
<li><strong>AUC</strong> → discriminación / capacidad de ordenar.</li>
<li><strong>Umbral</strong> → <strong>política</strong> concreta de decisión (sección 3.2: costos de FP y FN).</li>
</ul>
<blockquote class="blockquote">
<p>Un modelo puede tener un buen AUC y, sin embargo, utilizar un umbral operativo inadecuado para el problema de negocio.</p>
</blockquote>
<p>La curva <strong>muestra</strong> el menú de puntos <img src="https://latex.codecogs.com/png.latex?(FPR,%5C%20TPR)">; el negocio elige el punto. El AUC resume el menú, no elige el plato.</p>
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/roc.png" alt="Esquema de curva ROC" width="640"></p>
<p>El gráfico es un esquema: cerca de la esquina superior izquierda hay mejor compromiso sensibilidad–falsas alarmas; la diagonal es el azar. En 5.1 se dibujan tres ROC a partir de <strong>scores</strong>, no de un único <code>y_pred</code>.</p>
</section>
<section id="implementación-práctica-tres-curvas-roc" class="level3">
<h3 class="anchored" data-anchor-id="implementación-práctica-tres-curvas-roc">5.1 Implementación práctica: tres curvas ROC</h3>
<p>Abajo, <code>roc_curve(y_true, y_scores)</code> usa <strong>etiquetas y scores</strong>. No se le pasa un <code>y_pred</code> de un solo umbral: eso comprimiría el ranking a una matriz y la curva colapsaría a un punto (más los extremos técnicos que añade sklearn).</p>
<div id="cell-18" class="cell" data-execution_count="31">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb19-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb19-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> roc_curve, auc</span>
<span id="cb19-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># roc_curve(y_true, y_scores): etiquetas + ranking. No usar y_pred de un único umbral.</span></span>
<span id="cb19-5"></span>
<span id="cb19-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Caso 1: modelo pobre/casi aleatorio (AUC ~ 0.55)</span></span>
<span id="cb19-7">y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])</span>
<span id="cb19-8">y_scores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.58</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.55</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.56</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.52</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.53</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.51</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.46</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.45</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.61</span>])</span>
<span id="cb19-9"></span>
<span id="cb19-10">fpr, tpr, thresholds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_curve(y_true, y_scores)</span>
<span id="cb19-11">roc_auc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auc(fpr, tpr)</span>
<span id="cb19-12"></span>
<span id="cb19-13">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb19-14">plt.plot(fpr, tpr, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'darkorange'</span>, lw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Curva ROC (AUC = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)'</span>)</span>
<span id="cb19-15">plt.plot([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>)</span>
<span id="cb19-16">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Falsos Positivos (1 - Especificidad)'</span>)</span>
<span id="cb19-17">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Verdaderos Positivos (Sensibilidad)'</span>)</span>
<span id="cb19-18">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Curva ROC - Modelo Pobre (Contraste)'</span>)</span>
<span id="cb19-19">plt.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lower right'</span>)</span>
<span id="cb19-20">plt.grid(alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>)</span>
<span id="cb19-21">plt.show()</span>
<span id="cb19-22"></span>
<span id="cb19-23"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"AUC (caso 1): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb19-24"></span>
<span id="cb19-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Caso 2: separación moderada entre clases (AUC ~ 0.7)</span></span>
<span id="cb19-26">y_scores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.65</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.70</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.60</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.40</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.55</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.30</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.45</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.20</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.35</span>])</span>
<span id="cb19-27"></span>
<span id="cb19-28">fpr, tpr, _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_curve(y_true, y_scores)</span>
<span id="cb19-29">roc_auc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auc(fpr, tpr)</span>
<span id="cb19-30"></span>
<span id="cb19-31">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb19-32">plt.plot(fpr, tpr, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'blue'</span>, lw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Curva ROC (AUC = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)'</span>)</span>
<span id="cb19-33">plt.plot([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>)</span>
<span id="cb19-34">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Falsos Positivos (1 - Especificidad)'</span>)</span>
<span id="cb19-35">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Verdaderos Positivos (Sensibilidad)'</span>)</span>
<span id="cb19-36">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Curva ROC - Implementación Básica'</span>)</span>
<span id="cb19-37">plt.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lower right'</span>)</span>
<span id="cb19-38">plt.grid(alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>)</span>
<span id="cb19-39">plt.show()</span>
<span id="cb19-40"></span>
<span id="cb19-41"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"AUC (caso 2): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb19-42"></span>
<span id="cb19-43"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Caso 3: modelo excelente (AUC ~ 0.9)</span></span>
<span id="cb19-44">y_scores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.90</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.85</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.35</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.80</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.78</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.55</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.62</span>])</span>
<span id="cb19-45"></span>
<span id="cb19-46">fpr, tpr, _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_curve(y_true, y_scores)</span>
<span id="cb19-47">roc_auc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auc(fpr, tpr)</span>
<span id="cb19-48"></span>
<span id="cb19-49">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb19-50">plt.plot(fpr, tpr, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'green'</span>, lw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Curva ROC (AUC = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)'</span>)</span>
<span id="cb19-51">plt.plot([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>)</span>
<span id="cb19-52">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Falsos Positivos (1 - Especificidad)'</span>)</span>
<span id="cb19-53">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Verdaderos Positivos (Sensibilidad)'</span>)</span>
<span id="cb19-54">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Curva ROC - Modelo Excelente (Contraste)'</span>)</span>
<span id="cb19-55">plt.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lower right'</span>)</span>
<span id="cb19-56">plt.grid(alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>)</span>
<span id="cb19-57">plt.show()</span>
<span id="cb19-58"></span>
<span id="cb19-59"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"AUC (caso 3): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-5-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>AUC (caso 1): 0.560</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-5-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>AUC (caso 2): 0.720</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-5-output-5.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>AUC (caso 3): 0.920</code></pre>
</div>
</div>
</section>
<section id="ejemplo-de-decisión-con-umbral" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-de-decisión-con-umbral">5.2 Ejemplo de decisión con umbral</h3>
<p>Este ejemplo muestra dos momentos distintos del proceso: primero se prueban varios umbrales para comparar métricas, y luego se elige uno solo para tomar la decisión final. Así se entiende que la curva ROC y el análisis de umbrales sirven para evaluar opciones, pero en producción normalmente se usa un único corte. En 4.15 el mismo score se cortó en 0.30, 0.50 y 0.80 y <strong>cambiaron las matrices</strong>. Aquí se recorre una grilla de umbrales y se elige <strong>un</strong> corte (por F1) para producción: la ROC y la tabla sirven para <strong>evaluar opciones</strong>; el sistema desplegado usa un solo umbral.</p>
<div id="cell-20" class="cell" data-execution_count="32">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb23-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb23-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb23-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> precision_score, recall_score, f1_score, accuracy_score</span>
<span id="cb23-4"></span>
<span id="cb23-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Probabilidades del modelo para la clase positiva y etiquetas reales</span></span>
<span id="cb23-6">y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])</span>
<span id="cb23-7">y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.10</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.40</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.35</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.80</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.20</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.70</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.60</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.90</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.85</span>])</span>
<span id="cb23-8"></span>
<span id="cb23-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1) Evaluamos muchos umbrales en el mismo script</span></span>
<span id="cb23-10">umbrales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.10</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.95</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>)</span>
<span id="cb23-11">resultados <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb23-12"></span>
<span id="cb23-13"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> u <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> umbrales:</span>
<span id="cb23-14">    y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> u).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb23-15">    resultados.append({</span>
<span id="cb23-16">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'umbral'</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(u), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb23-17">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>: accuracy_score(y_true, y_pred),</span>
<span id="cb23-18">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'precision'</span>: precision_score(y_true, y_pred, zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb23-19">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'recall'</span>: recall_score(y_true, y_pred, zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb23-20">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1'</span>: f1_score(y_true, y_pred, zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb23-21">    })</span>
<span id="cb23-22"></span>
<span id="cb23-23">tabla <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(resultados)</span>
<span id="cb23-24">display(tabla.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb23-25"></span>
<span id="cb23-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2) Elegimos umbral según objetivo de negocio: aquí maximizamos F1</span></span>
<span id="cb23-27">mejor_fila <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tabla.loc[tabla[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1'</span>].idxmax()]</span>
<span id="cb23-28">umbral_optimo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(mejor_fila[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'umbral'</span>])</span>
<span id="cb23-29"></span>
<span id="cb23-30"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">Umbral recomendado (max F1): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>umbral_optimo<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb23-31"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(</span>
<span id="cb23-32">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Métricas en ese umbral -&gt; "</span></span>
<span id="cb23-33">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Accuracy: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mejor_fila[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, "</span></span>
<span id="cb23-34">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Precision: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mejor_fila[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'precision'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, "</span></span>
<span id="cb23-35">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Recall: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mejor_fila[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'recall'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, "</span></span>
<span id="cb23-36">    <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"F1: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mejor_fila[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb23-37">)</span>
<span id="cb23-38"></span>
<span id="cb23-39"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3) Regla de decisión final en producción (ya con un solo umbral)</span></span>
<span id="cb23-40">y_pred_final <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> umbral_optimo).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb23-41"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">Predicción final usando un solo umbral (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>umbral_optimo<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">):"</span>)</span>
<span id="cb23-42"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(y_pred_final)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">umbral</th>
<th data-quarto-table-cell-role="th">accuracy</th>
<th data-quarto-table-cell-role="th">precision</th>
<th data-quarto-table-cell-role="th">recall</th>
<th data-quarto-table-cell-role="th">f1</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>0.10</td>
<td>0.6</td>
<td>0.556</td>
<td>1.0</td>
<td>0.714</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>0.15</td>
<td>0.7</td>
<td>0.625</td>
<td>1.0</td>
<td>0.769</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>0.20</td>
<td>0.8</td>
<td>0.714</td>
<td>1.0</td>
<td>0.833</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>0.25</td>
<td>0.8</td>
<td>0.714</td>
<td>1.0</td>
<td>0.833</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>0.30</td>
<td>0.8</td>
<td>0.714</td>
<td>1.0</td>
<td>0.833</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">5</th>
<td>0.35</td>
<td>0.9</td>
<td>0.833</td>
<td>1.0</td>
<td>0.909</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">6</th>
<td>0.40</td>
<td>0.8</td>
<td>0.800</td>
<td>0.8</td>
<td>0.800</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">7</th>
<td>0.45</td>
<td>0.8</td>
<td>0.800</td>
<td>0.8</td>
<td>0.800</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">8</th>
<td>0.50</td>
<td>0.8</td>
<td>0.800</td>
<td>0.8</td>
<td>0.800</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">9</th>
<td>0.55</td>
<td>0.8</td>
<td>0.800</td>
<td>0.8</td>
<td>0.800</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">10</th>
<td>0.60</td>
<td>0.9</td>
<td>1.000</td>
<td>0.8</td>
<td>0.889</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">11</th>
<td>0.65</td>
<td>0.9</td>
<td>1.000</td>
<td>0.8</td>
<td>0.889</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">12</th>
<td>0.70</td>
<td>0.8</td>
<td>1.000</td>
<td>0.6</td>
<td>0.750</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">13</th>
<td>0.75</td>
<td>0.8</td>
<td>1.000</td>
<td>0.6</td>
<td>0.750</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">14</th>
<td>0.80</td>
<td>0.7</td>
<td>1.000</td>
<td>0.4</td>
<td>0.571</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">15</th>
<td>0.85</td>
<td>0.6</td>
<td>1.000</td>
<td>0.2</td>
<td>0.333</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">16</th>
<td>0.90</td>
<td>0.5</td>
<td>0.000</td>
<td>0.0</td>
<td>0.000</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>
Umbral recomendado (max F1): 0.35
Métricas en ese umbral -&gt; Accuracy: 0.900, Precision: 0.833, Recall: 1.000, F1: 0.909

Predicción final usando un solo umbral (0.35):
[0 1 1 1 0 1 1 1 0 1]</code></pre>
</div>
</div>
</section>
<section id="ejemplo-integrador-matriz-de-confusión-y-curva-roc" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-integrador-matriz-de-confusión-y-curva-roc">5.3 Ejemplo integrador: matriz de confusión y curva ROC</h3>
<div id="cell-22" class="cell" data-execution_count="33">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb25-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb25-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb25-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> (</span>
<span id="cb25-4">    confusion_matrix,</span>
<span id="cb25-5">    classification_report,</span>
<span id="cb25-6">    accuracy_score,</span>
<span id="cb25-7">    roc_curve,</span>
<span id="cb25-8">    roc_auc_score,</span>
<span id="cb25-9">)</span>
<span id="cb25-10"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb25-11"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb25-12"></span>
<span id="cb25-13">y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])</span>
<span id="cb25-14">y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.10</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.40</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.35</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.80</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.20</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.70</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.60</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.90</span>])</span>
<span id="cb25-15"></span>
<span id="cb25-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># La clase predicha sale del umbral, no de un vector aparte</span></span>
<span id="cb25-17">umbral <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span></span>
<span id="cb25-18">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> umbral).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb25-19"></span>
<span id="cb25-20">detalle <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb25-21">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Real'</span>: y_true,</span>
<span id="cb25-22">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Prob'</span>: y_prob,</span>
<span id="cb25-23">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Pred'</span>: y_pred,</span>
<span id="cb25-24">})</span>
<span id="cb25-25"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Umbral de decisión: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>umbral<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb25-26">display(detalle)</span>
<span id="cb25-27"></span>
<span id="cb25-28">cm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_true, y_pred)</span>
<span id="cb25-29">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb25-30">sns.heatmap(cm, annot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'d'</span>, cmap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Blues'</span>)</span>
<span id="cb25-31">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Predicción'</span>)</span>
<span id="cb25-32">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Real'</span>)</span>
<span id="cb25-33">plt.title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Matriz de Confusión (umbral = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>umbral<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)'</span>)</span>
<span id="cb25-34">plt.show()</span>
<span id="cb25-35"></span>
<span id="cb25-36">accuracy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> accuracy_score(y_true, y_pred)</span>
<span id="cb25-37">report <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> classification_report(</span>
<span id="cb25-38">    y_true,</span>
<span id="cb25-39">    y_pred,</span>
<span id="cb25-40">    target_names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clase 0'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clase 1'</span>],</span>
<span id="cb25-41">    output_dict<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb25-42">    zero_division<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb25-43">)</span>
<span id="cb25-44"></span>
<span id="cb25-45"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Exactitud: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>accuracy<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb25-46"></span>
<span id="cb25-47">filas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clase 0'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clase 1'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'macro avg'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weighted avg'</span>]</span>
<span id="cb25-48">reporte_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(</span>
<span id="cb25-49">    [{</span>
<span id="cb25-50">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clase'</span>: clase,</span>
<span id="cb25-51">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Precisión'</span>: report[clase][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'precision'</span>],</span>
<span id="cb25-52">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Recall'</span>: report[clase][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'recall'</span>],</span>
<span id="cb25-53">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'F1-score'</span>: report[clase][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'f1-score'</span>],</span>
<span id="cb25-54">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Soporte'</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(report[clase][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'support'</span>])</span>
<span id="cb25-55">    } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> clase <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> filas]</span>
<span id="cb25-56">)</span>
<span id="cb25-57">reporte_df[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Precisión'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Recall'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'F1-score'</span>]] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> reporte_df[</span>
<span id="cb25-58">    [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Precisión'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Recall'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'F1-score'</span>]</span>
<span id="cb25-59">].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb25-60"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Reporte de clasificación:'</span>)</span>
<span id="cb25-61">display(reporte_df)</span>
<span id="cb25-62"></span>
<span id="cb25-63">fpr, tpr, _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_curve(y_true, y_prob)</span>
<span id="cb25-64">roc_auc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_auc_score(y_true, y_prob)</span>
<span id="cb25-65"></span>
<span id="cb25-66">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb25-67">plt.plot(fpr, tpr, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'blue'</span>, lw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Curva ROC (AUC = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roc_auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)'</span>)</span>
<span id="cb25-68">plt.plot([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, lw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>)</span>
<span id="cb25-69">plt.xlim([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>])</span>
<span id="cb25-70">plt.ylim([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.05</span>])</span>
<span id="cb25-71">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Falsos Positivos'</span>)</span>
<span id="cb25-72">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tasa de Verdaderos Positivos'</span>)</span>
<span id="cb25-73">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Curva ROC (independiente del umbral)'</span>)</span>
<span id="cb25-74">plt.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lower right'</span>)</span>
<span id="cb25-75">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Umbral de decisión: 0.50</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">Real</th>
<th data-quarto-table-cell-role="th">Prob</th>
<th data-quarto-table-cell-role="th">Pred</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>0</td>
<td>0.10</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>1</td>
<td>0.40</td>
<td>0</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>0</td>
<td>0.35</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>1</td>
<td>0.80</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>0</td>
<td>0.20</td>
<td>0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">5</th>
<td>1</td>
<td>0.70</td>
<td>1</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">6</th>
<td>0</td>
<td>0.60</td>
<td>1</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">7</th>
<td>1</td>
<td>0.90</td>
<td>1</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-7-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Exactitud: 0.75
Reporte de clasificación:</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">Clase</th>
<th data-quarto-table-cell-role="th">Precisión</th>
<th data-quarto-table-cell-role="th">Recall</th>
<th data-quarto-table-cell-role="th">F1-score</th>
<th data-quarto-table-cell-role="th">Soporte</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>Clase 0</td>
<td>0.75</td>
<td>0.75</td>
<td>0.75</td>
<td>4</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>Clase 1</td>
<td>0.75</td>
<td>0.75</td>
<td>0.75</td>
<td>4</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>macro avg</td>
<td>0.75</td>
<td>0.75</td>
<td>0.75</td>
<td>8</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>weighted avg</td>
<td>0.75</td>
<td>0.75</td>
<td>0.75</td>
<td>8</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/index_files/figure-html/cell-7-output-6.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="usos-ventajas-y-límites-de-la-curva-roc" class="level3">
<h3 class="anchored" data-anchor-id="usos-ventajas-y-límites-de-la-curva-roc">5.4 Usos, ventajas y límites de la curva ROC</h3>
<ol type="1">
<li><strong>Evaluación de modelos de clasificación binaria</strong>
<ul>
<li>Permite comparar diferentes modelos para ver cuál tiene mejor capacidad predictiva.</li>
</ul></li>
<li><strong>Exploración de umbrales (no los elige el AUC)</strong>
<ul>
<li>La curva muestra el menú de pares (FPR, TPR). El umbral operativo se elige con costos y recall/precision (secciones 3.2 y 4), no porque el AUC asigne un corte.</li>
</ul></li>
<li><strong>Medición de la capacidad de discriminación del modelo</strong>
<ul>
<li>Evalúa qué tan bien el modelo distingue entre clases positivas y negativas.</li>
</ul></li>
<li><strong>Análisis de modelos desbalanceados</strong>
<ul>
<li>AUC-ROC puede ser útil para comparar capacidad de separación, pero en desbalance extremo conviene complementarla con Precision-Recall.</li>
</ul></li>
</ol>
</section>
<section id="ventajas-de-la-curva-roc" class="level3">
<h3 class="anchored" data-anchor-id="ventajas-de-la-curva-roc">Ventajas de la Curva ROC</h3>
<ul>
<li><strong>No se reduce a un solo umbral</strong>
<ul>
<li>Resume el ranking en todos los cortes. Eso <strong>no</strong> sustituye elegir el umbral con una política de costos.</li>
</ul></li>
<li><strong>Útil para comparar modelos</strong>
<ul>
<li>Si dos modelos tienen curvas ROC, podemos determinar cuál discrimina mejor con solo observar el AUC.</li>
</ul></li>
</ul>
</section>
<section id="desventajas-de-la-curva-roc" class="level3">
<h3 class="anchored" data-anchor-id="desventajas-de-la-curva-roc">Desventajas de la Curva ROC</h3>
<ul>
<li><strong>Puede ser engañosa con datos extremadamente desbalanceados</strong>
<ul>
<li>En casos donde la clase positiva es muy rara, una alta AUC no garantiza un buen rendimiento real.</li>
</ul></li>
<li><strong>No mide la calidad de las predicciones</strong>
<ul>
<li>No indica qué tan bien están calibradas las probabilidades predichas, solo mide la capacidad de discriminación.</li>
</ul></li>
<li><strong>No siempre es la mejor métrica</strong>
<ul>
<li>En problemas donde es más importante evitar falsos negativos (p.ej., diagnóstico médico), es preferible usar métricas como <strong>Recall o F1-score</strong>.</li>
</ul></li>
</ul>
<hr>
</section>
<section id="conclusión-1" class="level2">
<h2 class="anchored" data-anchor-id="conclusión-1">6. Conclusión</h2>
<p>Como en la sección 4: el modelo estima, el umbral decide y la matriz evalúa un solo corte. La ROC recorre los cortes; el AUC resume la discriminación del ranking y <strong>no</strong> fija el umbral de negocio. Sigue siendo una herramienta central para comparar clasificadores binarios. En desbalance extremo o cuando un tipo de error es crítico, conviene leerla junto con precision, recall, costos y, si aplica, la curva precision–recall.</p>
<hr>
<p>Los ejercicios de esta sesión están en el notebook <strong><code>Taller_metricas_prediccion_clasificacion.ipynb</code></strong> (métricas de predicción, matrices de confusión, umbral, AUC-ROC e integración).</p>
<section id="te-sirvió" class="level3">
<h3 class="anchored" data-anchor-id="te-sirvió">💬 ¿Te sirvió?</h3>
<p>Deja en los comentarios <strong>una duda o un caso donde aplicarías esto</strong> — respondo todos. Sígueme para no perderte el próximo artículo de la serie y comparte con alguien que esté aprendiendo análisis de datos.</p>
<p>👉 El código completo está disponible para ejecutar directamente.</p>


</section>
</section>
</section>

 ]]></description>
  <category>deep-learning</category>
  <category>evaluacion</category>
  <category>metricas</category>
  <guid>https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/</guid>
  <pubDate>Sun, 30 Aug 2026 05:00:00 GMT</pubDate>
  <media:content url="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/roc.png" medium="image" type="image/png" height="123" width="144"/>
</item>
<item>
  <title>Fundamentos matemáticos del Deep Learning y entrenamiento de un MLP</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/</link>
  <description><![CDATA[ 




<section id="fundamentos-matemáticos-del-deep-learning-y-entrenamiento-de-un-mlp" class="level1">
<h1>Fundamentos matemáticos del Deep Learning y entrenamiento de un MLP</h1>
<p><a href="TODO_URL_GITHUB"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab"></a></p>
<section id="electiva-técnica-iii---deep-learning-sesión-01" class="level3">
<h3 class="anchored" data-anchor-id="electiva-técnica-iii---deep-learning-sesión-01">Electiva Técnica III - Deep Learning · Sesión 01</h3>
<p>Este notebook cubre los conceptos fundamentales necesarios para comprender el funcionamiento de las redes neuronales profundas. El objetivo es construir una base sólida que conecte la motivación histórica (por qué surgió el Deep Learning), la formalización matemática (vectores, matrices, funciones de activación y pérdida) y el flujo completo de entrenamiento (forward, pérdida, gradiente, actualización). Al final se implementa un modelo desde cero en NumPy para fijar todos estos conceptos.</p>
</section>
<section id="sobre-el-autor" class="level2">
<h2 class="anchored" data-anchor-id="sobre-el-autor">👋 Sobre el autor</h2>
<p>Wilder Ramírez Delgado es Científico de Datos, Arquitecto de IA, Ingeniero Electrónico y Magíster en Analítica de Datos. CEO y fundador de Business Innovation Technology (BIT), consultor y docente universitario, trabaja en la intersección entre Data Science, Inteligencia Artificial, Big Data e IoT, transformando problemas reales en soluciones aplicadas.</p>
<p>De la teoría a la práctica, un problema a la vez.</p>
<div id="8eb7922f" class="cell" data-execution_count="40">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Importaciones necesarias para todo el notebook</span></span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb1-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb1-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.model_selection <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> train_test_split</span>
<span id="cb1-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> make_classification</span>
<span id="cb1-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> warnings</span>
<span id="cb1-8">warnings.filterwarnings(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ignore'</span>)</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Configuración de visualización</span></span>
<span id="cb1-11">plt.style.use(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'seaborn-v0_8-whitegrid'</span>)</span>
<span id="cb1-12">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'figure.figsize'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>)</span>
<span id="cb1-13">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'font.size'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span></span></code></pre></div></div>
</div>
<hr>
</section>
<section id="contexto-y-motivación" class="level2">
<h2 class="anchored" data-anchor-id="contexto-y-motivación">1. Contexto y Motivación</h2>
<section id="evolución-de-machine-learning-a-deep-learning" class="level3">
<h3 class="anchored" data-anchor-id="evolución-de-machine-learning-a-deep-learning">Evolución de Machine Learning a Deep Learning</h3>
<p>El <strong>Machine Learning tradicional</strong> (regresión lineal, árboles de decisión, SVM, etc.) se basa en que un humano diseñe <strong>características (features)</strong> a partir de los datos crudos. Por ejemplo, para imágenes se extraían histogramas, bordes o descriptores como SIFT. Ese proceso se llama <strong>feature engineering</strong> y limita mucho el rendimiento: si las features no capturan bien el problema, el modelo no puede mejorar.</p>
<p>El <strong>Deep Learning</strong> cambia el paradigma: en lugar de diseñar features a mano, se usan <strong>redes neuronales profundas</strong> (muchas capas) que <strong>aprenden representaciones jerárquicas</strong> de los datos de forma automática. Las primeras capas suelen capturar patrones de bajo nivel (bordes, texturas) y las capas profundas combinan esos patrones en conceptos de alto nivel (objetos, escenas). Así, el propio modelo “decide” qué representaciones son útiles para la tarea.</p>
</section>
<section id="diferencias-clave" class="level3">
<h3 class="anchored" data-anchor-id="diferencias-clave">Diferencias clave</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 22%">
<col style="width: 40%">
<col style="width: 37%">
</colgroup>
<thead>
<tr class="header">
<th>Aspecto</th>
<th>ML Tradicional</th>
<th>Deep Learning</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Features</td>
<td>Ingeniería manual</td>
<td>Aprendidas automáticamente</td>
</tr>
<tr class="even">
<td>Escalabilidad</td>
<td>Mejora limitada con más datos</td>
<td>Mejora continua con más datos</td>
</tr>
<tr class="odd">
<td>Dominios</td>
<td>Tabulares, estructurados</td>
<td>Imágenes, texto, audio, secuencias</td>
</tr>
<tr class="even">
<td>Interpretabilidad</td>
<td>Suele ser más interpretable</td>
<td>Modelos más “caja negra”</td>
</tr>
</tbody>
</table>
</section>
<section id="aplicaciones-industriales-actuales" class="level3">
<h3 class="anchored" data-anchor-id="aplicaciones-industriales-actuales">Aplicaciones industriales actuales</h3>
<ul>
<li><strong>Visión artificial</strong>: Detección de objetos, reconocimiento facial, vehículos autónomos, diagnóstico por imagen (radiología, dermatología).</li>
<li><strong>Procesamiento de lenguaje natural (NLP)</strong>: Traducción automática, chatbots, análisis de sentimiento, resumen de textos, modelos de lenguaje (GPT, BERT).</li>
<li><strong>Sistemas de recomendación</strong>: Netflix, Spotify, Amazon y redes sociales usan redes profundas para personalizar contenido y anuncios.</li>
<li><strong>Audio</strong>: Reconocimiento de voz (asistentes), generación de voz sintética, separación de fuentes.</li>
</ul>
</section>
<section id="por-qué-deep-learning-funciona-mejor-con-grandes-volúmenes-de-datos" class="level3">
<h3 class="anchored" data-anchor-id="por-qué-deep-learning-funciona-mejor-con-grandes-volúmenes-de-datos">¿Por qué Deep Learning funciona mejor con grandes volúmenes de datos?</h3>
<p>Las redes profundas tienen <strong>millones (o miles de millones) de parámetros</strong>. Con <strong>pocos datos</strong>, esos parámetros se ajustan demasiado a los ejemplos de entrenamiento y el modelo <strong>sobreajusta</strong>: funciona bien en train pero mal en datos nuevos. Con <strong>muchos datos</strong>, el modelo puede aprender patrones estadísticamente estables y generalizables sin memorizar casos concretos. Por eso el auge del Deep Learning está ligado a la disponibilidad de grandes datasets y capacidad de cómputo (GPUs).</p>
<hr>
</section>
</section>
<section id="representación-matemática-de-los-datos" class="level2">
<h2 class="anchored" data-anchor-id="representación-matemática-de-los-datos">2. Representación Matemática de los Datos</h2>
<p>Para entender cómo aprenden las redes neuronales es esencial manejar la representación matemática de los datos y las operaciones que se hacen sobre ellos.</p>
<section id="conceptos-clave" class="level3">
<h3 class="anchored" data-anchor-id="conceptos-clave">Conceptos clave</h3>
<ul>
<li><p><strong>Vector</strong>: Una lista ordenada de números (en ML suele ser un vector columna). Representa las <strong>características (features)</strong> de una sola muestra. Ejemplo: una persona puede describirse por el vector <img src="https://latex.codecogs.com/png.latex?(1.75,%2070,%2025)"> (altura en m, peso en kg, edad en años). La <strong>longitud</strong> del vector es la <strong>dimensionalidad</strong> del problema (aquí, 3).</p></li>
<li><p><strong>Matriz</strong>: Un conjunto de vectores dispuestos en filas (o columnas). En ML es habitual que <strong>cada fila sea una muestra</strong> y <strong>cada columna sea una feature</strong>. Así, una matriz <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BX%7D"> de tamaño <img src="https://latex.codecogs.com/png.latex?m%20%5Ctimes%20n"> tiene <img src="https://latex.codecogs.com/png.latex?m"> muestras y <img src="https://latex.codecogs.com/png.latex?n"> features. Todas las operaciones de un batch (lote) de datos se expresan con esta matriz.</p></li>
<li><p><strong>Dimensionalidad</strong>: El número de features (columnas) indica la “cantidad de información” que usamos para describir cada muestra. En redes profundas se trabaja con dimensionalidades altas (cientos o miles), lo que hace imprescindible el uso eficiente de operaciones matriciales.</p></li>
</ul>
</section>
<section id="operaciones-fundamentales" class="level3">
<h3 class="anchored" data-anchor-id="operaciones-fundamentales">Operaciones fundamentales</h3>
<ul>
<li><p><strong>Producto punto</strong> (dot product) entre dos vectores: <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Ba%7D%20%5Ccdot%20%5Cmathbf%7Bb%7D%20=%20%5Csum_i%20a_i%20b_i">. Da un <strong>escalar</strong>. Si pensamos en <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Ba%7D"> como datos y <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bb%7D"> como pesos, el producto punto es la “combinación lineal” que usa una neurona para una sola muestra.</p></li>
<li><p><strong>Multiplicación matricial</strong>: Para matrices <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BA%7D"> (tamaño <img src="https://latex.codecogs.com/png.latex?m%20%5Ctimes%20k">) y <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BB%7D"> (<img src="https://latex.codecogs.com/png.latex?k%20%5Ctimes%20n">), el resultado <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BC%7D%20=%20%5Cmathbf%7BA%7D%5Cmathbf%7BB%7D"> tiene tamaño <img src="https://latex.codecogs.com/png.latex?m%20%5Ctimes%20n"> con <img src="https://latex.codecogs.com/png.latex?(%5Cmathbf%7BAB%7D)_%7Bij%7D%20=%20%5Csum_%7Bk%7D%20A_%7Bik%7D%20B_%7Bkj%7D">. Así podemos aplicar el mismo conjunto de pesos a <strong>todas</strong> las muestras de un batch en una sola operación.</p></li>
<li><p><strong>Interpretación geométrica</strong>: Los vectores de datos viven en un <strong>espacio de características</strong> (cada eje es una feature). Vectores <strong>cercanos</strong> en ese espacio suelen corresponder a muestras <strong>similares</strong>. Las transformaciones lineales (producto por una matriz de pesos) rotan y escalan ese espacio; las funciones de activación introducen no linealidad y permiten modelar fronteras de decisión complejas.</p></li>
</ul>
<div id="ba915a05" class="cell" data-execution_count="41">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo: Vectores y matrices en NumPy</span></span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Un vector (una muestra con 3 features: ej. altura, peso, edad)</span></span>
<span id="cb2-4">x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.75</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>])</span>
<span id="cb2-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Vector (una muestra):"</span>, x)</span>
<span id="cb2-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dimensionalidad:"</span>, x.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="cb2-7"></span>
<span id="cb2-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Una matriz (dataset de 4 muestras, 3 features)</span></span>
<span id="cb2-9">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([</span>
<span id="cb2-10">    [<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.75</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span>],   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># persona 1</span></span>
<span id="cb2-11">    [<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.60</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>],   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># persona 2</span></span>
<span id="cb2-12">    [<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.85</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">90</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>],   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># persona 3</span></span>
<span id="cb2-13">    [<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.70</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span>],   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># persona 4</span></span>
<span id="cb2-14">])</span>
<span id="cb2-15"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Matriz (dataset):"</span>)</span>
<span id="cb2-16"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(X)</span>
<span id="cb2-17"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Forma: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> muestras × </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> features"</span>.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span>(X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]))</span>
<span id="cb2-18"></span>
<span id="cb2-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Producto punto entre dos vectores</span></span>
<span id="cb2-20">w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>])</span>
<span id="cb2-21">producto_punto <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.dot(x, w)</span>
<span id="cb2-22"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Producto punto x · w ="</span>, producto_punto)</span>
<span id="cb2-23"></span>
<span id="cb2-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Multiplicación matricial: X @ w (cada fila de X con w)</span></span>
<span id="cb2-25">predicciones <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> w  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># o np.dot(X, w)</span></span>
<span id="cb2-26"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Predicciones para todas las muestras:"</span>, predicciones)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Vector (una muestra): [ 1.75 70.   25.  ]
Dimensionalidad: 3

Matriz (dataset):
[[ 1.75 70.   25.  ]
 [ 1.6  55.   30.  ]
 [ 1.85 90.   22.  ]
 [ 1.7  65.   28.  ]]
Forma: 4 muestras × 3 features

Producto punto x · w = 2.875
Predicciones para todas las muestras: [2.875 0.3   5.525 1.75 ]</code></pre>
</div>
</div>
<hr>
</section>
</section>
<section id="modelo-neuronal-básico-intuición" class="level2">
<h2 class="anchored" data-anchor-id="modelo-neuronal-básico-intuición">3. Modelo Neuronal Básico (Intuición)</h2>
<p>Una <strong>neurona artificial</strong> es el bloque constructivo de las redes profundas. Matemáticamente es un <strong>modelo lineal</strong> (suma ponderada de entradas más bias) seguido opcionalmente de una <strong>función de activación</strong> no lineal.</p>
<section id="fórmula-de-una-neurona" class="level3">
<h3 class="anchored" data-anchor-id="fórmula-de-una-neurona">Fórmula de una neurona</h3>
<p><img src="https://latex.codecogs.com/png.latex?z%20=%20%5Cmathbf%7Bw%7D%5ET%20%5Cmathbf%7Bx%7D%20+%20b%20=%20w_1%20x_1%20+%20w_2%20x_2%20+%20%5Cldots%20+%20w_n%20x_n%20+%20b"></p>
<ul>
<li><p><strong><img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bw%7D"></strong> (pesos): Vector de coeficientes que indica <strong>qué tan importante</strong> es cada feature para la salida. Un peso grande en valor absoluto significa que esa entrada influye mucho; un peso cercano a cero la “apaga”.</p></li>
<li><p><strong><img src="https://latex.codecogs.com/png.latex?b"></strong> (bias): Un escalar que <strong>desplaza</strong> la salida. Permite que la neurona “active” incluso cuando la suma ponderada <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bw%7D%5ET%5Cmathbf%7Bx%7D"> es cero, lo que da más flexibilidad para definir fronteras de decisión que no pasen por el origen.</p></li>
<li><p><strong>Suma ponderada</strong>: La expresión <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bw%7D%5ET%20%5Cmathbf%7Bx%7D"> es exactamente el producto punto entre pesos y entradas: combina todas las features en un único número. Es la misma idea que en regresión lineal; la diferencia con una “red” aparece cuando encadenamos varias de estas operaciones y añadimos no linealidad entre capas.</p></li>
</ul>
</section>
<section id="interpretación-geométrica" class="level3">
<h3 class="anchored" data-anchor-id="interpretación-geométrica">Interpretación geométrica</h3>
<p>En clasificación binaria, la ecuación <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bw%7D%5ET%20%5Cmathbf%7Bx%7D%20+%20b%20=%200"> define un <strong>hiperplano</strong> en el espacio de features. Los puntos de un lado del hiperplano se clasifican en una clase y los del otro en la otra. Los pesos <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bw%7D"> definen la <strong>orientación</strong> del hiperplano y el bias <img src="https://latex.codecogs.com/png.latex?b"> su <strong>posición</strong>. Una sola neurona (sin activación) solo puede separar clases que sean <strong>linealmente separables</strong>; por eso las redes usan muchas neuronas y funciones de activación para modelar fronteras no lineales.</p>
</section>
<section id="representación-matricial" class="level3">
<h3 class="anchored" data-anchor-id="representación-matricial">Representación matricial</h3>
<p>Para procesar un <strong>batch</strong> de <img src="https://latex.codecogs.com/png.latex?m"> muestras a la vez: <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BZ%7D%20=%20%5Cmathbf%7BX%7D%20%5Cmathbf%7BW%7D%20+%20%5Cmathbf%7Bb%7D"></p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BX%7D">: matriz <img src="https://latex.codecogs.com/png.latex?(m%20%5Ctimes%20n)"> (m muestras, n features).</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BW%7D">: matriz <img src="https://latex.codecogs.com/png.latex?(n%20%5Ctimes%201)"> (o vector de n componentes).</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7Bb%7D">: escalar que se suma a cada fila por <strong>broadcasting</strong>.</li>
</ul>
<p>Cada fila de <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BZ%7D"> es la salida <img src="https://latex.codecogs.com/png.latex?z"> de la neurona para la muestra correspondiente. Esta forma es la que se implementa en código (y en GPUs) para ser eficiente.</p>
</section>
<section id="redes-más-importantes-y-dónde-se-usan" class="level3">
<h3 class="anchored" data-anchor-id="redes-más-importantes-y-dónde-se-usan">Redes más importantes y dónde se usan</h3>
<p>A partir de neuronas y capas se construyen <strong>arquitecturas</strong> que dominan el Deep Learning actual:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 12%">
<col style="width: 48%">
<col style="width: 38%">
</colgroup>
<thead>
<tr class="header">
<th>Red</th>
<th>Descripción breve</th>
<th>Uso frecuente</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>MLP</strong> (Perceptrón multicapa)</td>
<td>Capas densas apiladas con activación no lineal.</td>
<td>Datos tabulares, clasificación/regresión general, embeddings.</td>
</tr>
<tr class="even">
<td><strong>CNN</strong> (Redes convolucionales)</td>
<td>Convoluciones que capturan patrones locales (bordes, texturas).</td>
<td><strong>Visión por computador</strong>: clasificación de imágenes, detección de objetos, segmentación, vídeo.</td>
</tr>
<tr class="odd">
<td><strong>RNN</strong> (Redes recurrentes)</td>
<td>Conexiones que dependen del paso de tiempo (estado oculto).</td>
<td><strong>Secuencias</strong>: series temporales, texto (antes de Transformers).</td>
</tr>
<tr class="even">
<td><strong>LSTM</strong> / <strong>GRU</strong></td>
<td>RNN con mecanismos de memoria (gates) para dependencias largas.</td>
<td>Traducción, predicción de series, modelado de lenguaje (histórico).</td>
</tr>
<tr class="odd">
<td><strong>Transformer</strong></td>
<td>Atención (attention) sobre secuencias, sin recurrencia explícita.</td>
<td><strong>NLP</strong>: BERT, GPT, traducción; también visión (ViT) y multimodal.</td>
</tr>
<tr class="even">
<td><strong>GAN</strong> (Red generativa adversarial)</td>
<td>Generador vs discriminador en juego adversarial.</td>
<td>Generación de imágenes, datos sintéticos, superresolución, arte.</td>
</tr>
<tr class="odd">
<td><strong>Autoencoders</strong></td>
<td>Codificador + decodificador; aprendizaje no supervisado.</td>
<td>Reducción de dimensionalidad, detección de anomalías, denoising.</td>
</tr>
</tbody>
</table>
<p>En la práctica: <strong>CNN</strong> para imágenes; <strong>Transformer</strong> para lenguaje y modelos multimodales; <strong>RNN/LSTM</strong> en series temporales; <strong>GAN</strong> y <strong>autoencoders</strong> para generación y representaciones no supervisadas.</p>
<div id="136ca773" class="cell" data-execution_count="42">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación del modelo neuronal básico (sin activación)</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> neurona_lineal(X, w, b):</span>
<span id="cb4-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb4-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Modelo lineal: z = X @ w + b</span></span>
<span id="cb4-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    X: (n_muestras, n_features)</span></span>
<span id="cb4-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    w: (n_features,)</span></span>
<span id="cb4-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    b: escalar</span></span>
<span id="cb4-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb4-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> b</span>
<span id="cb4-11"></span>
<span id="cb4-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo</span></span>
<span id="cb4-13">np.random.seed(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb4-14">X_ejemplo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.randn(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 100 muestras, 3 features</span></span>
<span id="cb4-15">w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8</span>])</span>
<span id="cb4-16">b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span></span>
<span id="cb4-17"></span>
<span id="cb4-18">z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> neurona_lineal(X_ejemplo, w, b)</span>
<span id="cb4-19"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Salida z (pre-activación) para las primeras 5 muestras:"</span>)</span>
<span id="cb4-20"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(z[:<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>])</span>
<span id="cb4-21"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Forma de z:"</span>, z.shape)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Salida z (pre-activación) para las primeras 5 muestras:
[ 0.9079872   0.74445138  0.28379648  0.13772153 -0.58496906]

Forma de z: (100,)</code></pre>
</div>
</div>
<hr>
</section>
</section>
<section id="funciones-de-activación" class="level2">
<h2 class="anchored" data-anchor-id="funciones-de-activación">4. Funciones de Activación</h2>
<p>Las funciones de activación se aplican <strong>elemento a elemento</strong> a la salida <img src="https://latex.codecogs.com/png.latex?z"> de una neurona (o de una capa), y son las que introducen la <strong>no linealidad</strong> en la red.</p>
<section id="por-qué-necesitamos-no-linealidad" class="level3">
<h3 class="anchored" data-anchor-id="por-qué-necesitamos-no-linealidad">¿Por qué necesitamos no linealidad?</h3>
<p>Si no hubiera activaciones no lineales, <strong>cualquier secuencia de capas lineales</strong> (multiplicación por matrices y suma de bias) se podría reescribir como <strong>una sola transformación lineal</strong> (una única matriz y un bias). Es decir, profundidad no aportaría nada. Con <strong>funciones de activación no lineales</strong> entre capas, cada capa puede deformar el espacio de representación de forma no lineal, y la composición de muchas de estas transformaciones permite aproximar fronteras de decisión y funciones muy complejas. Por eso las activaciones son imprescindibles en redes profundas.</p>
</section>
<section id="funciones-comunes" class="level3">
<h3 class="anchored" data-anchor-id="funciones-comunes">Funciones comunes</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 30%">
<col style="width: 30%">
<col style="width: 40%">
</colgroup>
<thead>
<tr class="header">
<th>Función</th>
<th>Fórmula</th>
<th>Uso típico</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Sigmoid</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Csigma(z)%20=%20%5Cfrac%7B1%7D%7B1+e%5E%7B-z%7D%7D"></td>
<td>Salida en (0,1); se interpreta como probabilidad. Muy usada en la <strong>última capa</strong> de clasificación binaria.</td>
</tr>
<tr class="even">
<td><strong>ReLU</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Ctext%7BReLU%7D(z)%20=%20%5Cmax(0,%20z)"></td>
<td><strong>Capas ocultas</strong> en la mayoría de arquitecturas actuales. Cero para <img src="https://latex.codecogs.com/png.latex?z%20%5Cle%200">, identidad para <img src="https://latex.codecogs.com/png.latex?z%20%3E%200">.</td>
</tr>
</tbody>
</table>
<p>Otras que suelen aparecer en la literatura: <strong>tanh</strong> (similar a sigmoid pero centrada en 0), <strong>Leaky ReLU</strong>, <strong>GELU</strong> (en Transformers), etc.</p>
</section>
<section id="comparación-y-problemas-típicos" class="level3">
<h3 class="anchored" data-anchor-id="comparación-y-problemas-típicos">Comparación y problemas típicos</h3>
<ul>
<li><p><strong>Sigmoid</strong>: Es <strong>suave</strong> y <strong>acotada</strong> en (0, 1), lo que ayuda a interpretar la salida como probabilidad. El inconveniente es el <strong>gradiente que se desvanece</strong>: cuando <img src="https://latex.codecogs.com/png.latex?%7Cz%7C"> es grande, la curva es muy plana y la derivada es casi cero, así que el gradiente que llega a capas anteriores es muy pequeño y el aprendizaje se estanca. Por eso no suele usarse en capas ocultas profundas.</p></li>
<li><p><strong>ReLU</strong>: Es <strong>simple</strong> de calcular y no satura para <img src="https://latex.codecogs.com/png.latex?z%20%3E%200"> (derivada 1), por lo que el gradiente fluye bien en esas neuronas “activas”. Las que dan <img src="https://latex.codecogs.com/png.latex?z%20%5Cle%200"> se “apagan” (salida 0, gradiente 0) y pueden dejar de aprender (“neurona muerta”), pero en la práctica ReLU suele entrenar más rápido y estable que sigmoid en capas ocultas y es el estándar en muchas arquitecturas.</p></li>
</ul>
</section>
<section id="tabla-ampliada-funciones-de-activación-y-problemas-típicos" class="level3">
<h3 class="anchored" data-anchor-id="tabla-ampliada-funciones-de-activación-y-problemas-típicos">Tabla ampliada: funciones de activación y problemas típicos</h3>
<p>En la siguiente tabla se listan más funciones de activación y en <strong>qué problemas típicos</strong> suelen usarse.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 13%">
<col style="width: 13%">
<col style="width: 24%">
<col style="width: 48%">
</colgroup>
<thead>
<tr class="header">
<th>Función</th>
<th>Fórmula</th>
<th>Uso en la red</th>
<th>Problemas típicos donde se usa</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Sigmoid</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Csigma(z)%20=%20%5Cfrac%7B1%7D%7B1+e%5E%7B-z%7D%7D"></td>
<td>Última capa (salida probabilística)</td>
<td><strong>Clasificación binaria</strong>, predicción de probabilidades (ej. click-through rate), gates en LSTM.</td>
</tr>
<tr class="even">
<td><strong>ReLU</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Ctext%7BReLU%7D(z)%20=%20%5Cmax(0,%20z)"></td>
<td>Capas ocultas (default)</td>
<td><strong>CNN</strong>, <strong>MLP</strong>, casi cualquier red moderna; regresión y clasificación.</td>
</tr>
<tr class="odd">
<td><strong>Tanh</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Ctanh(z)%20=%20%5Cfrac%7Be%5Ez%20-%20e%5E%7B-z%7D%7D%7Be%5Ez%20+%20e%5E%7B-z%7D%7D"></td>
<td>Capas ocultas (alternativa)</td>
<td><strong>RNN/LSTM</strong> (estado oculto centrado en 0), cuando se quiere salida en <img src="https://latex.codecogs.com/png.latex?(-1,%201)">.</td>
</tr>
<tr class="even">
<td><strong>Leaky ReLU</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Cmax(%5Calpha%20z,%20z)">, <img src="https://latex.codecogs.com/png.latex?%5Calpha%20%5Capprox%200.01"></td>
<td>Capas ocultas</td>
<td>Cuando ReLU produce muchas “neuronas muertas”; <strong>GANs</strong>, redes muy profundas.</td>
</tr>
<tr class="odd">
<td><strong>GELU</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?z%20%5Ccdot%20%5CPhi(z)"> (aproximada)</td>
<td>Capas ocultas</td>
<td><strong>Transformers</strong> (BERT, GPT), modelos de lenguaje; suavidad y mejor flujo de gradiente.</td>
</tr>
<tr class="even">
<td><strong>Softmax</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7Be%5E%7Bz_i%7D%7D%7B%5Csum_j%20e%5E%7Bz_j%7D%7D"></td>
<td>Última capa (multiclase)</td>
<td><strong>Clasificación multiclase</strong> (imágenes, NLP); salidas suman 1 y se interpretan como probabilidades.</td>
</tr>
<tr class="odd">
<td><strong>Linear</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?f(z)=z"></td>
<td>Última capa en regresión</td>
<td><strong>Regresión</strong> (predecir valor continuo: precios, cantidades, series temporales).</td>
</tr>
</tbody>
</table>
<p><strong>Resumen:</strong> En <strong>capas ocultas</strong> se usa sobre todo <strong>ReLU</strong> (o <strong>GELU</strong> en Transformers). En <strong>salida</strong>: <strong>Sigmoid</strong> → clasificación binaria; <strong>Softmax</strong> → clasificación multiclase; <strong>Linear</strong> → regresión.</p>
<div id="ebed4099" class="cell" data-execution_count="43">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación y visualización de funciones de activación</span></span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sigmoid(z):</span>
<span id="cb6-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>z))</span>
<span id="cb6-5"></span>
<span id="cb6-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> relu(z):</span>
<span id="cb6-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.maximum(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, z)</span>
<span id="cb6-8"></span>
<span id="cb6-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> tanh(z):</span>
<span id="cb6-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.tanh(z)</span>
<span id="cb6-11"></span>
<span id="cb6-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> leaky_relu(z, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>):</span>
<span id="cb6-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.where(z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, z, alpha <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> z)</span>
<span id="cb6-14"></span>
<span id="cb6-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> gelu(z):</span>
<span id="cb6-16">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Aproximación común: 0.5 * z * (1 + tanh(sqrt(2/pi) * (z + 0.044715 * z^3)))</span></span>
<span id="cb6-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.tanh(np.sqrt(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> np.pi) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.044715</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> z<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>)))</span>
<span id="cb6-18"></span>
<span id="cb6-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tabla resumen con pandas</span></span>
<span id="cb6-20">df_activaciones <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb6-21">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Función'</span>: [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sigmoid'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ReLU'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tanh'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Leaky ReLU'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'GELU'</span>],</span>
<span id="cb6-22">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Fórmula'</span>: [<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r'1/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">e</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">^</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">{-z}</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r'max</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">0,z</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r'tanh</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">z</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r'max</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">αz, z</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">, α≈0</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">.</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">01'</span>, <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r'z·Φ</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">z</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">aprox</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">.</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>],</span>
<span id="cb6-23">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Problemas típicos'</span>: [</span>
<span id="cb6-24">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Clasificación binaria, gates LSTM, probabilidades'</span>,</span>
<span id="cb6-25">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CNN, MLP, capas ocultas (estándar)'</span>,</span>
<span id="cb6-26">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'RNN/LSTM, estado centrado en (-1,1)'</span>,</span>
<span id="cb6-27">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'GANs, evitar neuronas muertas'</span>,</span>
<span id="cb6-28">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Transformers (BERT, GPT), NLP'</span></span>
<span id="cb6-29">    ]</span>
<span id="cb6-30">})</span>
<span id="cb6-31"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Resumen de funciones de activación y uso típico:</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb6-32">display(df_activaciones)</span>
<span id="cb6-33"></span>
<span id="cb6-34"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Graficar varias funciones</span></span>
<span id="cb6-35">z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>)</span>
<span id="cb6-36">fig, axes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>))</span>
<span id="cb6-37"></span>
<span id="cb6-38">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].plot(z, sigmoid(z), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'b-'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb6-39">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sigmoid'</span>)</span>
<span id="cb6-40">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span>)</span>
<span id="cb6-41">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].axhline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-42">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].axvline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-43">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb6-44"></span>
<span id="cb6-45">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].plot(z, relu(z), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'green'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb6-46">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ReLU'</span>)</span>
<span id="cb6-47">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span>)</span>
<span id="cb6-48">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].axhline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-49">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].axvline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-50">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb6-51"></span>
<span id="cb6-52">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].plot(z, tanh(z), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'darkorange'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb6-53">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tanh'</span>)</span>
<span id="cb6-54">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span>)</span>
<span id="cb6-55">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].axhline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-56">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].axvline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-57">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb6-58"></span>
<span id="cb6-59">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].plot(z, leaky_relu(z), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'purple'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb6-60">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Leaky ReLU (α=0.01)'</span>)</span>
<span id="cb6-61">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span>)</span>
<span id="cb6-62">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].axhline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-63">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].axvline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-64">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb6-65"></span>
<span id="cb6-66">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].plot(z, gelu(z), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'red'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb6-67">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'GELU (aprox.)'</span>)</span>
<span id="cb6-68">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span>)</span>
<span id="cb6-69">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].axhline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-70">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].axvline(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gray'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>)</span>
<span id="cb6-71">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb6-72"></span>
<span id="cb6-73">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].axis(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'off'</span>)</span>
<span id="cb6-74">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>].text(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Softmax y Linear</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">se usan en la capa</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> de salida</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">(multiclase / regresión)'</span>, ha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'center'</span>, va<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'center'</span>, fontsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>)</span>
<span id="cb6-75"></span>
<span id="cb6-76">plt.tight_layout()</span>
<span id="cb6-77">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Resumen de funciones de activación y uso típico:
</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">Función</th>
<th data-quarto-table-cell-role="th">Fórmula</th>
<th data-quarto-table-cell-role="th">Problemas típicos</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>Sigmoid</td>
<td>1/(1+e^{-z})</td>
<td>Clasificación binaria, gates LSTM, probabilidades</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>ReLU</td>
<td>max(0,z)</td>
<td>CNN, MLP, capas ocultas (estándar)</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>Tanh</td>
<td>tanh(z)</td>
<td>RNN/LSTM, estado centrado en (-1,1)</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>Leaky ReLU</td>
<td>max(αz, z), α≈0.01</td>
<td>GANs, evitar neuronas muertas</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>GELU</td>
<td>z·Φ(z) (aprox.)</td>
<td>Transformers (BERT, GPT), NLP</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-5-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
<section id="detalle-sigmoid" class="level3">
<h3 class="anchored" data-anchor-id="detalle-sigmoid">Detalle: Sigmoid</h3>
<ul>
<li><strong>Fórmula:</strong> <img src="https://latex.codecogs.com/png.latex?%5Csigma(z)%20=%20%5Cdfrac%7B1%7D%7B1%20+%20e%5E%7B-z%7D%7D">. Rango <img src="https://latex.codecogs.com/png.latex?(0,%201)">; se interpreta como probabilidad.</li>
<li><strong>Derivada:</strong> <img src="https://latex.codecogs.com/png.latex?%5Csigma'(z)%20=%20%5Csigma(z)(1%20-%20%5Csigma(z))">, útil en backpropagation.</li>
<li><strong>Problema:</strong> Para <img src="https://latex.codecogs.com/png.latex?%7Cz%7C"> grande la derivada <img src="https://latex.codecogs.com/png.latex?%5Capprox%200"> → <strong>gradiente que se desvanece</strong> en capas profundas. Por eso se evita en capas ocultas.</li>
</ul>
</section>
<section id="detalle-relu" class="level3">
<h3 class="anchored" data-anchor-id="detalle-relu">Detalle: ReLU</h3>
<ul>
<li><strong>Fórmula:</strong> <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BReLU%7D(z)%20=%20%5Cmax(0,%20z)">. Rango <img src="https://latex.codecogs.com/png.latex?%5B0,%20+%5Cinfty)">.</li>
<li><strong>Derivada:</strong> 1 si <img src="https://latex.codecogs.com/png.latex?z%3E0">, 0 si <img src="https://latex.codecogs.com/png.latex?z%5Cle%200"> → en la zona activa el gradiente <strong>no se atenúa</strong>.</li>
<li><strong>Ventaja:</strong> Cálculo barato, entrenamiento más estable. <strong>Riesgo:</strong> neuronas con <img src="https://latex.codecogs.com/png.latex?z%5Cle%200"> siempre pueden quedar “muertas” (gradiente 0).</li>
</ul>
</section>
<section id="otras-funciones-referencia" class="level3">
<h3 class="anchored" data-anchor-id="otras-funciones-referencia">Otras funciones (referencia)</h3>
<ul>
<li><strong>Tanh:</strong> Rango <img src="https://latex.codecogs.com/png.latex?(-1,1)">, centrada en 0; también sufre vanishing gradient.</li>
<li><strong>Leaky ReLU:</strong> <img src="https://latex.codecogs.com/png.latex?%5Cmax(%5Calpha%20z,%20z)"> con <img src="https://latex.codecogs.com/png.latex?%5Calpha"> pequeño; reduce neuronas muertas.</li>
<li><strong>GELU:</strong> Usada en Transformers; más costosa, mejor en redes muy profundas.</li>
</ul>
<hr>
</section>
</section>
<section id="función-de-pérdida" class="level2">
<h2 class="anchored" data-anchor-id="función-de-pérdida">5. Función de Pérdida</h2>
<p>La <strong>función de pérdida</strong> (o coste) es el criterio que el algoritmo de entrenamiento intenta <strong>minimizar</strong>. Conecta las predicciones del modelo con los datos reales y define qué significa “aprender” en términos numéricos.</p>
<section id="qué-significa-aprender" class="level3">
<h3 class="anchored" data-anchor-id="qué-significa-aprender">¿Qué significa “aprender”?</h3>
<p>En términos prácticos, <strong>aprender</strong> es ajustar los <strong>pesos</strong> (y bias) del modelo para que las <strong>predicciones</strong> <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"> se parezcan cada vez más a los <strong>valores reales</strong> <img src="https://latex.codecogs.com/png.latex?y"> observados en los datos. La función de pérdida <img src="https://latex.codecogs.com/png.latex?L"> asigna un <strong>número</strong> a cada conjunto de predicciones: cuanto mayor es <img src="https://latex.codecogs.com/png.latex?L">, peor encaja el modelo; el objetivo del entrenamiento es encontrar los pesos que hacen <img src="https://latex.codecogs.com/png.latex?L"> lo más pequeño posible. Así, la pérdida es el “termómetro” que guía el descenso de gradiente.</p>
</section>
<section id="funciones-de-pérdida-comunes" class="level3">
<h3 class="anchored" data-anchor-id="funciones-de-pérdida-comunes">Funciones de pérdida comunes</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 21%">
<col style="width: 28%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Tarea</th>
<th>Función</th>
<th>Fórmula (idea)</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Regresión</strong></td>
<td>MSE (Mean Squared Error)</td>
<td><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7Bn%7D%5Csum_i%20(y_i%20-%20%5Chat%7By%7D_i)%5E2"></td>
</tr>
<tr class="even">
<td><strong>Clasificación binaria</strong></td>
<td>Cross-Entropy binaria</td>
<td><img src="https://latex.codecogs.com/png.latex?-%5Cfrac%7B1%7D%7Bn%7D%5Csum_i%20%5Cbigl%5B%20y_i%20%5Clog(%5Chat%7Bp%7D_i)%20+%20(1-y_i)%5Clog(1-%5Chat%7Bp%7D_i)%20%5Cbigr%5D"></td>
</tr>
</tbody>
</table>
<p>En clasificación, <img src="https://latex.codecogs.com/png.latex?%5Chat%7Bp%7D_i"> es la probabilidad predicha para la clase positiva (por ejemplo, la salida de una sigmoid).</p>
</section>
<section id="interpretación" class="level3">
<h3 class="anchored" data-anchor-id="interpretación">Interpretación</h3>
<ul>
<li><p><strong>MSE</strong>: Es el <strong>promedio de los errores al cuadrado</strong>. El cuadrado hace que los errores <strong>grandes</strong> pesen mucho más que los pequeños, por lo que el modelo se ve “forzado” a corregir sobre todo las predicciones muy desviadas. Tiene una interpretación probabilística cuando asumimos ruido gaussiano en la salida.</p></li>
<li><p><strong>Cross-Entropy</strong>: Viene de la teoría de información: mide la “sorpresa” o <strong>discrepancia</strong> entre la distribución real de la etiqueta (one-hot o binaria) y la distribución predicha (probabilidades). Minimizar cross-entropy equivale a hacer que la distribución predicha se acerque a la real. Es la elección estándar en clasificación porque se combina bien con la sigmoid en la última capa y tiene buenas propiedades de gradiente. Una interpretación probabilística: si interpretamos <img src="https://latex.codecogs.com/png.latex?%5Chat%7Bp%7D"> como <img src="https://latex.codecogs.com/png.latex?P(%5Ctext%7Bclase%20positiva%7D)">, la cross-entropy es el negativo del logaritmo de la verosimilitud bajo un modelo Bernoulli.</p></li>
</ul>
</section>
<section id="otras-funciones-de-pérdida-referencia" class="level3">
<h3 class="anchored" data-anchor-id="otras-funciones-de-pérdida-referencia">Otras funciones de pérdida (referencia)</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 21%">
<col style="width: 39%">
<col style="width: 39%">
</colgroup>
<thead>
<tr class="header">
<th>Función</th>
<th>Fórmula (idea)</th>
<th>Cuándo usarla</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>MAE</strong> (L1)</td>
<td><img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7Bn%7D%5Csum_i%20%5Clvert%20y_i%20-%20%5Chat%7By%7D_i%20%5Crvert"></td>
<td>Regresión cuando hay <strong>outliers</strong>: los errores grandes no se amplifican al cuadrado.</td>
</tr>
<tr class="even">
<td><strong>Huber</strong></td>
<td>Cuadrática para <img src="https://latex.codecogs.com/png.latex?%5Clvert%20e%20%5Crvert%20%5Cle%20%5Cdelta">, lineal fuera</td>
<td>Regresión robusta: combina ventajas de MSE y MAE.</td>
</tr>
<tr class="odd">
<td><strong>Cross-Entropy multiclase</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?-%5Cfrac%7B1%7D%7Bn%7D%5Csum_i%20%5Csum_c%20y_%7Bi,c%7D%20%5Clog(%5Chat%7Bp%7D_%7Bi,c%7D)"></td>
<td>Clasificación con <strong>varias clases</strong>; <img src="https://latex.codecogs.com/png.latex?%5Chat%7Bp%7D"> sale de <strong>Softmax</strong> en la última capa.</td>
</tr>
</tbody>
</table>
</section>
<section id="gradientes-de-la-pérdida-para-backprop" class="level3">
<h3 class="anchored" data-anchor-id="gradientes-de-la-pérdida-para-backprop">Gradientes de la pérdida (para backprop)</h3>
<ul>
<li><strong>MSE</strong>: La derivada respecto a <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D_i"> es <img src="https://latex.codecogs.com/png.latex?2(%5Chat%7By%7D_i%20-%20y_i)"> (o <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B2%7D%7Bn%7D"> si se promedia). El gradiente “empuja” la predicción hacia el valor real.</li>
<li><strong>Cross-Entropy binaria + Sigmoid</strong>: Al combinar la pérdida con la derivada de la sigmoid, el gradiente respecto a la pre-activación <img src="https://latex.codecogs.com/png.latex?z"> resulta en la forma <strong><img src="https://latex.codecogs.com/png.latex?%5Chat%7Bp%7D%20-%20y"></strong>: muy simple y numéricamente estable, por eso es el estándar en clasificación binaria.</li>
</ul>
<div id="3062aacc" class="cell" data-execution_count="44">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implementación de funciones de pérdida</span></span>
<span id="cb8-2"></span>
<span id="cb8-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> mse(y_true, y_pred):</span>
<span id="cb8-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Mean Squared Error - Regresión"""</span></span>
<span id="cb8-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.mean((y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_pred) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb8-6"></span>
<span id="cb8-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> cross_entropy_binary(y_true, y_pred_prob):</span>
<span id="cb8-8">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb8-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Cross-Entropy para clasificación binaria.</span></span>
<span id="cb8-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    y_true: etiquetas 0 o 1</span></span>
<span id="cb8-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    y_pred_prob: probabilidades en [0, 1] (salida de sigmoid)</span></span>
<span id="cb8-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb8-13">    eps <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-15</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Evitar log(0)</span></span>
<span id="cb8-14">    y_pred_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.clip(y_pred_prob, eps, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> eps)</span>
<span id="cb8-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>np.mean(y_true <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.log(y_pred_prob) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_true) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.log(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_pred_prob))</span>
<span id="cb8-16"></span>
<span id="cb8-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo MSE</span></span>
<span id="cb8-18">y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>])</span>
<span id="cb8-19">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.2</span>])</span>
<span id="cb8-20"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MSE:"</span>, mse(y_real, y_pred))</span>
<span id="cb8-21"></span>
<span id="cb8-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo Cross-Entropy</span></span>
<span id="cb8-23">y_true_bin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="cb8-24">y_prob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Buenas predicciones</span></span>
<span id="cb8-25"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cross-Entropy (buenas pred):"</span>, cross_entropy_binary(y_true_bin, y_prob))</span>
<span id="cb8-26">y_prob_mala <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Malas predicciones</span></span>
<span id="cb8-27"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cross-Entropy (malas pred):"</span>, cross_entropy_binary(y_true_bin, y_prob_mala))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>MSE: 0.030000000000000023
Cross-Entropy (buenas pred): 0.1976348816421487
Cross-Entropy (malas pred): 1.1614980451270867</code></pre>
</div>
</div>
<hr>
</section>
</section>
<section id="intuición-del-gradiente-y-aprendizaje" class="level2">
<h2 class="anchored" data-anchor-id="intuición-del-gradiente-y-aprendizaje">6. Intuición del Gradiente y Aprendizaje</h2>
<p>El <strong>gradiente</strong> de la función de pérdida respecto a los pesos es lo que indica <strong>cómo</strong> cambiar cada peso para reducir la pérdida. El algoritmo estándar que usa esa información es el <strong>descenso de gradiente</strong>.</p>
<section id="conceptos-clave-1" class="level3">
<h3 class="anchored" data-anchor-id="conceptos-clave-1">Conceptos clave</h3>
<ul>
<li><p><strong>Derivada</strong>: En una variable, la derivada de una función en un punto es la <strong>pendiente</strong> de la recta tangente en ese punto. Indica si la función crece o decrece al moverse un poco y con qué “velocidad”. Para minimizar la pérdida, interesa saber en qué dirección <strong>decrece</strong> <img src="https://latex.codecogs.com/png.latex?L">.</p></li>
<li><p><strong>Gradiente</strong>: En varias variables, el <strong>gradiente</strong> <img src="https://latex.codecogs.com/png.latex?%5Cnabla%20L"> es el vector cuyas componentes son las <strong>derivadas parciales</strong> de <img src="https://latex.codecogs.com/png.latex?L"> respecto a cada peso. El gradiente apunta en la dirección en que <img src="https://latex.codecogs.com/png.latex?L"> <strong>aumenta</strong> más rápido. Por tanto, para <strong>minimizar</strong> <img src="https://latex.codecogs.com/png.latex?L"> se avanza en la dirección <strong>opuesta</strong> al gradiente: <img src="https://latex.codecogs.com/png.latex?-%5Cnabla%20L">.</p></li>
<li><p><strong>Descenso de gradiente</strong>: Se actualiza cada peso restando una fracción del gradiente (es decir, dando un “paso” en la dirección que reduce la pérdida). Repitiendo este proceso muchas veces (épocas), se tiende a un mínimo (local o global) de la pérdida.</p></li>
</ul>
</section>
<section id="actualización-de-pesos" class="level3">
<h3 class="anchored" data-anchor-id="actualización-de-pesos">Actualización de pesos</h3>
<p><img src="https://latex.codecogs.com/png.latex?w_%7B%5Ctext%7Bnuevo%7D%7D%20=%20w_%7B%5Ctext%7Bviejo%7D%7D%20-%20%5Ceta%20%5Ccdot%20%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20w%7D"></p>
<ul>
<li><strong><img src="https://latex.codecogs.com/png.latex?%5Ceta"></strong> (learning rate, tasa de aprendizaje): Es el <strong>tamaño del paso</strong>. Si es <strong>muy alto</strong>, los pasos son grandes y puede producirse overshoot del mínimo, incluso divergencia; si es <strong>muy bajo</strong>, se avanza muy despacio y el entrenamiento es lento y puede quedarse atascado en zonas planas. En la práctica se suele elegir <img src="https://latex.codecogs.com/png.latex?%5Ceta"> por validación o con schedulers que lo reducen con el tiempo.</li>
</ul>
</section>
<section id="flujo-del-entrenamiento-una-época" class="level3">
<h3 class="anchored" data-anchor-id="flujo-del-entrenamiento-una-época">Flujo del entrenamiento (una época)</h3>
<ol type="1">
<li><strong>Forward pass</strong>: Con los pesos actuales, se calculan las salidas de cada capa (productos por matrices, bias, activaciones) hasta obtener las <strong>predicciones</strong> y, con ellas, el valor de la <strong>pérdida</strong> <img src="https://latex.codecogs.com/png.latex?L">.</li>
<li><strong>Backward pass (backpropagation)</strong>: Se calculan las <strong>derivadas</strong> de <img src="https://latex.codecogs.com/png.latex?L"> respecto a cada peso y cada activación intermedia, aplicando la regla de la cadena. El resultado es el <strong>gradiente</strong> <img src="https://latex.codecogs.com/png.latex?%5Cpartial%20L%20/%20%5Cpartial%20w"> para cada peso.</li>
<li><strong>Actualización</strong>: Cada peso se actualiza con la regla anterior: <img src="https://latex.codecogs.com/png.latex?w%20%5Cleftarrow%20w%20-%20%5Ceta%20%5C,%20%5Cpartial%20L%20/%20%5Cpartial%20w"> (y lo mismo para el bias).</li>
<li>Se repite para muchos <strong>batches</strong> y muchas <strong>épocas</strong> hasta que la pérdida se estabilice o se cumpla un criterio de parada.</li>
</ol>
</section>
<section id="regla-de-la-cadena-y-backpropagation" class="level3">
<h3 class="anchored" data-anchor-id="regla-de-la-cadena-y-backpropagation">Regla de la cadena y backpropagation</h3>
<p>En una red con muchas capas, <img src="https://latex.codecogs.com/png.latex?L"> depende de los pesos de la <strong>última</strong> capa a través de las salidas, y esas salidas dependen de la capa anterior, y así sucesivamente. La <strong>regla de la cadena</strong> del cálculo permite escribir <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B%5Cpartial%20L%7D%7B%5Cpartial%20w%7D"> como producto de derivadas a lo largo del camino desde <img src="https://latex.codecogs.com/png.latex?L"> hasta <img src="https://latex.codecogs.com/png.latex?w">. El algoritmo <strong>backpropagation</strong> calcula esas derivadas de atrás hacia adelante: primero las de la capa de salida, luego las de la penúltima, etc., reutilizando resultados ya calculados. Así se obtienen de forma eficiente los gradientes de todos los pesos con una sola pasada hacia atrás.</p>
</section>
<section id="batch-estocástico-y-mini-batch" class="level3">
<h3 class="anchored" data-anchor-id="batch-estocástico-y-mini-batch">Batch, estocástico y mini-batch</h3>
<ul>
<li><strong>Batch (lote completo)</strong>: Se usa <strong>todo</strong> el conjunto de entrenamiento para calcular el gradiente en cada paso. Estable pero costoso en memoria y cómputo; el gradiente es muy preciso pero hay pocos pasos por época.</li>
<li><strong>Estocástico (SGD por muestra)</strong>: Se actualizan los pesos con el gradiente de <strong>una sola</strong> muestra cada vez. Mucha variabilidad, muchos pasos por época; puede escapar de mínimos locales pero es ruidoso.</li>
<li><strong>Mini-batch</strong>: Se toman <strong>grupos</strong> de <img src="https://latex.codecogs.com/png.latex?k"> muestras (por ejemplo 32 o 64), se calcula el gradiente sobre ese mini-batch y se actualiza. Equilibrio entre estabilidad y velocidad; es lo más usado en la práctica.</li>
</ul>
</section>
<section id="learning-rate-y-schedulers" class="level3">
<h3 class="anchored" data-anchor-id="learning-rate-y-schedulers">Learning rate y schedulers</h3>
<p>El <strong>learning rate</strong> <img src="https://latex.codecogs.com/png.latex?%5Ceta"> controla el tamaño del paso. Si es <strong>muy alto</strong>, la pérdida puede oscilar o divergir; si es <strong>muy bajo</strong>, el entrenamiento es lento. Los <strong>schedulers</strong> cambian <img src="https://latex.codecogs.com/png.latex?%5Ceta"> a lo largo del entrenamiento (por ejemplo reducirlo cada cierto número de épocas o cuando la pérdida se estanca), lo que suele mejorar la convergencia y la calidad final.</p>
</section>
<section id="mínimos-locales-y-gradientes" class="level3">
<h3 class="anchored" data-anchor-id="mínimos-locales-y-gradientes">Mínimos locales y gradientes</h3>
<ul>
<li><strong>Mínimos locales</strong>: La pérdida puede tener varios “valles”; el descenso de gradiente puede quedarse en un mínimo local en lugar del global. En redes grandes, hay tantos parámetros que los mínimos “malos” son menos frecuentes de lo que se pensaba; además, el ruido del mini-batch ayuda a escapar de algunos.</li>
<li><strong>Gradientes que se desvanecen</strong>: En redes muy profundas, si las derivadas son menores que 1 en cada capa, el gradiente puede volverse casi cero al propagarse hacia atrás; las capas iniciales aprenden muy lento. Soluciones: activaciones como ReLU, inicialización adecuada, y a veces capas residuales (ResNet).</li>
<li><strong>Gradientes que explotan</strong>: Si las derivadas son mayores que 1, el gradiente puede crecer descontroladamente. Soluciones: reducir <img src="https://latex.codecogs.com/png.latex?%5Ceta">, <strong>gradient clipping</strong> (limitar la norma del gradiente) y buenas prácticas de inicialización.</li>
</ul>
<div id="e0cfeec6" class="cell" data-execution_count="45">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Visualización: Descenso de gradiente en 2D</span></span>
<span id="cb10-2"></span>
<span id="cb10-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Función de pérdida simple: L(w) = w^2 (mínimo en w=0)</span></span>
<span id="cb10-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> loss(w):</span>
<span id="cb10-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> w<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb10-6"></span>
<span id="cb10-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> grad_loss(w):</span>
<span id="cb10-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>w</span>
<span id="cb10-9"></span>
<span id="cb10-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simular descenso de gradiente</span></span>
<span id="cb10-11">np.random.seed(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb10-12">w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Punto inicial</span></span>
<span id="cb10-13">lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Learning rate</span></span>
<span id="cb10-14">history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [w]</span>
<span id="cb10-15"></span>
<span id="cb10-16"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>):</span>
<span id="cb10-17">    w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> w <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> grad_loss(w)</span>
<span id="cb10-18">    history.append(w)</span>
<span id="cb10-19"></span>
<span id="cb10-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Graficar</span></span>
<span id="cb10-21">w_vals <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>)</span>
<span id="cb10-22">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>))</span>
<span id="cb10-23">plt.plot(w_vals, loss(w_vals), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'b-'</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'L(w) = w²'</span>)</span>
<span id="cb10-24">plt.plot(history, [loss(wi) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> wi <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> history], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ro-'</span>, markersize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Descenso de gradiente'</span>)</span>
<span id="cb10-25">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'w'</span>)</span>
<span id="cb10-26">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Pérdida L(w)'</span>)</span>
<span id="cb10-27">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Intuición del descenso de gradiente: minimizar L(w)'</span>)</span>
<span id="cb10-28">plt.legend()</span>
<span id="cb10-29">plt.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb10-30">plt.tight_layout()</span>
<span id="cb10-31">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-7-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<hr>
</section>
</section>
<section id="evaluación-básica" class="level2">
<h2 class="anchored" data-anchor-id="evaluación-básica">7. Evaluación Básica</h2>
<p>Para saber si el modelo es útil en la práctica no basta con mirar cómo se comporta sobre los mismos datos con los que se entrenó; hay que evaluarlo sobre datos <strong>nuevos</strong>. Eso se hace con una <strong>división train/test</strong> (y a menudo con validación) y con métricas como la pérdida y el accuracy.</p>
<section id="división-traintest" class="level3">
<h3 class="anchored" data-anchor-id="división-traintest">División Train/Test</h3>
<ul>
<li><p><strong>Conjunto de entrenamiento (train)</strong>: Son los datos que el algoritmo usa para <strong>ajustar los pesos</strong> (mediante descenso de gradiente). El modelo “ve” muchas veces estos ejemplos durante las épocas.</p></li>
<li><p><strong>Conjunto de test</strong>: Son datos que el modelo <strong>no usa nunca</strong> durante el entrenamiento. Solo se usan <strong>al final</strong> para medir el rendimiento. Así se simula el comportamiento en datos “nuevos” y se evita evaluar solo sobre lo que el modelo ya ha memorizado o ajustado.</p></li>
</ul>
<p>Una división típica es 80% train y 20% test (o 70/30). Es importante que la división sea <strong>aleatoria</strong> (o estratificada por clase) para que train y test sean representativos de la misma distribución.</p>
</section>
<section id="concepto-de-generalización" class="level3">
<h3 class="anchored" data-anchor-id="concepto-de-generalización">Concepto de generalización</h3>
<p><strong>Generalizar</strong> significa que el modelo se comporta bien en <strong>datos que no ha visto</strong> durante el entrenamiento. Lo relevante en producción es precisamente ese rendimiento en datos nuevos.</p>
<ul>
<li>Si la <strong>pérdida (o error) en train</strong> es mucho <strong>menor</strong> que en test, el modelo está <strong>sobreajustando (overfitting)</strong>: ha “memorizado” o se ha adaptado demasiado al train y no captura patrones que se mantengan en test.</li>
<li>Si train y test tienen rendimiento similar y razonable, el modelo está generalizando bien.</li>
<li>Si tanto train como test van mal, puede haber <strong>subajuste (underfitting)</strong> (modelo muy simple o poco entrenamiento).</li>
</ul>
<p>Por eso es fundamental <strong>visualizar</strong> la pérdida (y si aplica, el accuracy) en train (y en validación si la hay) a lo largo de las épocas.</p>
</section>
<section id="métricas-a-visualizar" class="level3">
<h3 class="anchored" data-anchor-id="métricas-a-visualizar">Métricas a visualizar</h3>
<ul>
<li><p><strong>Curva de pérdida</strong>: En el eje X las <strong>épocas</strong> (o steps) y en el eje Y el valor de la <strong>pérdida</strong> en train (y opcionalmente en validación). Lo esperado es que baje y luego se estabilice. Si la pérdida de validación sube mientras la de train sigue bajando, es señal de overfitting.</p></li>
<li><p><strong>Accuracy</strong> (en clasificación): Proporción de ejemplos bien clasificados. Se puede graficar accuracy en train (y en validación) frente a las épocas. En el notebook aplicado se muestra también una comparación de accuracy en train vs test al final del entrenamiento.</p></li>
</ul>
</section>
<section id="train-validación-test" class="level3">
<h3 class="anchored" data-anchor-id="train-validación-test">Train / Validación / Test</h3>
<p>Además de train y test, es habitual usar un <strong>conjunto de validación</strong> (valid): datos que no se usan para entrenar ni para el reporte final, sino para <strong>elegir hiperparámetros</strong> (learning rate, número de épocas, tamaño del modelo, etc.) y para <strong>early stopping</strong> (parar cuando la pérdida en validación deja de mejorar). Así se evita “afinar” el modelo mirando el test; el test se reserva solo para una evaluación final y honesta. Una división típica es 70% train, 15% validación, 15% test (o 80/10/10).</p>
</section>
<section id="métricas-de-clasificación-más-allá-del-accuracy" class="level3">
<h3 class="anchored" data-anchor-id="métricas-de-clasificación-más-allá-del-accuracy">Métricas de clasificación (más allá del accuracy)</h3>
<p>Cuando las clases están desbalanceadas o el coste de equivocarse no es simétrico, el <strong>accuracy</strong> puede ser engañoso. Conviene considerar:</p>
<ul>
<li><strong>Precision</strong> (por clase positiva): de todos los que el modelo predijo como positivos, cuántos lo son realmente. <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BPrecision%7D%20=%20%5Cfrac%7BTP%7D%7BTP%20+%20FP%7D">.</li>
<li><strong>Recall</strong> (sensibilidad): de todos los positivos reales, cuántos detectó el modelo. <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BRecall%7D%20=%20%5Cfrac%7BTP%7D%7BTP%20+%20FN%7D">.</li>
<li><strong>F1</strong>: media armónica de precision y recall; resume ambos en un solo número. <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BF1%7D%20=%202%20%5Ccdot%20%5Cfrac%7B%5Ctext%7BPrecision%7D%20%5Ccdot%20%5Ctext%7BRecall%7D%7D%7B%5Ctext%7BPrecision%7D%20+%20%5Ctext%7BRecall%7D%7D">.</li>
</ul>
<p>(TP = verdaderos positivos, FP = falsos positivos, FN = falsos negativos.)</p>
</section>
<section id="matriz-de-confusión" class="level3">
<h3 class="anchored" data-anchor-id="matriz-de-confusión">Matriz de confusión</h3>
<p>La <strong>matriz de confusión</strong> es una tabla de 2×2 (en clasificación binaria) donde: - <strong>Filas</strong> = clase <strong>real</strong> (lo que dice la etiqueta). - <strong>Columnas</strong> = clase <strong>predicha</strong> (lo que dijo el modelo).</p>
<p>Cada celda cuenta cuántos ejemplos caen en esa combinación: - <strong>TN</strong> (arriba-izquierda): predijo negativo y era negativo → acierto. - <strong>FP</strong> (arriba-derecha): predijo positivo y era negativo → falso alarm. - <strong>FN</strong> (abajo-izquierda): predijo negativo y era positivo → se le escapó un positivo. - <strong>TP</strong> (abajo-derecha): predijo positivo y era positivo → acierto.</p>
<p>Así se puede ver de un vistazo si el modelo se equivoca más en una dirección (por ejemplo muchos FN si la clase positiva es la “importante”) y es la base para calcular precision, recall y F1. En Python se usa <code>confusion_matrix</code> de sklearn y suele dibujarse como heatmap.</p>
</section>
<section id="roc-y-auc" class="level3">
<h3 class="anchored" data-anchor-id="roc-y-auc">ROC y AUC</h3>
<p>Cuando el modelo devuelve <strong>probabilidades</strong> (p.&nbsp;ej. salida de sigmoid), no hay un único “umbral”: si se elige umbral 0.5 se clasifica como positivo cuando <img src="https://latex.codecogs.com/png.latex?P(%5Ctext%7Bpositivo%7D)%20%5Cgeq%200.5">, pero también se podría usar 0.3 o 0.7. La curva <strong>ROC</strong> muestra, para <strong>cada posible umbral</strong>, el trade-off entre: - <strong>Eje X</strong>: Tasa de falsos positivos (FP / (FP + TN)) — cuántos negativos se marcan como positivos. - <strong>Eje Y</strong>: Tasa de verdaderos positivos = Recall (TP / (TP + FN)) — cuántos positivos se detectan.</p>
<p>Un buen modelo tiene la curva “pegada” al borde superior-izquierdo (muchos TP, pocos FP). El <strong>AUC</strong> (área bajo esa curva) es un número entre 0 y 1: <strong>1</strong> = clasificador perfecto, <strong>0.5</strong> = como tirar una moneda, <strong>menor que 0.5</strong> = peor que aleatorio. Sirve para comparar modelos sin fijar un umbral. En Python: <code>roc_curve</code> y <code>roc_auc_score</code> de sklearn.</p>
<p>A continuación se ilustran con Python las métricas anteriores: matriz de confusión, curva ROC/AUC, Precision/Recall/F1 y un ejemplo de curvas de pérdida en entrenamiento.</p>
<div id="885a003b" class="cell" data-execution_count="46">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplos: Matriz de confusión, ROC/AUC, Precision/Recall/F1 y curvas de pérdida</span></span>
<span id="cb11-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.metrics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> (</span>
<span id="cb11-3">    confusion_matrix, ConfusionMatrixDisplay, roc_curve, roc_auc_score,</span>
<span id="cb11-4">    precision_score, recall_score, f1_score, classification_report</span>
<span id="cb11-5">)</span>
<span id="cb11-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.linear_model <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> LogisticRegression</span>
<span id="cb11-7"></span>
<span id="cb11-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Datos sintéticos y modelo rápido para tener predicciones y probabilidades</span></span>
<span id="cb11-9">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_classification(n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">400</span>, n_features<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, n_informative<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, n_classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-10">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-11"></span>
<span id="cb11-12">modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LogisticRegression(max_iter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-13">modelo.fit(X_train, y_train)</span>
<span id="cb11-14">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.predict(X_test)</span>
<span id="cb11-15">y_proba <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.predict_proba(X_test)[:, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># probabilidad de la clase 1</span></span>
<span id="cb11-16"></span>
<span id="cb11-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- 1) Matriz de confusión ---</span></span>
<span id="cb11-18">cm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> confusion_matrix(y_test, y_pred)</span>
<span id="cb11-19">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb11-20">ConfusionMatrixDisplay(cm, display_labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Negativo"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Positivo"</span>]).plot(ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax, values_format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"d"</span>)</span>
<span id="cb11-21">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Matriz de confusión (real = filas, predicho = columnas)"</span>)</span>
<span id="cb11-22">plt.tight_layout()</span>
<span id="cb11-23">plt.show()</span>
<span id="cb11-24"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Interpretación: TN (0→0), FP (0→1), FN (1→0), TP (1→1)."</span>)</span>
<span id="cb11-25"></span>
<span id="cb11-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- 2) Curva ROC y AUC ---</span></span>
<span id="cb11-27">fpr, tpr, _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_curve(y_test, y_proba)</span>
<span id="cb11-28">auc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> roc_auc_score(y_test, y_proba)</span>
<span id="cb11-29"></span>
<span id="cb11-30">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb11-31">ax.plot(fpr, tpr, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b-"</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"ROC (AUC = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>auc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb11-32">ax.plot([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"k--"</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Aleatorio (AUC = 0.5)"</span>)</span>
<span id="cb11-33">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tasa de falsos positivos"</span>)</span>
<span id="cb11-34">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tasa de verdaderos positivos (Recall)"</span>)</span>
<span id="cb11-35">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Curva ROC"</span>)</span>
<span id="cb11-36">ax.legend()</span>
<span id="cb11-37">ax.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb11-38">plt.tight_layout()</span>
<span id="cb11-39">plt.show()</span>
<span id="cb11-40"></span>
<span id="cb11-41"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- 3) Precision, Recall, F1 ---</span></span>
<span id="cb11-42">precision <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> precision_score(y_test, y_pred, average<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"binary"</span>)</span>
<span id="cb11-43">recall <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> recall_score(y_test, y_pred, average<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"binary"</span>)</span>
<span id="cb11-44">f1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> f1_score(y_test, y_pred, average<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"binary"</span>)</span>
<span id="cb11-45"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Reporte por clase (classification_report):"</span>)</span>
<span id="cb11-46"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(classification_report(y_test, y_pred, target_names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Negativo"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Positivo"</span>]))</span>
<span id="cb11-47"></span>
<span id="cb11-48">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb11-49">metricas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Precision"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Recall"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"F1"</span>]</span>
<span id="cb11-50">valores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [precision, recall, f1]</span>
<span id="cb11-51">colores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#2ecc71"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#3498db"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#9b59b6"</span>]</span>
<span id="cb11-52">ax.bar(metricas, valores, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>colores, edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8</span>)</span>
<span id="cb11-53">ax.set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.05</span>)</span>
<span id="cb11-54">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Valor"</span>)</span>
<span id="cb11-55">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Métricas de clasificación (clase positiva)"</span>)</span>
<span id="cb11-56"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, v <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(valores):</span>
<span id="cb11-57">    ax.text(i, v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.02</span>, <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>v<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>, ha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"center"</span>, fontsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>)</span>
<span id="cb11-58">plt.tight_layout()</span>
<span id="cb11-59">plt.show()</span>
<span id="cb11-60"></span>
<span id="cb11-61"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- 4) Ejemplo de curvas de pérdida (train vs validación) ---</span></span>
<span id="cb11-62"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Simulación: pérdida en train baja; en validación baja y luego sube un poco (overfitting)</span></span>
<span id="cb11-63">np.random.seed(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-64">epocas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span>)</span>
<span id="cb11-65">loss_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.8</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>epocas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.random.rand(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.03</span></span>
<span id="cb11-66">loss_valid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>epocas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.random.rand(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.04</span></span>
<span id="cb11-67">loss_valid[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>:] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> np.linspace(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.06</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sube al final (overfitting)</span></span>
<span id="cb11-68"></span>
<span id="cb11-69">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb11-70">ax.plot(epocas, loss_train, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"b-"</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pérdida train"</span>)</span>
<span id="cb11-71">ax.plot(epocas, loss_valid, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r-"</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pérdida validación"</span>)</span>
<span id="cb11-72">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Época"</span>)</span>
<span id="cb11-73">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pérdida"</span>)</span>
<span id="cb11-74">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ejemplo: curvas de pérdida (validación sube → señal de overfitting)"</span>)</span>
<span id="cb11-75">ax.legend()</span>
<span id="cb11-76">ax.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb11-77">plt.tight_layout()</span>
<span id="cb11-78">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-8-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Interpretación: TN (0→0), FP (0→1), FN (1→0), TP (1→1).</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-8-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Reporte por clase (classification_report):
              precision    recall  f1-score   support

    Negativo       0.86      0.78      0.82        64
    Positivo       0.77      0.86      0.81        56

    accuracy                           0.82       120
   macro avg       0.82      0.82      0.82       120
weighted avg       0.82      0.82      0.82       120
</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-8-output-5.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-8-output-6.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<hr>
</section>
</section>
<section id="notebook-aplicado" class="level2">
<h2 class="anchored" data-anchor-id="notebook-aplicado">8. Notebook Aplicado</h2>
<p>En esta sección se implementa un <strong>MLP (Multi-Layer Perceptron)</strong> sencillo con <strong>una capa oculta</strong>, entrenado <strong>desde cero</strong> usando solo NumPy. No se usa PyTorch ni TensorFlow; el objetivo es mostrar explícitamente:</p>
<ul>
<li>Cómo se construye el forward pass (capas lineales + ReLU en oculta + sigmoid en salida).</li>
<li>Cómo se calcula la pérdida (cross-entropy binaria).</li>
<li>Cómo se obtienen los gradientes con la regla de la cadena (backpropagation) y se actualizan los pesos con descenso de gradiente.</li>
</ul>
<p>Se usa un dataset de clasificación binaria sintético (generado con <code>make_classification</code> de scikit-learn), se hace división train/test, y se visualizan la <strong>curva de pérdida</strong> y el <strong>accuracy</strong> en train y test para comprobar que el modelo aprende y generaliza.</p>
<div id="1588987a" class="cell" data-execution_count="47">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 8.1 Carga del dataset</span></span>
<span id="cb14-2"></span>
<span id="cb14-3">X, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_classification(</span>
<span id="cb14-4">    n_samples<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>,</span>
<span id="cb14-5">    n_features<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>,</span>
<span id="cb14-6">    n_informative<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>,</span>
<span id="cb14-7">    n_redundant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>,</span>
<span id="cb14-8">    n_classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb14-9">    random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>,</span>
<span id="cb14-10">    flip_y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Un poco de ruido</span></span>
<span id="cb14-11">)</span>
<span id="cb14-12"></span>
<span id="cb14-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Normalizar features (buena práctica)</span></span>
<span id="cb14-14">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> X.mean(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (X.std(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-8</span>)</span>
<span id="cb14-15"></span>
<span id="cb14-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># División Train/Test (80% train, 20% test)</span></span>
<span id="cb14-17">X_train, X_test, y_train, y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> train_test_split(X, y, test_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>, random_state<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb14-18"></span>
<span id="cb14-19"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Dataset cargado:"</span>)</span>
<span id="cb14-20"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"  Train: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X_train<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> muestras, </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X_train<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> features"</span>)</span>
<span id="cb14-21"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"  Test:  </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> muestras"</span>)</span>
<span id="cb14-22"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"  Clases: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>np<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>unique(y)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Dataset cargado:
  Train: 800 muestras, 20 features
  Test:  200 muestras
  Clases: [0 1]</code></pre>
</div>
</div>
<div id="d7b34668" class="cell" data-execution_count="48">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 8.2 Construcción del modelo básico (MLP desde cero)</span></span>
<span id="cb16-2"></span>
<span id="cb16-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> MLPClasificador:</span>
<span id="cb16-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb16-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    MLP con 1 capa oculta: entrada -&gt; ReLU -&gt; salida -&gt; Sigmoid</span></span>
<span id="cb16-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb16-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, n_input, n_hidden, n_output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>, seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>):</span>
<span id="cb16-8">        np.random.seed(seed)</span>
<span id="cb16-9">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> lr</span>
<span id="cb16-10">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Inicialización He (buena para ReLU)</span></span>
<span id="cb16-11">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.randn(n_input, n_hidden) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.sqrt(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>n_input)</span>
<span id="cb16-12">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, n_hidden))</span>
<span id="cb16-13">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.randn(n_hidden, n_output) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.sqrt(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>n_hidden)</span>
<span id="cb16-14">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.zeros((<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, n_output))</span>
<span id="cb16-15"></span>
<span id="cb16-16">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sigmoid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, z):</span>
<span id="cb16-17">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>np.clip(z, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">500</span>)))</span>
<span id="cb16-18"></span>
<span id="cb16-19">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> relu(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, z):</span>
<span id="cb16-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.maximum(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, z)</span>
<span id="cb16-21"></span>
<span id="cb16-22">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> relu_deriv(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, z):</span>
<span id="cb16-23">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>)</span>
<span id="cb16-24"></span>
<span id="cb16-25">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X):</span>
<span id="cb16-26">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.z1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b1</span>
<span id="cb16-27">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.relu(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.z1)</span>
<span id="cb16-28">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.z2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b2</span>
<span id="cb16-29">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.sigmoid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.z2)</span>
<span id="cb16-30">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a2</span>
<span id="cb16-31"></span>
<span id="cb16-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> backward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X, y, output):</span>
<span id="cb16-33">        m <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb16-34">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Gradiente de Cross-Entropy + Sigmoid: dL/dz2 = output - y</span></span>
<span id="cb16-35">        dz2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y.reshape(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb16-36">        dW2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a1.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> dz2) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> m</span>
<span id="cb16-37">        db2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(dz2, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, keepdims<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> m</span>
<span id="cb16-38"></span>
<span id="cb16-39">        da1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dz2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W2.T</span>
<span id="cb16-40">        dz1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> da1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.relu_deriv(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.z1)</span>
<span id="cb16-41">        dW1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (X.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> dz1) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> m</span>
<span id="cb16-42">        db1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(dz1, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, keepdims<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> m</span>
<span id="cb16-43"></span>
<span id="cb16-44">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> dW2</span>
<span id="cb16-45">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> db2</span>
<span id="cb16-46">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> dW1</span>
<span id="cb16-47">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.b1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> db1</span>
<span id="cb16-48"></span>
<span id="cb16-49">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> fit(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X, y, epochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, verbose<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>):</span>
<span id="cb16-50">        history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'loss'</span>: [], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>: []}</span>
<span id="cb16-51">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(epochs):</span>
<span id="cb16-52">            output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.forward(X)</span>
<span id="cb16-53">            loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>np.mean(y.reshape(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>np.log(output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-8</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>y.reshape(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>np.log(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-8</span>))</span>
<span id="cb16-54">            pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>).flatten()</span>
<span id="cb16-55">            acc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.mean(pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> y)</span>
<span id="cb16-56">            history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'loss'</span>].append(loss)</span>
<span id="cb16-57">            history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>].append(acc)</span>
<span id="cb16-58">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.backward(X, y, output)</span>
<span id="cb16-59">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> verbose <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb16-60">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Epoch </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>epochs<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> - Loss: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>loss<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.4f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> - Accuracy: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.4f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb16-61">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history</span>
<span id="cb16-62"></span>
<span id="cb16-63">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> predict(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, X):</span>
<span id="cb16-64">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.forward(X) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>).flatten()</span>
<span id="cb16-65"></span>
<span id="cb16-66"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crear modelo</span></span>
<span id="cb16-67">modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MLPClasificador(n_input<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, n_hidden<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span>, lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>)</span></code></pre></div></div>
</div>
<div id="bdf853be" class="cell" data-execution_count="49">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 8.3 Entrenamiento del MLP</span></span>
<span id="cb17-2">history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.fit(X_train, y_train, epochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, verbose<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Epoch 20/100 - Loss: 0.4848 - Accuracy: 0.8000
Epoch 40/100 - Loss: 0.3951 - Accuracy: 0.8488
Epoch 60/100 - Loss: 0.3501 - Accuracy: 0.8750
Epoch 80/100 - Loss: 0.3208 - Accuracy: 0.8925
Epoch 100/100 - Loss: 0.2989 - Accuracy: 0.9000</code></pre>
</div>
</div>
<div id="812159b7" class="cell" data-execution_count="50">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 8.4 Visualización de curva de pérdida</span></span>
<span id="cb19-2"></span>
<span id="cb19-3">plt.figure(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb19-4">plt.plot(history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'loss'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'b-'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb19-5">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Época'</span>)</span>
<span id="cb19-6">plt.ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Pérdida (Cross-Entropy)'</span>)</span>
<span id="cb19-7">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Curva de pérdida durante el entrenamiento'</span>)</span>
<span id="cb19-8">plt.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb19-9">plt.tight_layout()</span>
<span id="cb19-10">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-12-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="f62a6cb7" class="cell" data-execution_count="51">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 8.5 Visualización de accuracy</span></span>
<span id="cb20-2"></span>
<span id="cb20-3">fig, axes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb20-4"></span>
<span id="cb20-5">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].plot(history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'green'</span>, linewidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb20-6">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Época'</span>)</span>
<span id="cb20-7">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Accuracy'</span>)</span>
<span id="cb20-8">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Accuracy en entrenamiento'</span>)</span>
<span id="cb20-9">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>)</span>
<span id="cb20-10"></span>
<span id="cb20-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Evaluar en test</span></span>
<span id="cb20-12">y_pred_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo.predict(X_test)</span>
<span id="cb20-13">acc_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.mean(y_pred_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> y_test)</span>
<span id="cb20-14">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].bar([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Train'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Test'</span>], [history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>][<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], acc_test], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'steelblue'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coral'</span>])</span>
<span id="cb20-15">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Accuracy'</span>)</span>
<span id="cb20-16">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Comparación Train vs Test (generalización)'</span>)</span>
<span id="cb20-17">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.05</span>)</span>
<span id="cb20-18"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, v <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>([history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>][<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], acc_test]):</span>
<span id="cb20-19">    axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>].text(i, v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.02</span>, <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>v<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.3f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, ha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'center'</span>, fontweight<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bold'</span>)</span>
<span id="cb20-20"></span>
<span id="cb20-21">plt.tight_layout()</span>
<span id="cb20-22">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/index_files/figure-html/cell-13-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="67969f27" class="cell" data-execution_count="52">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Resumen final</span></span>
<span id="cb21-2"></span>
<span id="cb21-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"="</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>)</span>
<span id="cb21-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"RESUMEN DEL MODELO"</span>)</span>
<span id="cb21-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"="</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>)</span>
<span id="cb21-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Accuracy en Train: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'accuracy'</span>][<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.4f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb21-7"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Accuracy en Test:  </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>acc_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.4f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb21-8"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Pérdida final:     </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>history[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'loss'</span>][<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.4f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb21-9"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">El modelo generaliza bien si Train ≈ Test."</span>)</span>
<span id="cb21-10"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Si Train &gt;&gt; Test → posible sobreajuste."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>==================================================
RESUMEN DEL MODELO
==================================================
Accuracy en Train: 0.9000
Accuracy en Test:  0.8550
Pérdida final:     0.2989

El modelo generaliza bien si Train ≈ Test.
Si Train &gt;&gt; Test → posible sobreajuste.</code></pre>
</div>
</div>
<hr>
</section>
<section id="sección-final-evaluación" class="level2">
<h2 class="anchored" data-anchor-id="sección-final-evaluación">Sección final: Evaluación</h2>
<p>A continuación se proponen <strong>10 preguntas</strong> sobre los conceptos y el código presentados en el notebook. Tres de ellas hacen referencia a <strong>fragmentos concretos de código</strong> del propio notebook.</p>
<ol type="1">
<li><p><strong>Deep Learning y datos:</strong> ¿Por qué el Deep Learning suele requerir grandes volúmenes de datos en comparación con el Machine Learning tradicional? Relacionar con el número de parámetros y el riesgo de sobreajuste.</p></li>
<li><p><strong>Funciones de activación:</strong> ¿Qué papel cumple la función de activación <strong>no lineal</strong> en una red neuronal? ¿Qué pasaría si todas las capas fueran solo transformaciones lineales (sin activación)?</p></li>
<li><p><strong>Pérdida MSE vs Cross-Entropy:</strong> Explique brevemente la diferencia entre MSE y Cross-Entropy binaria: ¿en qué tipo de tarea se usa cada una y por qué?</p></li>
<li><p><strong>Learning rate:</strong> ¿Qué indica el learning rate <img src="https://latex.codecogs.com/png.latex?%5Ceta"> en el descenso de gradiente? ¿Qué problemas puede haber si <img src="https://latex.codecogs.com/png.latex?%5Ceta"> es demasiado alto o demasiado bajo?</p></li>
<li><p><strong>Overfitting:</strong> ¿Qué significa <strong>overfitting</strong> y cómo se puede detectar observando las curvas de pérdida en train y en validación a lo largo de las épocas?</p></li>
<li><p><strong>Métricas de clasificación:</strong> ¿Para qué sirve la <strong>matriz de confusión</strong>? ¿Qué información aportan las métricas <strong>Precision</strong>, <strong>Recall</strong> y <strong>F1</strong> y cuándo son más útiles que el accuracy?</p></li>
<li><p><strong>ROC y AUC:</strong> ¿Qué representa el <strong>AUC</strong> en una curva ROC? ¿Qué valores indican un buen clasificador, uno aleatorio y uno peor que aleatorio?</p></li>
<li><p><strong>Forward del MLP (Sección 8):</strong> En el método <code>forward</code> del MLP se calcula <code>self.z1 = X @ self.W1 + self.b1</code> y luego <code>self.a1 = self.relu(self.z1)</code>. ¿Qué representa <strong>z1</strong> y qué representa <strong>a1</strong>? ¿Por qué se aplica ReLU en la capa oculta y no en la salida?</p></li>
<li><p><strong>Backward y gradiente (Sección 8):</strong> En el método <code>backward</code> del mismo MLP aparece la línea <code>dz2 = output - y.reshape(-1, 1)</code>. ¿Qué <strong>pérdida</strong> y qué <strong>activación de salida</strong> se están usando? ¿Por qué el gradiente respecto a la pre-activación de salida tiene exactamente esa forma?</p></li>
<li><p><strong>Matriz de confusión (Sección 7):</strong> En el ejemplo de métricas se usa <code>ConfusionMatrixDisplay(cm, display_labels=["Negativo", "Positivo"])</code>. Según la convención de scikit-learn, ¿qué representan las <strong>filas</strong> y las <strong>columnas</strong> de <code>cm</code> (clase real vs clase predicha)? ¿En qué posición de la matriz 2×2 estarían TN, FP, FN y TP?</p></li>
</ol>
<section id="te-sirvió" class="level3">
<h3 class="anchored" data-anchor-id="te-sirvió">💬 ¿Te sirvió?</h3>
<p>Deja en los comentarios <strong>una duda o un caso donde aplicarías esto</strong> — respondo todos. Sígueme para no perderte el próximo artículo de la serie y comparte con alguien que esté aprendiendo análisis de datos.</p>
<p>👉 El código completo está disponible para ejecutar directamente.</p>


</section>
</section>
</section>

 ]]></description>
  <category>deep-learning</category>
  <category>mlp</category>
  <category>fundamentos</category>
  <guid>https://biitt.com/es/blog/deep-learning/03-fundamentos-entrenamiento-mlp/</guid>
  <pubDate>Sat, 29 Aug 2026 05:00:00 GMT</pubDate>
</item>
</channel>
</rss>
