<?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/</link>
<atom:link href="https://biitt.com/es/blog/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>
<item>
  <title>Análisis Avanzado de Datos — 1. Regresión lineal</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/estadistica-fundamentos/01-regresion-lineal/</link>
  <description><![CDATA[ 




<section id="análisis-avanzado-de-datos-1.-regresión-lineal" class="level1">
<h1>Análisis Avanzado de Datos — 1. Regresión lineal</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="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 id="qué-es-la-regresión-lineal-y-qué-problema-resuelve" class="level2">
<h2 class="anchored" data-anchor-id="qué-es-la-regresión-lineal-y-qué-problema-resuelve">¿Qué es la regresión lineal y qué problema resuelve?</h2>
<p>Este es el primer notebook del Módulo 1, y vale la pena tomárselo con calma: la regresión lineal es la base sobre la que se construye prácticamente todo lo demás en este curso — regularización, modelos lineales generalizados, suavizado, incluso partes de los módulos de datos dependientes. Si entiendes bien esta pieza, todo lo que viene después te va a resultar mucho más natural.</p>
<p>En el fondo, la pregunta que resuelve la regresión es muy simple: <strong>¿puedes predecir un valor numérico a partir de otras variables que sí conoces?</strong></p>
<p>Piensa en ejemplos cotidianos:</p>
<ul>
<li>Predecir el precio de una casa a partir de su tamaño, su ubicación y su antigüedad.</li>
<li>Predecir las ventas del próximo mes a partir de la inversión en publicidad.</li>
<li>Predecir cómo va a evolucionar una enfermedad en un paciente a partir de variables clínicas como su edad, su presión arterial o su índice de masa corporal (IMC).</li>
</ul>
<p>En los tres casos tienes una variable que te interesa predecir (el <strong>objetivo</strong> o variable de respuesta, <img src="https://latex.codecogs.com/png.latex?y">) y una o más variables que usas para predecirla (las <strong>variables predictoras</strong> o <em>features</em>, <img src="https://latex.codecogs.com/png.latex?x">). La regresión lineal asume algo concreto: que la relación entre esas variables predictoras y el objetivo se puede aproximar razonablemente bien con una <strong>línea recta</strong> (o, con varias variables, con un plano o hiperplano).</p>
<p>Es un supuesto fuerte — el mundo real casi nunca es perfectamente lineal — pero es sorprendentemente útil como punto de partida: es fácil de ajustar, fácil de interpretar y, en muchos problemas, funciona sorprendentemente bien. Por eso es el primer modelo que vas a dominar a fondo en este curso.</p>
<p>A lo largo de este notebook vas a trabajar con el dataset <strong>diabetes</strong> de <code>scikit-learn</code>: datos clínicos de 442 pacientes (edad, sexo, IMC, presión arterial y varias mediciones de sangre) con los que vas a predecir un índice cuantitativo de progresión de la enfermedad un año después de la medición inicial. Es un dataset pequeño, real y viene incluido en la librería, así que todo el código de este notebook corre sin depender de archivos externos.</p>
<div id="7d781ba7" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:32.470550Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:32.470394Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:34.120428Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:34.119755Z&quot;}}" data-execution_count="35">
<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.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_diabetes</span>
<span id="cb1-4"></span>
<span id="cb1-5">diabetes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_diabetes(as_frame<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="cb1-6">X_completo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> diabetes.data</span>
<span id="cb1-7">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> diabetes.target  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># progresión de la enfermedad, medida un año después del inicio</span></span>
<span id="cb1-8"></span>
<span id="cb1-9"><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"Observaciones: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X_completo<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;">"</span>)</span>
<span id="cb1-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"Variables predictoras: </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;">list</span>(X_completo.columns)<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="cb1-11">X_completo.head()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Observaciones: 442
Variables predictoras: ['age', 'sex', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="35">
<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">age</th>
<th data-quarto-table-cell-role="th">sex</th>
<th data-quarto-table-cell-role="th">bmi</th>
<th data-quarto-table-cell-role="th">bp</th>
<th data-quarto-table-cell-role="th">s1</th>
<th data-quarto-table-cell-role="th">s2</th>
<th data-quarto-table-cell-role="th">s3</th>
<th data-quarto-table-cell-role="th">s4</th>
<th data-quarto-table-cell-role="th">s5</th>
<th data-quarto-table-cell-role="th">s6</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>0.038076</td>
<td>0.050680</td>
<td>0.061696</td>
<td>0.021872</td>
<td>-0.044223</td>
<td>-0.034821</td>
<td>-0.043401</td>
<td>-0.002592</td>
<td>0.019907</td>
<td>-0.017646</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>-0.001882</td>
<td>-0.044642</td>
<td>-0.051474</td>
<td>-0.026328</td>
<td>-0.008449</td>
<td>-0.019163</td>
<td>0.074412</td>
<td>-0.039493</td>
<td>-0.068332</td>
<td>-0.092204</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>0.085299</td>
<td>0.050680</td>
<td>0.044451</td>
<td>-0.005670</td>
<td>-0.045599</td>
<td>-0.034194</td>
<td>-0.032356</td>
<td>-0.002592</td>
<td>0.002861</td>
<td>-0.025930</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>-0.089063</td>
<td>-0.044642</td>
<td>-0.011595</td>
<td>-0.036656</td>
<td>0.012191</td>
<td>0.024991</td>
<td>-0.036038</td>
<td>0.034309</td>
<td>0.022688</td>
<td>-0.009362</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>0.005383</td>
<td>-0.044642</td>
<td>-0.036385</td>
<td>0.021872</td>
<td>0.003935</td>
<td>0.015596</td>
<td>0.008142</td>
<td>-0.002592</td>
<td>-0.031988</td>
<td>-0.046641</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<p>Antes de seguir, vale la pena saber qué mide cada columna — las vas a interpretar más adelante:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Variable</th>
<th>Significado</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>age</code></td>
<td>Edad del paciente</td>
</tr>
<tr class="even">
<td><code>sex</code></td>
<td>Sexo del paciente</td>
</tr>
<tr class="odd">
<td><code>bmi</code></td>
<td>Índice de masa corporal (IMC)</td>
</tr>
<tr class="even">
<td><code>bp</code></td>
<td>Presión arterial media</td>
</tr>
<tr class="odd">
<td><code>s1</code></td>
<td>Colesterol total en sangre (<code>tc</code>)</td>
</tr>
<tr class="even">
<td><code>s2</code></td>
<td>Colesterol LDL, el “colesterol malo” (<code>ldl</code>)</td>
</tr>
<tr class="odd">
<td><code>s3</code></td>
<td>Colesterol HDL, el “colesterol bueno” (<code>hdl</code>)</td>
</tr>
<tr class="even">
<td><code>s4</code></td>
<td>Razón colesterol total / HDL (<code>tch</code>)</td>
</tr>
<tr class="odd">
<td><code>s5</code></td>
<td>Nivel de triglicéridos en sangre, en escala logarítmica (<code>ltg</code>)</td>
</tr>
<tr class="even">
<td><code>s6</code></td>
<td>Nivel de azúcar en sangre (<code>glu</code>)</td>
</tr>
</tbody>
</table>
<p>Y la variable de salida, <code>y</code>, es una medida cuantitativa de qué tan avanzada está la enfermedad un año después de la medición inicial: entre más alto el valor, más ha progresado.</p>
</section>
<section id="regresión-lineal-simple-una-variable-predictora" class="level2">
<h2 class="anchored" data-anchor-id="regresión-lineal-simple-una-variable-predictora">Regresión lineal simple: una variable predictora</h2>
<p>Empieza por el caso más simple posible: predecir <img src="https://latex.codecogs.com/png.latex?y"> usando <strong>una sola</strong> variable predictora, <img src="https://latex.codecogs.com/png.latex?x">. El modelo de regresión lineal simple es una recta:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D%20=%20%5Cbeta_0%20+%20%5Cbeta_1%20x"></p>
<p>Donde:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"> es el valor <strong>predicho</strong> por el modelo, distinto del valor real observado, <img src="https://latex.codecogs.com/png.latex?y">.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> es el <strong>intercepto</strong>: el valor predicho de <img src="https://latex.codecogs.com/png.latex?y"> cuando <img src="https://latex.codecogs.com/png.latex?x%20=%200">. Geométricamente, es el punto donde la recta cruza el eje vertical.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> es la <strong>pendiente</strong>: cuánto cambia <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D"> por cada unidad que aumenta <img src="https://latex.codecogs.com/png.latex?x">. Si <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1%20%3E%200">, la relación es positiva (a más <img src="https://latex.codecogs.com/png.latex?x">, más <img src="https://latex.codecogs.com/png.latex?y">); si <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1%20%3C%200">, es negativa.</li>
</ul>
<section id="cómo-encuentras-esa-recta-y-por-qué-no-basta-con-el-y-mx-b-del-colegio" class="level3">
<h3 class="anchored" data-anchor-id="cómo-encuentras-esa-recta-y-por-qué-no-basta-con-el-y-mx-b-del-colegio">¿Cómo encuentras esa recta? (y por qué no basta con el <img src="https://latex.codecogs.com/png.latex?y%20=%20mx%20+%20b"> del colegio)</h3>
<p>Seguro te acuerdas del colegio: para encontrar la ecuación de una recta <img src="https://latex.codecogs.com/png.latex?y%20=%20mx%20+%20b"> te bastaba con <strong>dos puntos</strong> — resolvías un sistema de dos ecuaciones y dos incógnitas (<img src="https://latex.codecogs.com/png.latex?m"> y <img src="https://latex.codecogs.com/png.latex?b">), y la recta pasaba exactamente por esos dos puntos. Fin del problema.</p>
<p>El problema es que en regresión no tienes dos puntos: tienes diez, cientos o miles. Y esos puntos casi nunca están perfectamente alineados — hay ruido, variabilidad, factores que no mediste. Si intentaras resolver el sistema con <strong>todos</strong> los puntos a la vez, tendrías muchas más ecuaciones (una por cada observación) que incógnitas (solo dos: <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1">). Un sistema así, con más ecuaciones que incógnitas, casi nunca tiene solución exacta: no existe ninguna recta que pase exactamente por todos los puntos al mismo tiempo, a menos que por pura casualidad estén perfectamente alineados.</p>
<p>Entonces, en lugar de buscar una recta que pase exactamente por todos los puntos (imposible, en la práctica), buscas la recta que <strong>se acerque lo más posible a todos ellos, en promedio</strong>. Para eso necesitas dos cosas: una forma de medir “qué tan lejos” queda la recta de cada punto, y un criterio para decidir cuál recta queda “más cerca” en general.</p>
<p>Lo primero es fácil: para cada observación <img src="https://latex.codecogs.com/png.latex?i">, el modelo predice <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D_i">, pero el valor real es <img src="https://latex.codecogs.com/png.latex?y_i">. La diferencia es el <strong>residual</strong>:</p>
<p><img src="https://latex.codecogs.com/png.latex?e_i%20=%20y_i%20-%20%5Chat%7By%7D_i"></p>
<p>Un residual positivo significa que el modelo <strong>subestimó</strong> el valor real; uno negativo, que lo <strong>sobrestimó</strong>.</p>
<p>Lo segundo — el criterio — es lo que le da nombre al método. <strong>Mínimos cuadrados ordinarios</strong> (<em>Ordinary Least Squares</em>, OLS) elige los coeficientes <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> que <strong>minimizan la suma de esos residuales al cuadrado</strong>:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmin_%7B%5Cbeta_0,%20%5Cbeta_1%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20e_i%5E2%20=%20%5Cmin_%7B%5Cbeta_0,%20%5Cbeta_1%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20%5Cleft(y_i%20-%20(%5Cbeta_0%20+%20%5Cbeta_1%20x_i)%5Cright)%5E2"></p>
<p>Esa suma se conoce como <strong>SSE</strong> (<em>sum of squared errors</em>): por cada punto, mides qué tan lejos quedó la recta, elevas esa distancia al cuadrado y sumas todo. Entre más chica sea la suma, mejor se ajusta la recta a los datos — y la “mejor” recta, por definición, es la que hace esa suma lo más pequeña posible.</p>
<p>¿Por qué elevar al cuadrado y no, por ejemplo, sumar los valores absolutos? Dos razones prácticas:</p>
<ul>
<li>Penaliza con más fuerza los errores grandes que los pequeños (un error del doble de tamaño pesa cuatro veces más), y evita que un residual positivo se cancele con uno negativo al sumarlos — si no elevaras al cuadrado, una recta con errores enormes pero balanceados podría dar una suma cercana a cero, y verse “perfecta” sin serlo.</li>
<li>Convierte el problema en uno que tiene una <strong>solución exacta</strong>, calculable con álgebra — no hace falta “probar” rectas una por una.</li>
</ul>
<p>En resumen: la ecuación de la recta del colegio resuelve un problema <em>determinado</em> (misma cantidad de ecuaciones que de incógnitas, con dos puntos exactos). Mínimos cuadrados resuelve un problema <em>sobredeterminado</em> — muchas más ecuaciones que incógnitas — encontrando la mejor aproximación posible en lugar de una solución exacta.</p>
</section>
<section id="la-fórmula-cerrada-la-solución-al-problema-de-minimización" class="level3">
<h3 class="anchored" data-anchor-id="la-fórmula-cerrada-la-solución-al-problema-de-minimización">La fórmula cerrada: la solución al problema de minimización</h3>
<p>Resolver ese problema de minimización (con cálculo: derivando el SSE respecto a <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1">, e igualando a cero) te da una fórmula directa para los coeficientes óptimos — la que probablemente ya conoces de un curso de estadística:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbeta_1%20=%20%5Cfrac%7B%5Csum_%7Bi=1%7D%5E%7Bn%7D%20(x_i%20-%20%5Cbar%7Bx%7D)(y_i%20-%20%5Cbar%7By%7D)%7D%7B%5Csum_%7Bi=1%7D%5E%7Bn%7D%20(x_i%20-%20%5Cbar%7Bx%7D)%5E2%7D,%20%5Cqquad%20%5Cbeta_0%20=%20%5Cbar%7By%7D%20-%20%5Cbeta_1%20%5Cbar%7Bx%7D"></p>
<p>Donde <img src="https://latex.codecogs.com/png.latex?%5Cbar%7Bx%7D"> y <img src="https://latex.codecogs.com/png.latex?%5Cbar%7By%7D"> son los promedios de <img src="https://latex.codecogs.com/png.latex?x"> y de <img src="https://latex.codecogs.com/png.latex?y">. La intuición detrás:</p>
<ul>
<li>El numerador de <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> es, salvo una constante, la <strong>covarianza</strong> entre <img src="https://latex.codecogs.com/png.latex?x"> y <img src="https://latex.codecogs.com/png.latex?y">: mide si ambas variables se mueven juntas.</li>
<li>El denominador es la <strong>varianza</strong> de <img src="https://latex.codecogs.com/png.latex?x">: qué tanto se dispersan los valores de <img src="https://latex.codecogs.com/png.latex?x"> alrededor de su media.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> es, entonces, “cuánto se mueven juntas <img src="https://latex.codecogs.com/png.latex?x"> y <img src="https://latex.codecogs.com/png.latex?y">” dividido entre “cuánto se mueve <img src="https://latex.codecogs.com/png.latex?x"> por sí sola” — la razón de cambio que buscabas.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> garantiza que la recta pase exactamente por el punto <img src="https://latex.codecogs.com/png.latex?(%5Cbar%7Bx%7D,%20%5Cbar%7By%7D)">: el centro de masa de los datos.</li>
</ul>
</section>
<section id="por-qué-no-hay-que-iterar-como-en-otros-modelos-de-machine-learning" class="level3">
<h3 class="anchored" data-anchor-id="por-qué-no-hay-que-iterar-como-en-otros-modelos-de-machine-learning">¿Por qué no hay que iterar, como en otros modelos de machine learning?</h3>
<p>Si ya oíste hablar de <em>descenso de gradiente</em> (<em>gradient descent</em>) en otro contexto, esta pregunta probablemente te ronda: ¿por qué aquí no hay que “ir probando” iterativamente, acercándose poco a poco al mínimo, como sí se hace para entrenar una red neuronal?</p>
<p>La respuesta está en la forma de la función que estás minimizando. El SSE, visto como función de <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1">, es una <strong>parábola</strong> (con una sola variable) o, con más variables, un <strong>paraboloide</strong>: una superficie con forma de tazón, perfectamente suave y convexa, sin mínimos locales falsos ni mesetas raras donde un algoritmo se pueda quedar atascado. Eso te regala dos cosas:</p>
<ul>
<li>Existe un único mínimo global — no hay riesgo de encontrar una solución subóptima “por mala suerte”.</li>
<li>Ese mínimo tiene una ubicación exacta y calculable: es, sencillamente, el punto donde el fondo del tazón es plano, es decir, donde la derivada del SSE respecto a cada <img src="https://latex.codecogs.com/png.latex?%5Cbeta"> vale cero. Resolver ese sistema de ecuaciones (derivadas = 0) es justo lo que te da la fórmula cerrada de arriba — o, en su versión matricial, la ecuación normal que vas a ver más adelante.</li>
</ul>
<p>Otros modelos —redes neuronales, muchos casos de regresión logística con datasets grandes, etc.— tienen funciones de costo mucho más complicadas: no convexas, sin fórmula cerrada disponible, o con una que sería computacionalmente inviable de calcular. Ahí sí hace falta iterar con descenso de gradiente, dando pasos pequeños hacia donde el error disminuye, sin garantía de encontrar siempre el mínimo global. La regresión lineal es uno de los pocos modelos “con suerte”: puedes saltarte todo ese proceso iterativo e ir directo a la respuesta exacta con una fórmula.</p>
<p>Esta fórmula no es una elección arbitraria: es, precisamente, la solución del problema de mínimos cuadrados que acabas de plantear. Aplícala sobre un ejemplo pequeño y tradicional — horas de estudio de 10 estudiantes contra su calificación en un examen — usando solo NumPy, sin ninguna librería de machine learning.</p>
<div id="3ed48e0d" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:34.122551Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:34.122380Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:34.592872Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:34.592127Z&quot;}}" data-execution_count="36">
<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> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ejemplo tradicional: horas de estudio de 10 estudiantes vs. calificación del examen (0-100)</span></span>
<span id="cb3-4">horas_estudio <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;">2</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;">4</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;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</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;">9</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>])</span>
<span id="cb3-5">calificacion <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;">50</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;">58</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">63</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;">70</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">74</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">80</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">84</span>])</span>
<span id="cb3-6"></span>
<span id="cb3-7">x_media <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> horas_estudio.mean()</span>
<span id="cb3-8">y_media <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calificacion.mean()</span>
<span id="cb3-9"></span>
<span id="cb3-10">beta1_manual <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>((horas_estudio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x_media) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (calificacion <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_media)) <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>(</span>
<span id="cb3-11">    (horas_estudio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x_media) <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="cb3-12">)</span>
<span id="cb3-13">beta0_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_media <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> beta1_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x_media</span>
<span id="cb3-14"></span>
<span id="cb3-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"x̄ = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>x_media<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 class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>y_media<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="cb3-16"><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"beta1 (pendiente):  </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>beta1_manual<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="cb3-17"><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"beta0 (intercepto): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>beta0_manual<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="cb3-18"></span>
<span id="cb3-19">x_recta_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(horas_estudio.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>(), horas_estudio.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)</span>
<span id="cb3-20">y_recta_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> beta0_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta1_manual <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x_recta_manual</span>
<span id="cb3-21"></span>
<span id="cb3-22">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<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;">6.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb3-23">ax.scatter(horas_estudio, calificacion, 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>, 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;">60</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;">"Datos (horas vs. calificación)"</span>)</span>
<span id="cb3-24">ax.plot(x_recta_manual, y_recta_manual, 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;">"crimson"</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;">"Recta ajustada a mano"</span>)</span>
<span id="cb3-25">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Horas de estudio"</span>)</span>
<span id="cb3-26">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Calificación del examen"</span>)</span>
<span id="cb3-27">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ejemplo tradicional: mínimos cuadrados calculados a mano"</span>)</span>
<span id="cb3-28">ax.legend()</span>
<span id="cb3-29">ax.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.3</span>)</span>
<span id="cb3-30">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>x̄ = 5.50, ȳ = 67.10
beta1 (pendiente):  3.59
beta0 (intercepto): 47.33</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/estadistica-fundamentos/01-regresion-lineal/index_files/figure-html/cell-3-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>Compruébalo ahora con <code>scikit-learn</code>: ajusta el mismo modelo sobre los mismos datos y confirma que llegas exactamente a los mismos coeficientes por el camino “automático”.</p>
<div id="88714131" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:34.595931Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:34.595648Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:34.688519Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:34.687743Z&quot;}}" data-execution_count="37">
<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="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> LinearRegression</span>
<span id="cb5-2"></span>
<span id="cb5-3">modelo_estudio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression()</span>
<span id="cb5-4">modelo_estudio.fit(horas_estudio.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>), calificacion)</span>
<span id="cb5-5"></span>
<span id="cb5-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;">"Fórmula clásica (a mano):"</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(beta0_manual, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(beta1_manual, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb5-7"><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;">"scikit-learn:            "</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(modelo_estudio.intercept_, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(modelo_estudio.coef_[<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>))</span>
<span id="cb5-8"></span>
<span id="cb5-9">predicho<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>modelo_estudio.coef_[<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="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> modelo_estudio.intercept_ </span>
<span id="cb5-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"Predicción de calificación para 12 horas de estudio: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>predicho<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-stdout">
<pre><code>Fórmula clásica (a mano): 47.33 3.59
scikit-learn:             47.33 3.59
Predicción de calificación para 12 horas de estudio: 90.46</code></pre>
</div>
</div>
</section>
<section id="cómo-funciona-scikit-learn-por-dentro-instanciar-ajustar-predecir" class="level3">
<h3 class="anchored" data-anchor-id="cómo-funciona-scikit-learn-por-dentro-instanciar-ajustar-predecir">Cómo funciona <code>scikit-learn</code> por dentro: instanciar, ajustar, predecir</h3>
<p>Detente un momento en ese código, porque el mismo patrón de tres pasos se repite en <strong>todos</strong> los modelos de <code>scikit-learn</code> que vas a usar en el curso — regresión, regularización, clasificación, lo que sea:</p>
<ol type="1">
<li><strong>Instanciar el modelo</strong>: <code>LinearRegression()</code> crea un objeto “vacío”, que todavía no ha visto ningún dato. En este punto no tiene coeficientes ni sabe nada — solo declara qué tipo de modelo vas a usar (y, si aplica, sus hiperparámetros, como en <code>Ridge(alpha=1.0)</code>).</li>
<li><strong>Ajustar, con <code>.fit(X, y)</code></strong>: aquí ocurre el aprendizaje. <code>scikit-learn</code> recibe la matriz de variables predictoras <code>X</code> y el vector objetivo <code>y</code>, resuelve por dentro el mismo problema de mínimos cuadrados que viste a mano, y <strong>guarda el resultado como atributos del objeto</strong>: <code>modelo_estudio.intercept_</code> y <code>modelo_estudio.coef_</code>. El guion bajo al final (<code>intercept_</code>, <code>coef_</code>) es una convención de <code>scikit-learn</code>: marca que ese atributo se calculó durante el <code>.fit()</code>, no que lo definiste tú.</li>
<li><strong>Predecir, con <code>.predict(X_nuevo)</code></strong>: una vez ajustado, el objeto ya “conoce” <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1">, así que puede darte predicciones para datos nuevos sin volver a calcular nada — solo evalúa el modelo con los coeficientes que ya aprendió.</li>
</ol>
<p>Este patrón — <strong>instanciar → ajustar → predecir</strong> — es la razón por la que más adelante vas a poder cambiar <code>LinearRegression</code> por <code>Ridge</code>, <code>Lasso</code> o casi cualquier otro modelo del curso modificando una sola línea: todos comparten la misma interfaz.</p>
<p>Un detalle sobre <code>horas_estudio.reshape(-1, 1)</code>: <code>scikit-learn</code> siempre espera que <code>X</code> sea una <strong>matriz 2D</strong> (filas = observaciones, columnas = variables), incluso cuando solo tienes una variable predictora — por eso conviertes el vector de 10 valores en una matriz de 10 filas y 1 columna. <code>y</code>, en cambio, sí puede pasarse como un vector 1D.</p>
<p>Como esperabas, ambos caminos llegaron exactamente al mismo resultado — la fórmula de covarianza/varianza no es más que lo que <code>scikit-learn</code> calcula por dentro cuando llamas a <code>.fit()</code>.</p>
<p>Pero, ¿cómo sabes que esa fórmula realmente te da la recta con el SSE más bajo posible, y no solo <em>una</em> recta razonable? Compruébalo con números concretos: calcula el SSE que produce la recta ajustada, y compáralo con el de un par de rectas alternativas elegidas de forma arbitraria (un poco más inclinada, un poco más alta). Si la fórmula es correcta, ninguna alternativa debería producir un SSE menor.</p>
<div id="8ed662c9" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:34.690804Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:34.690465Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:34.697748Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:34.697005Z&quot;}}" data-execution_count="38">
<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="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sse(beta0, beta1, x, y):</span>
<span id="cb7-2">    y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> beta0 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x</span>
<span id="cb7-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>((y <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="cb7-4"></span>
<span id="cb7-5">sse_ols <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sse(beta0_manual, beta1_manual, horas_estudio, calificacion)</span>
<span id="cb7-6">sse_alt1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sse(beta0_manual, beta1_manual <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;">1.0</span>, horas_estudio, calificacion)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># pendiente algo mayor</span></span>
<span id="cb7-7">sse_alt2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sse(beta0_manual <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;">3.0</span>, beta1_manual, horas_estudio, calificacion)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># intercepto desplazado</span></span>
<span id="cb7-8"></span>
<span id="cb7-9"><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"SSE con la recta de mínimos cuadrados:       </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sse_ols<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="cb7-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"SSE con pendiente +1 (recta alternativa 1):  </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sse_alt1<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="cb7-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"SSE con intercepto -3 (recta alternativa 2): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sse_alt2<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></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>SSE con la recta de mínimos cuadrados:       9.3
SSE con pendiente +1 (recta alternativa 1):  394.3
SSE con intercepto -3 (recta alternativa 2): 99.3</code></pre>
</div>
</div>
<p>Como esperabas, la recta de mínimos cuadrados tiene el SSE más bajo de las tres — ninguna de las alternativas mejora el ajuste, por más que muevas un poco la pendiente o el intercepto. Esa es, en la práctica, la garantía detrás de la fórmula: no existe otra recta con menor suma de errores al cuadrado sobre estos datos.</p>
<p>La diferencia real entre calcular a mano y usar <code>scikit-learn</code> aparece con la <strong>escala</strong>: con una variable y diez observaciones, la fórmula a mano es perfectamente manejable; con cientos de observaciones prefieres que la librería haga el cálculo por ti, de forma más rápida y numéricamente estable.</p>
<p>Un detalle importante que vas a necesitar para interpretar los coeficientes en el dataset real: <code>scikit-learn</code> entrega el dataset diabetes con las 10 variables <strong>ya centradas en media cero y reescaladas</strong>. Es decir, un valor de <code>bmi</code> de <code>0.05</code> no es un IMC de 0.05 — es una versión estandarizada del IMC real del paciente. Ten esto presente en la interpretación.</p>
<p>Ahora aplica lo mismo sobre datos clínicos reales, usando <code>bmi</code> como variable predictora y <code>LinearRegression</code> de <code>scikit-learn</code>.</p>
<div id="62e0a09d" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:34.699935Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:34.699739Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:34.841643Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:34.840992Z&quot;}}" data-execution_count="39">
<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="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-2"><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> LinearRegression</span>
<span id="cb9-3"></span>
<span id="cb9-4">x_bmi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X_completo[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bmi"</span>]]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># scikit-learn espera una matriz 2D, no un vector</span></span>
<span id="cb9-5"></span>
<span id="cb9-6">modelo_simple <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression()</span>
<span id="cb9-7">modelo_simple.fit(x_bmi, y)</span>
<span id="cb9-8"></span>
<span id="cb9-9">beta0 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_simple.intercept_</span>
<span id="cb9-10">beta1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_simple.coef_[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb9-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"Intercepto (beta0): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>beta0<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="cb9-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"Pendiente  (beta1): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>beta1<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="cb9-13"></span>
<span id="cb9-14">x_recta <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(x_bmi[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bmi"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>(), x_bmi[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bmi"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)</span>
<span id="cb9-15">y_recta <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> beta0 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x_recta</span>
<span id="cb9-16"></span>
<span id="cb9-17">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb9-18">ax.scatter(x_bmi, y, 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>, 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;">"Pacientes (datos reales)"</span>)</span>
<span id="cb9-19">ax.plot(x_recta, y_recta, 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;">"crimson"</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;">"Recta ajustada"</span>)</span>
<span id="cb9-20">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IMC estandarizado (bmi)"</span>)</span>
<span id="cb9-21">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Progresión de la enfermedad"</span>)</span>
<span id="cb9-22">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Regresión lineal simple: progresión de la enfermedad vs. IMC"</span>)</span>
<span id="cb9-23">ax.legend()</span>
<span id="cb9-24">ax.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.3</span>)</span>
<span id="cb9-25">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Intercepto (beta0): 152.13
Pendiente  (beta1): 949.44</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/estadistica-fundamentos/01-regresion-lineal/index_files/figure-html/cell-6-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>Ya comprobaste con números que la fórmula minimiza el error. Ahora hazlo visual: dibuja los residuales como líneas verticales entre cada punto y la recta ajustada, esta vez sobre los datos reales de <code>bmi</code> y el modelo que ajustaste con <code>scikit-learn</code>.</p>
<div id="250281fe" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:34.843493Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:34.843274Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.012357Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.011467Z&quot;}}" data-execution_count="40">
<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">y_pred_bmi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_simple.predict(x_bmi)</span>
<span id="cb11-2">residuales_bmi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_pred_bmi</span>
<span id="cb11-3"></span>
<span id="cb11-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Para que la gráfica sea legible, dibuja los residuales solo de una muestra de pacientes</span></span>
<span id="cb11-5">rng <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.default_rng(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb11-6">idx_muestra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.choice(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(y), size<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;">60</span>, replace<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="cb11-7"></span>
<span id="cb11-8">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb11-9">ax.scatter(x_bmi, y, 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>, 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;">"Pacientes (datos reales)"</span>)</span>
<span id="cb11-10">ax.plot(x_recta, y_recta, 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;">"crimson"</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;">"Recta ajustada"</span>)</span>
<span id="cb11-11"><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> idx_muestra:</span>
<span id="cb11-12">    xi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x_bmi[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bmi"</span>].iloc[i]</span>
<span id="cb11-13">    ax.plot([xi, xi], [y.iloc[i], y_pred_bmi[i]], 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>, 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>, 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="cb11-14">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IMC estandarizado (bmi)"</span>)</span>
<span id="cb11-15">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Progresión de la enfermedad"</span>)</span>
<span id="cb11-16">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Residuales: distancia vertical entre cada punto y la recta"</span>)</span>
<span id="cb11-17">ax.legend()</span>
<span id="cb11-18">ax.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.3</span>)</span>
<span id="cb11-19">plt.show()</span>
<span id="cb11-20"></span>
<span id="cb11-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"Suma de residuales al cuadrado (SSE): </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(residuales_bmi <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="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,.0f}</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/estadistica-fundamentos/01-regresion-lineal/index_files/figure-html/cell-7-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Suma de residuales al cuadrado (SSE): 1,719,582</code></pre>
</div>
</div>
</section>
</section>
<section id="interpretación-de-los-coeficientes" class="level2">
<h2 class="anchored" data-anchor-id="interpretación-de-los-coeficientes">Interpretación de los coeficientes</h2>
<p>Ya tienes el modelo ajustado, pero un modelo solo es útil si sabes leer lo que dice. Fíjate en los valores de <code>beta0</code> y <code>beta1</code> que imprimiste arriba (<img src="https://latex.codecogs.com/png.latex?%5Cbeta_0%20%5Capprox%20152">, <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1%20%5Capprox%20949">):</p>
<ul>
<li><strong>El intercepto (<img src="https://latex.codecogs.com/png.latex?%5Cbeta_0%20%5Capprox%20152">)</strong> es la progresión de la enfermedad que predice el modelo cuando <code>bmi</code> vale 0, es decir, para un paciente con un IMC exactamente igual al promedio de la muestra (recuerda: la variable está centrada en cero). No lo interpretes como “IMC igual a cero” en el sentido literal — nadie tiene un IMC de cero — sino como “un paciente con IMC promedio”.</li>
<li><strong>La pendiente (<img src="https://latex.codecogs.com/png.latex?%5Cbeta_1%20%5Capprox%20949">)</strong> te dice cuánto sube, en promedio, el índice de progresión de la enfermedad por cada unidad que aumenta <code>bmi</code>. Ojo con un detalle fácil de asumir mal: <code>scikit-learn</code> no reescaló esta variable a la estandarización habitual (media 0, varianza 1). La centró en media cero y luego dividió cada columna para que la <strong>suma de cuadrados diera exactamente 1</strong> (norma L2 unitaria) — un detalle propio de cómo empaquetaron este dataset en particular. La desviación estándar real de esta <code>bmi</code> reescalada es de apenas ≈0.048, no 1 — así que “una unidad” no es un punto de IMC real, y tampoco es una desviación estándar: es sencillamente la unidad de esa escala normalizada específica, sin una lectura clínica directa. Lo que sí puedes interpretar sin ambigüedad, más allá de esa escala arbitraria, es el <strong>signo y la magnitud relativa</strong>: la pendiente sale claramente positiva y grande, lo que confirma la intuición clínica de que un IMC más alto se asocia con una progresión más rápida de la enfermedad.</li>
</ul>
<p>Este es un punto que te va a servir en cualquier dataset que uses de aquí en adelante: <strong>antes de interpretar un coeficiente, revisa en qué unidades está la variable</strong> — y no asumas que “estandarizado” siempre significa lo mismo. Un mismo coeficiente significa cosas muy distintas si <img src="https://latex.codecogs.com/png.latex?x"> está en las unidades originales o si fue reescalada, y de qué forma.</p>
</section>
<section id="interpretación-de-los-errores-residuales" class="level2">
<h2 class="anchored" data-anchor-id="interpretación-de-los-errores-residuales">Interpretación de los errores (residuales)</h2>
<p>Ya interpretaste qué dicen los coeficientes. La otra mitad de la historia son los residuales — la diferencia entre lo que predijo el modelo y lo que pasó en realidad, <img src="https://latex.codecogs.com/png.latex?e_i%20=%20y_i%20-%20%5Chat%7By%7D_i"> — que ya usaste antes para comprobar que la recta minimiza el SSE. Pero los residuales no solo sirven para verificar la fórmula: también te dicen si el modelo está capturando bien la relación entre <code>bmi</code> y la progresión de la enfermedad, o si se le está escapando algo.</p>
<p>La forma más rápida de leerlos es graficar cada residual contra el valor predicho <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D_i">. Buscas que los puntos formen una nube sin forma clara, repartida al azar alrededor de la línea horizontal en cero:</p>
<ul>
<li>Si ves una <strong>curva</strong> en vez de una nube sin forma, es señal de que la relación real no es lineal — el modelo se está dejando algo sin capturar.</li>
<li>Si el <strong>ancho de la nube cambia</strong> de forma clara a medida que te mueves de izquierda a derecha (por ejemplo, se abre como un abanico), es señal de heterocedasticidad: el error no es igual de grande en todo el rango de predicciones.</li>
<li>Si la nube se ve pareja y sin patrón visible, es una señal razonable de que el modelo no está violando el supuesto de linealidad de forma obvia — aunque un diagnóstico riguroso (normalidad de los residuales, multicolinealidad entre varias variables, etc.) necesita más que una inspección visual, algo que vas a ver a fondo en el notebook de análisis multivariado.</li>
</ul>
<div id="c7660639" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.014463Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.014037Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.096014Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.094679Z&quot;}}" data-execution_count="41">
<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">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb13-2">ax.scatter(y_pred_bmi, residuales_bmi, 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="cb13-3">ax.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;">"crimson"</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="cb13-4">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Valor predicho (ŷ)"</span>)</span>
<span id="cb13-5">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Residual (y - ŷ)"</span>)</span>
<span id="cb13-6">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Residuales vs. valores predichos: modelo simple con bmi"</span>)</span>
<span id="cb13-7">ax.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.3</span>)</span>
<span id="cb13-8">plt.show()</span>
<span id="cb13-9"></span>
<span id="cb13-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"R² del modelo: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>modelo_simple<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score(x_bmi, y)<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="cb13-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"Desviación estándar de los residuales: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>residuales_bmi<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>std()<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/estadistica-fundamentos/01-regresion-lineal/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>R² del modelo: 0.344
Desviación estándar de los residuales: 62.44</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura de los residuales del modelo simple</strong></p>
<ul>
<li>La nube no muestra una curva evidente ni se abre claramente de un lado a otro — el ancho se mantiene bastante parejo a lo largo del rango de predicciones. Es una señal razonable de que el modelo lineal no está violando el supuesto de linealidad de forma obvia.</li>
<li>Lo que sí salta a la vista es la dispersión: los residuales se mueven en un rango amplio (desviación estándar de más de 60 unidades) y el R² apenas llega a 0.34.</li>
<li>Eso no es un problema del ajuste — la recta sí es la que minimiza el SSE — sino una limitación de usar una sola variable: bmi por sí solo deja bastante variabilidad de la progresión de la enfermedad sin explicar.</li>
<li>Esa es precisamente la brecha que se cierra al combinar varias variables predictoras en un modelo de regresión múltiple, como vas a ver en el notebook de análisis multivariado del módulo.</li>
</ul>
</div>
</section>
<section id="otro-ejemplo-predecir-el-valor-de-una-vivienda" class="level2">
<h2 class="anchored" data-anchor-id="otro-ejemplo-predecir-el-valor-de-una-vivienda">Otro ejemplo: predecir el valor de una vivienda</h2>
<p>Para que la idea no se quede pegada a un solo dataset, repítela con un problema clásico y puramente explicativo: predecir el <strong>precio de una vivienda</strong> a partir de su <strong>tamaño</strong>. No necesitas un dataset real para esto — con unos pocos puntos sintéticos alcanza para ver el patrón con claridad.</p>
<p>Aplica exactamente el mismo procedimiento que ya conoces: calcula <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> con la fórmula clásica y, por separado, con <code>LinearRegression</code>, para comprobar otra vez que ambos caminos llegan al mismo resultado.</p>
<div id="1b8ea476" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.099204Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.098949Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.208356Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.207630Z&quot;}}" data-execution_count="42">
<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> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb15-3"><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> LinearRegression</span>
<span id="cb15-4"></span>
<span id="cb15-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Datos sintéticos, solo para ilustrar: tamaño (m²) y precio de venta (miles de USD) de 10 casas</span></span>
<span id="cb15-6">tamano_m2 <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;">50</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</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;">80</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;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">110</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">130</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">140</span>])</span>
<span id="cb15-7">precio <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;">120</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;">150</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">165</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">180</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">195</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">208</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">225</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">242</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">258</span>])</span>
<span id="cb15-8"></span>
<span id="cb15-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Camino 1: fórmula clásica, a mano</span></span>
<span id="cb15-10">x_media_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tamano_m2.mean()</span>
<span id="cb15-11">y_media_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> precio.mean()</span>
<span id="cb15-12">beta1_h <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>((tamano_m2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x_media_h) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (precio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> y_media_h)) <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>(</span>
<span id="cb15-13">    (tamano_m2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x_media_h) <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="cb15-14">)</span>
<span id="cb15-15">beta0_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_media_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> beta1_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x_media_h</span>
<span id="cb15-16"></span>
<span id="cb15-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Camino 2: scikit-learn</span></span>
<span id="cb15-18">modelo_vivienda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression()</span>
<span id="cb15-19">modelo_vivienda.fit(tamano_m2.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>), precio)</span>
<span id="cb15-20"></span>
<span id="cb15-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;">"Fórmula clásica (a mano):"</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(beta0_h, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(beta1_h, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb15-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;">"scikit-learn:            "</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(modelo_vivienda.intercept_, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(modelo_vivienda.coef_[<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>))</span>
<span id="cb15-23"></span>
<span id="cb15-24">x_recta_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(tamano_m2.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>(), tamano_m2.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)</span>
<span id="cb15-25">y_recta_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> beta0_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> beta1_h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x_recta_h</span>
<span id="cb15-26"></span>
<span id="cb15-27">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<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;">6.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb15-28">ax.scatter(tamano_m2, precio, 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>, 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;">60</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;">"Casas (datos sintéticos)"</span>)</span>
<span id="cb15-29">ax.plot(x_recta_h, y_recta_h, 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;">"crimson"</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;">"Recta ajustada"</span>)</span>
<span id="cb15-30">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tamaño de la vivienda (m²)"</span>)</span>
<span id="cb15-31">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Precio de venta (miles de USD)"</span>)</span>
<span id="cb15-32">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ejemplo explicativo: precio de una vivienda según su tamaño"</span>)</span>
<span id="cb15-33">ax.legend()</span>
<span id="cb15-34">ax.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.3</span>)</span>
<span id="cb15-35">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Fórmula clásica (a mano): 44.79 1.51
scikit-learn:             44.79 1.51</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/estadistica-fundamentos/01-regresion-lineal/index_files/figure-html/cell-9-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<p>La pendiente confirma la intuición: a mayor tamaño, mayor precio esperado. Ya tienes un modelo ajustado — ahora la pregunta natural es: <strong>¿cómo lo usas para predecir un caso nuevo</strong>, uno que no está en los datos?</p>
<p>Con la recta ya ajustada, predecir es tan simple como evaluarla en el nuevo valor de <img src="https://latex.codecogs.com/png.latex?x">. Fíjate en un detalle práctico: <code>scikit-learn</code> espera que le pases una <strong>matriz 2D</strong> para predecir, incluso si es un único valor y una sola variable — por eso <code>[[105.0]]</code> y no simplemente <code>105.0</code>. Es la misma forma que tenía <code>tamano_m2.reshape(-1, 1)</code> cuando ajustaste el modelo.</p>
<div id="62008833" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.210098Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.209942Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.214610Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.213926Z&quot;}}" data-execution_count="43">
<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;"># ¿Cuánto costaría, según el modelo, una casa de 105 m²?</span></span>
<span id="cb17-2">tamano_nuevo <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;">105.0</span>]])</span>
<span id="cb17-3">precio_predicho <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_vivienda.predict(tamano_nuevo)</span>
<span id="cb17-4"></span>
<span id="cb17-5"><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"Precio predicho para 105 m²: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>precio_predicho[<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;">:.1f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> mil USD"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Precio predicho para 105 m²: 203.2 mil USD</code></pre>
</div>
</div>
</section>
<section id="forma-matricial-haty-xbeta" class="level2">
<h2 class="anchored" data-anchor-id="forma-matricial-haty-xbeta">Forma matricial: <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D%20=%20X%5Cbeta"></h2>
<p>Vuelve ahora al dataset diabetes. Hasta ahora escribiste el modelo variable por variable: <img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D%20=%20%5Cbeta_0%20+%20%5Cbeta_1%20x">. Esa notación funciona bien con una sola variable, pero se vuelve incómoda apenas tienes varias — y el dataset diabetes tiene 10. La solución, como recordarás del repaso de NumPy, es usar álgebra lineal: agrupar todas las observaciones y todos los coeficientes en matrices y expresar el modelo completo como un único producto matricial.</p>
<p>Define la <strong>matriz de diseño</strong> <img src="https://latex.codecogs.com/png.latex?X"> agregando una columna de unos al inicio (para que multiplique al intercepto <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0">) y luego una columna por cada variable predictora:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AX%20=%20%5Cbegin%7Bpmatrix%7D%0A1%20&amp;%20x_%7B11%7D%20&amp;%20x_%7B12%7D%20&amp;%20%5Cdots%20&amp;%20x_%7B1p%7D%20%5C%5C%0A1%20&amp;%20x_%7B21%7D%20&amp;%20x_%7B22%7D%20&amp;%20%5Cdots%20&amp;%20x_%7B2p%7D%20%5C%5C%0A%5Cvdots%20&amp;%20%5Cvdots%20&amp;%20%5Cvdots%20&amp;%20%5Cddots%20&amp;%20%5Cvdots%20%5C%5C%0A1%20&amp;%20x_%7Bn1%7D%20&amp;%20x_%7Bn2%7D%20&amp;%20%5Cdots%20&amp;%20x_%7Bnp%7D%0A%5Cend%7Bpmatrix%7D,%20%5Cqquad%0A%5Cbeta%20=%20%5Cbegin%7Bpmatrix%7D%20%5Cbeta_0%20%5C%5C%20%5Cbeta_1%20%5C%5C%20%5Cvdots%20%5C%5C%20%5Cbeta_p%20%5Cend%7Bpmatrix%7D%0A"></p>
<p>Con esto, las predicciones de <strong>todas</strong> las observaciones a la vez se calculan con un solo producto matricial:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D%20=%20X%5Cbeta"></p>
<p>Y el problema de mínimos cuadrados que planteaste antes tiene una solución exacta, cerrada, conocida como la <strong>ecuación normal</strong>:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbeta%20=%20(X%5E%5Ctop%20X)%5E%7B-1%7D%20X%5E%5Ctop%20y"></p>
<p><code>scikit-learn</code> no resuelve exactamente así por dentro (usa métodos numéricamente más estables), pero el resultado es equivalente.</p>
<p>Antes de aplicarlo sobre datos reales, hazlo tangible con un ejemplo pequeño que ya conoces bien: horas de estudio contra calificación. Con <img src="https://latex.codecogs.com/png.latex?n=10"> observaciones y <img src="https://latex.codecogs.com/png.latex?p=1"> variable, la matriz <img src="https://latex.codecogs.com/png.latex?X"> tiene 10 filas y 2 columnas (la columna de unos, más <code>horas_estudio</code>) — lo suficientemente chica para imprimirla completa y verla “a mano”.</p>
<p>Con los 10 pares (horas, calificación) del ejemplo, la matriz de diseño <img src="https://latex.codecogs.com/png.latex?X_%7Bestudio%7D"> (columna de unos + columna de horas) y el vector <img src="https://latex.codecogs.com/png.latex?y_%7Bestudio%7D"> (las calificaciones) quedan así:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AX_%7Bestudio%7D%20=%20%5Cbegin%7Bpmatrix%7D%0A1%20&amp;%201%20%5C%5C%201%20&amp;%202%20%5C%5C%201%20&amp;%203%20%5C%5C%201%20&amp;%204%20%5C%5C%201%20&amp;%205%20%5C%5C%201%20&amp;%206%20%5C%5C%201%20&amp;%207%20%5C%5C%201%20&amp;%208%20%5C%5C%201%20&amp;%209%20%5C%5C%201%20&amp;%2010%0A%5Cend%7Bpmatrix%7D,%20%5Cqquad%0Ay_%7Bestudio%7D%20=%20%5Cbegin%7Bpmatrix%7D%2050%20%5C%5C%2055%20%5C%5C%2058%20%5C%5C%2063%20%5C%5C%2065%20%5C%5C%2070%20%5C%5C%2072%20%5C%5C%2074%20%5C%5C%2080%20%5C%5C%2084%20%5Cend%7Bpmatrix%7D%0A"></p>
<p>Cada fila de <img src="https://latex.codecogs.com/png.latex?X_%7Bestudio%7D"> es un estudiante: un 1 (para el intercepto) y sus horas de estudio. Aplica la ecuación normal, <img src="https://latex.codecogs.com/png.latex?%5Cbeta%20=%20(X%5E%5Ctop%20X)%5E%7B-1%7D%20X%5E%5Ctop%20y">, sobre estas matrices exactas y compara el resultado con <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> que ya calculaste antes.</p>
<div id="a89da674" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.216863Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.216693Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.221356Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.220618Z&quot;}}" data-execution_count="44">
<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;"># Matriz de diseño X para el ejemplo de horas de estudio: columna de 1s + columna de horas</span></span>
<span id="cb19-2">n_estudio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> horas_estudio.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb19-3">X_estudio <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.hstack([np.ones((n_estudio, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)), horas_estudio.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="cb19-4"></span>
<span id="cb19-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;">"Matriz de diseño X (10 filas: columna de 1s | horas de estudio):"</span>)</span>
<span id="cb19-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(X_estudio)</span>
<span id="cb19-7"></span>
<span id="cb19-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ecuación normal: beta = (X^T X)^-1 X^T y</span></span>
<span id="cb19-9">beta_estudio_matricial <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linalg.inv(X_estudio.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_estudio) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_estudio.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> calificacion</span>
<span id="cb19-10"></span>
<span id="cb19-11"><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;">Coeficientes con la ecuación normal:      "</span>, beta_estudio_matricial)</span>
<span id="cb19-12"><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;">"Coeficientes con la fórmula de covarianza:"</span>, [beta0_manual, beta1_manual])</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Matriz de diseño X (10 filas: columna de 1s | horas de estudio):
[[ 1.  1.]
 [ 1.  2.]
 [ 1.  3.]
 [ 1.  4.]
 [ 1.  5.]
 [ 1.  6.]
 [ 1.  7.]
 [ 1.  8.]
 [ 1.  9.]
 [ 1. 10.]]

Coeficientes con la ecuación normal:       [47.33333333  3.59393939]
Coeficientes con la fórmula de covarianza: [np.float64(47.33333333333333), np.float64(3.5939393939393938)]</code></pre>
</div>
</div>
<p>Los coeficientes coinciden exactamente con los que calculaste con la fórmula de covarianza/varianza — tiene que ser así, porque son dos caminos algebraicos distintos para llegar a la misma solución del mismo problema de mínimos cuadrados.</p>
<p>Repite el mismo ejercicio con el otro ejemplo pequeño que ya conoces: el precio de las casas según su tamaño.</p>
<p>Con las 10 casas del ejemplo, la matriz de diseño <img src="https://latex.codecogs.com/png.latex?X_%7Bvivienda%7D"> (columna de unos + columna de tamaño en m²) y el vector <img src="https://latex.codecogs.com/png.latex?y_%7Bvivienda%7D"> (los precios) quedan así:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0AX_%7Bvivienda%7D%20=%20%5Cbegin%7Bpmatrix%7D%0A1%20&amp;%2050%20%5C%5C%201%20&amp;%2060%20%5C%5C%201%20&amp;%2070%20%5C%5C%201%20&amp;%2080%20%5C%5C%201%20&amp;%2090%20%5C%5C%201%20&amp;%20100%20%5C%5C%201%20&amp;%20110%20%5C%5C%201%20&amp;%20120%20%5C%5C%201%20&amp;%20130%20%5C%5C%201%20&amp;%20140%0A%5Cend%7Bpmatrix%7D,%20%5Cqquad%0Ay_%7Bvivienda%7D%20=%20%5Cbegin%7Bpmatrix%7D%20120%20%5C%5C%20138%20%5C%5C%20150%20%5C%5C%20165%20%5C%5C%20180%20%5C%5C%20195%20%5C%5C%20208%20%5C%5C%20225%20%5C%5C%20242%20%5C%5C%20258%20%5Cend%7Bpmatrix%7D%0A"></p>
<p>Mismo patrón: cada fila es una casa, con un 1 para el intercepto y su tamaño en la segunda columna. Aplica <img src="https://latex.codecogs.com/png.latex?%5Cbeta%20=%20(X%5E%5Ctop%20X)%5E%7B-1%7D%20X%5E%5Ctop%20y"> sobre estas matrices y compara con <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0"> y <img src="https://latex.codecogs.com/png.latex?%5Cbeta_1"> que ya calculaste antes.</p>
<div id="940d408e" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.223483Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.223297Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.227104Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.226490Z&quot;}}" data-execution_count="45">
<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;"># Matriz de diseño X para el ejemplo de las casas: columna de 1s + columna de tamaño (m²)</span></span>
<span id="cb21-2">n_vivienda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tamano_m2.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb21-3">X_vivienda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.hstack([np.ones((n_vivienda, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)), tamano_m2.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="cb21-4"></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;">"Matriz de diseño X (10 filas: columna de 1s | tamaño en m²):"</span>)</span>
<span id="cb21-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(X_vivienda)</span>
<span id="cb21-7"></span>
<span id="cb21-8">beta_vivienda_matricial <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linalg.inv(X_vivienda.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_vivienda) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_vivienda.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> precio</span>
<span id="cb21-9"></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;">"</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;">Coeficientes con la ecuación normal:      "</span>, beta_vivienda_matricial)</span>
<span id="cb21-11"><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;">"Coeficientes con la fórmula de covarianza:"</span>, [beta0_h, beta1_h])</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Matriz de diseño X (10 filas: columna de 1s | tamaño en m²):
[[  1.  50.]
 [  1.  60.]
 [  1.  70.]
 [  1.  80.]
 [  1.  90.]
 [  1. 100.]
 [  1. 110.]
 [  1. 120.]
 [  1. 130.]
 [  1. 140.]]

Coeficientes con la ecuación normal:       [44.79393939  1.50848485]
Coeficientes con la fórmula de covarianza: [np.float64(44.79393939393938), np.float64(1.5084848484848485)]</code></pre>
</div>
</div>
<p>Otra vez, coincide exactamente. Ya viste con dos ejemplos distintos que la forma matricial reproduce, número por número, lo mismo que la fórmula “tradicional” — la diferencia es que la matricial escala sin esfuerzo a cualquier cantidad de variables. Ahora aplícala sobre datos reales: reconstruye el modelo simple de <code>bmi</code> con NumPy puro, usando la ecuación normal, y verifica que obtienes los mismos coeficientes que te dio <code>LinearRegression</code>.</p>
<div id="1f8c0076" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.228817Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.228600Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.233336Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.232706Z&quot;}}" data-execution_count="46">
<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">n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x_bmi.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb23-2">columna_unos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.ones((n, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb23-3">X_matriz <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.hstack([columna_unos, x_bmi.to_numpy()])  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># columna de 1s + columna de bmi</span></span>
<span id="cb23-4"></span>
<span id="cb23-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ecuación normal: beta = (X^T X)^-1 X^T y</span></span>
<span id="cb23-6">beta_matricial <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linalg.inv(X_matriz.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_matriz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> X_matriz.T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> y.to_numpy()</span>
<span id="cb23-7"></span>
<span id="cb23-8"><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;">"Coeficientes con la ecuación normal (NumPy):"</span>, beta_matricial)</span>
<span id="cb23-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;">"Coeficientes con scikit-learn:              "</span>, [beta0, beta1])</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Coeficientes con la ecuación normal (NumPy): [152.13348416 949.43526038]
Coeficientes con scikit-learn:               [np.float64(152.13348416289617), np.float64(949.4352603840387)]</code></pre>
</div>
</div>
</section>
<section id="ejercicios-consolida-la-regresión-simple" class="level2">
<h2 class="anchored" data-anchor-id="ejercicios-consolida-la-regresión-simple">Ejercicios: consolida la regresión simple</h2>
<p>Ya tienes todas las piezas: la fórmula clásica, <code>scikit-learn</code>, la forma matricial y la ecuación normal. Antes de pasar a modelos con más de una variable predictora — el tema del notebook de análisis multivariado del módulo — vale la pena practicar el mismo patrón unas cuantas veces más: con otra variable, con casos nuevos, comparando variables entre sí, repitiendo el álgebra matricial y poniendo a prueba qué tan frágil es una recta ajustada con pocos datos. Los cinco ejercicios que siguen usan exactamente las herramientas que ya construiste arriba.</p>
<section id="ejercicio-1-repite-el-patrón-con-otra-variable-bp" class="level3">
<h3 class="anchored" data-anchor-id="ejercicio-1-repite-el-patrón-con-otra-variable-bp">Ejercicio 1 — Repite el patrón con otra variable: <code>bp</code></h3>
<p>Hasta ahora trabajaste la regresión simple sobre <code>bmi</code>. Repite exactamente el mismo procedimiento — fórmula manual, <code>LinearRegression</code> y gráfica de la recta ajustada — pero esta vez con <code>bp</code> (presión arterial media) como única variable predictora. La idea es que el patrón quede automatizado en tu cabeza, no memorizado para una sola variable.</p>
<div id="e80e83e8" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.235142Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.234961Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.237857Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.237304Z&quot;}}" data-execution_count="47">
<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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tu código aquí. Guía de pasos:</span></span>
<span id="cb25-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Extrae "bp" de X_completo como matriz 2D: x_bp = X_completo[["bp"]]</span></span>
<span id="cb25-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Calcula beta0 y beta1 a mano con la fórmula de covarianza/varianza (igual que hiciste con bmi)</span></span>
<span id="cb25-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Ajusta un LinearRegression sobre x_bp y compara sus coeficientes con los del paso 2</span></span>
<span id="cb25-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Grafica los puntos (x_bp, y) junto con la recta ajustada, con matplotlib</span></span></code></pre></div></div>
</div>
</section>
<section id="ejercicio-2-predicciones-sobre-tres-pacientes-hipotéticos" class="level3">
<h3 class="anchored" data-anchor-id="ejercicio-2-predicciones-sobre-tres-pacientes-hipotéticos">Ejercicio 2 — Predicciones sobre tres pacientes hipotéticos</h3>
<p>Usa el modelo simple que ya ajustaste con <code>bmi</code> (<code>modelo_simple</code>) para predecir la progresión de la enfermedad en tres pacientes hipotéticos: uno con IMC bajo, uno con IMC medio y uno con IMC alto. En lugar de inventar valores al azar, toma los percentiles 10, 50 y 90 de la columna <code>bmi</code> real, para que los tres casos sean plausibles dentro del rango observado.</p>
<div id="f1e69cc9" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.239707Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.239495Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.242056Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.241438Z&quot;}}" data-execution_count="48">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb26-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tu código aquí. Guía de pasos:</span></span>
<span id="cb26-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Calcula los percentiles 10, 50 y 90 de x_bmi["bmi"] con np.percentile</span></span>
<span id="cb26-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Arma una tabla (por ejemplo, un pd.DataFrame) con esos tres valores de bmi, uno por paciente</span></span>
<span id="cb26-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Usa modelo_simple.predict(...) sobre esa tabla para obtener la progresión predicha de cada paciente</span></span>
<span id="cb26-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Imprime los tres resultados junto con el valor de bmi que los generó</span></span></code></pre></div></div>
</div>
</section>
<section id="ejercicio-3-qué-variable-explica-mejor-la-progresión-por-sí-sola" class="level3">
<h3 class="anchored" data-anchor-id="ejercicio-3-qué-variable-explica-mejor-la-progresión-por-sí-sola">Ejercicio 3 — ¿Qué variable explica mejor la progresión, por sí sola?</h3>
<p>Ya ajustaste una regresión simple con <code>bmi</code> y otra con <code>bp</code>. Generaliza el ejercicio: ajusta una regresión simple distinta para <strong>cada una</strong> de las 10 variables clínicas, calcula el <img src="https://latex.codecogs.com/png.latex?R%5E2"> que logra cada una por su cuenta y ordénalas de mayor a menor. Aquí el <img src="https://latex.codecogs.com/png.latex?R%5E2"> se calcula sobre los mismos datos con los que ajustas (más adelante, en la sección de evaluación, vas a aprender por qué eso no basta para medir qué tan bien generaliza un modelo) — el objetivo de este ejercicio es solo comparar variables entre sí, no evaluar el modelo rigurosamente.</p>
<p>Fíjate en el resultado: ninguna variable por sí sola se acerca al poder explicativo que se obtiene al combinarlas todas en un modelo de regresión lineal múltiple — el tema del notebook de análisis multivariado del módulo.</p>
<div id="89f8b0ba" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.243596Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.243442Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.246290Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.245569Z&quot;}}" data-execution_count="49">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tu código aquí. Guía de pasos:</span></span>
<span id="cb27-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Recorre cada columna de X_completo (por ejemplo, con un for sobre X_completo.columns)</span></span>
<span id="cb27-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Para cada columna, ajusta un LinearRegression usando solo esa variable como predictor</span></span>
<span id="cb27-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Calcula el R² de esa regresión sobre los mismos datos, con r2_score</span></span>
<span id="cb27-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Guarda los resultados (por ejemplo, en un diccionario o un pd.Series) y ordénalos de mayor a menor</span></span></code></pre></div></div>
</div>
</section>
<section id="ejercicio-4-ecuación-normal-con-s5" class="level3">
<h3 class="anchored" data-anchor-id="ejercicio-4-ecuación-normal-con-s5">Ejercicio 4 — Ecuación normal con <code>s5</code></h3>
<p>Ya reconstruiste con NumPy puro, vía ecuación normal, el modelo simple de <code>bmi</code>. Repite exactamente el mismo procedimiento — matriz de diseño con columna de unos + columna de la variable, y <img src="https://latex.codecogs.com/png.latex?%5Cbeta%20=%20(X%5E%5Ctop%20X)%5E%7B-1%7D%20X%5E%5Ctop%20y"> — pero ahora con <code>s5</code> (triglicéridos, en escala logarítmica), la variable que quedó en segundo lugar en el ranking del ejercicio anterior. Verifica que el resultado coincide con <code>LinearRegression</code>.</p>
<div id="b1aadd48" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.248150Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.247859Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.250947Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.250363Z&quot;}}" data-execution_count="50">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb28-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Tu código aquí. Guía de pasos:</span></span>
<span id="cb28-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Extrae x_s5 = X_completo[["s5"]]</span></span>
<span id="cb28-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Construye la matriz de diseño: columna de unos + columna de s5 (np.hstack, igual que hiciste con bmi)</span></span>
<span id="cb28-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Aplica la ecuación normal: beta = (X^T X)^-1 X^T y, con np.linalg.inv</span></span>
<span id="cb28-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Ajusta también un LinearRegression sobre x_s5 y compara ambos resultados</span></span></code></pre></div></div>
</div>
</section>
<section id="ejercicio-5-qué-tan-frágil-es-la-recta-ante-un-solo-dato-raro" class="level3">
<h3 class="anchored" data-anchor-id="ejercicio-5-qué-tan-frágil-es-la-recta-ante-un-solo-dato-raro">Ejercicio 5 — Qué tan frágil es la recta ante un solo dato raro</h3>
<p>Vuelve al ejemplo de horas de estudio contra calificación. Agrega un único estudiante atípico — uno que estudió muy poco (2 horas) pero sacó una calificación muy alta (95) — y reajusta la recta con la fórmula clásica. Compara la nueva recta con la original, tanto en los coeficientes como visualmente.</p>
<p>Esto sirve para ver algo importante que mínimos cuadrados no te dice por sí solo: como el criterio de ajuste eleva los residuales <strong>al cuadrado</strong>, un único punto muy alejado de la tendencia general puede desplazar la recta bastante más de lo que su “peso” en el conjunto de datos (1 de 11 observaciones) sugeriría. OLS no distingue entre una observación real y un error de medición — ajusta la recta que minimiza el SSE, punto.</p>
<div id="9a9346b4" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:07:35.253449Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:07:35.253187Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:07:35.256689Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:07:35.255956Z&quot;}}" data-execution_count="51">
<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;"># Tu código aquí. Guía de pasos:</span></span>
<span id="cb29-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1. Crea horas_con_outlier y calificacion_con_outlier agregando el par (2, 95) a los arrays originales,</span></span>
<span id="cb29-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#    con np.append</span></span>
<span id="cb29-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2. Recalcula beta0 y beta1 con la fórmula clásica, pero sobre los datos con el outlier incluido</span></span>
<span id="cb29-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3. Compara los nuevos coeficientes contra beta0_manual y beta1_manual (los originales, sin el outlier)</span></span>
<span id="cb29-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4. Grafica ambas rectas (original vs. con el outlier) sobre el mismo scatter para ver el desplazamiento</span></span></code></pre></div></div>
</div>
</section>
<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>estadistica</category>
  <category>regresion-lineal</category>
  <category>scikit-learn</category>
  <guid>https://biitt.com/es/blog/estadistica-fundamentos/01-regresion-lineal/</guid>
  <pubDate>Fri, 28 Aug 2026 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Análisis Avanzado de Datos — 1. Regresión Lineal Múltiple</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/estadistica-fundamentos/02-analisis-multivariado/</link>
  <description><![CDATA[ 




<section id="análisis-avanzado-de-datos-1.-regresión-lineal-múltiple" class="level1">
<h1>Análisis Avanzado de Datos — 1. Regresión Lineal Múltiple</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="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 id="análisis-multivariado-aplicado" class="level2">
<h2 class="anchored" data-anchor-id="análisis-multivariado-aplicado">Análisis Multivariado Aplicado</h2>
<p>Este notebook introduce el <strong>análisis multivariado</strong> de forma enfocada: concepto, supuestos, flujo de modelado e interpretación.</p>
<p>Contexto de ejemplo: <strong>consumo energético residencial</strong> (sin relación con ventas).</p>
</section>
<section id="qué-es-análisis-multivariado" class="level2">
<h2 class="anchored" data-anchor-id="qué-es-análisis-multivariado">1. Qué es análisis multivariado</h2>
<p>En análisis univariado observamos una variable a la vez. En bivariado estudiamos la relación entre dos.</p>
<p>En <strong>multivariado</strong> analizamos varias variables simultáneamente para:</p>
<ul>
<li><p><strong>Explicar una variable objetivo con múltiples predictores</strong>: en lugar de asumir que un solo factor determina el resultado, modelamos la contribución conjunta de varias variables. Esto permite representar mejor fenómenos reales, que casi siempre son multifactoriales.</p></li>
<li><p><strong>Controlar factores de confusión</strong>: algunas variables pueden distorsionar una relación aparente entre predictor y respuesta. Incluirlas en el modelo ayuda a aislar relaciones más limpias y evita conclusiones engañosas.</p></li>
<li><p><strong>Estimar efectos parciales (manteniendo constantes otras variables)</strong>: cada coeficiente se interpreta como el cambio esperado en la respuesta cuando una variable aumenta una unidad y las demás permanecen fijas. Esta idea es clave para interpretar impactos individuales.</p></li>
<li><p><strong>Mejorar capacidad predictiva y toma de decisiones</strong>: combinar información de varias fuentes suele reducir error de predicción y producir recomendaciones más útiles para la acción (priorizar variables, diseñar intervenciones o asignar recursos).</p></li>
</ul>
</section>
<section id="modelo-base-regresión-lineal-múltiple" class="level2">
<h2 class="anchored" data-anchor-id="modelo-base-regresión-lineal-múltiple">2. Modelo base: regresión lineal múltiple</h2>
<p>Una formulación típica es:</p>
<p><img src="https://latex.codecogs.com/png.latex?y%20=%20%5Cbeta_0%20+%20%5Cbeta_1%20x_1%20+%20%5Cbeta_2%20x_2%20+%20%5Ccdots%20+%20%5Cbeta_p%20x_p%20+%20%5Cvarepsilon"></p>
<p>donde:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?y"> es la variable objetivo,</li>
<li><img src="https://latex.codecogs.com/png.latex?x_1,%20...,%20x_p"> son predictores,</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cbeta_j"> representa el cambio esperado en <img src="https://latex.codecogs.com/png.latex?y"> por una unidad adicional de <img src="https://latex.codecogs.com/png.latex?x_j">, manteniendo las demás variables constantes,</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cvarepsilon"> captura variación no explicada.</li>
</ul>
</section>
<section id="ejemplo-de-contexto-energía-residencial" class="level2">
<h2 class="anchored" data-anchor-id="ejemplo-de-contexto-energía-residencial">3. Ejemplo de contexto (energía residencial)</h2>
<p>Objetivo: explicar el consumo mensual de energía (kWh) a partir de variables como:</p>
<ul>
<li>temperatura promedio exterior,</li>
<li>número de ocupantes,</li>
<li>área de la vivienda (m2),</li>
<li>índice de aislamiento térmico,</li>
<li>cantidad de electrodomésticos intensivos.</li>
</ul>
<p>Este tipo de problema es naturalmente multivariado: una sola variable rara vez explica por completo el consumo.</p>
<div id="7ade1677" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:51.787685Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:51.787321Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:52.616955Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:52.616254Z&quot;}}" data-execution_count="34">
<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">pip install seaborn</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Requirement already satisfied: seaborn in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (0.13.2)
Requirement already satisfied: numpy!=1.24.0,&gt;=1.20 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from seaborn) (2.5.1)
Requirement already satisfied: pandas&gt;=1.2 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from seaborn) (3.0.5)
Requirement already satisfied: matplotlib!=3.6.1,&gt;=3.4 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from seaborn) (3.11.1)
Requirement already satisfied: contourpy&gt;=1.0.1 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (1.3.3)
Requirement already satisfied: cycler&gt;=0.10 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (0.12.1)
Requirement already satisfied: fonttools&gt;=4.28.2 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (4.63.0)
Requirement already satisfied: kiwisolver&gt;=1.3.1 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (1.5.0)
Requirement already satisfied: packaging&gt;=20.0 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (26.0)
Requirement already satisfied: pillow&gt;=9 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (12.3.0)
Requirement already satisfied: pyparsing&gt;=3 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (3.3.2)
Requirement already satisfied: python-dateutil&gt;=2.7 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (2.9.0.post0)
Requirement already satisfied: tzdata in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from pandas&gt;=1.2-&gt;seaborn) (2026.3)
Requirement already satisfied: six&gt;=1.5 in c:\Users\wilde\.conda\envs\ANALITICA\Lib\site-packages (from python-dateutil&gt;=2.7-&gt;matplotlib!=3.6.1,&gt;=3.4-&gt;seaborn) (1.17.0)
Note: you may need to restart the kernel to use updated packages.</code></pre>
</div>
</div>
<div id="d3a27f3b" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:52.618621Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:52.618386Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:54.855093Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:54.854410Z&quot;}}" data-execution_count="35">
<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;"># Librerias base para analisis multivariado</span></span>
<span id="cb3-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="cb3-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="cb3-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="cb3-5"><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-6"></span>
<span id="cb3-7"><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, cross_val_score</span>
<span id="cb3-8"><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> LinearRegression, Ridge, Lasso</span>
<span id="cb3-9"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.pipeline <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Pipeline</span>
<span id="cb3-10"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StandardScaler</span>
<span id="cb3-11"><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> mean_squared_error, mean_absolute_error, r2_score</span>
<span id="cb3-12"></span>
<span id="cb3-13"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> statsmodels.api <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sm</span>
<span id="cb3-14"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> statsmodels.stats.outliers_influence <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> variance_inflation_factor</span>
<span id="cb3-15"></span>
<span id="cb3-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Estilo visual base para mantener uniformidad en todas las graficas</span></span>
<span id="cb3-17">sns.set_theme(style<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;">"whitegrid"</span>, context<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;">"notebook"</span>)</span>
<span id="cb3-18">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"axes.titlesize"</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;">12</span></span>
<span id="cb3-19">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"axes.labelsize"</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></code></pre></div></div>
</div>
<div id="f7e2163d" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:54.856774Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:54.856490Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:54.869727Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:54.869138Z&quot;}}" data-execution_count="36">
<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;"># Dataset sintetico: energia residencial</span></span>
<span id="cb4-2">rng <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.default_rng(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>)</span>
<span id="cb4-3">n <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>
<span id="cb4-4"></span>
<span id="cb4-5">temperatura <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, n)</span>
<span id="cb4-6">ocupantes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.integers(<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;">7</span>, n)</span>
<span id="cb4-7">area_m2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">85</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, n).clip(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">35</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">180</span>)</span>
<span id="cb4-8">aislamiento <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.uniform(<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;">1.0</span>, n)</span>
<span id="cb4-9">electrodomesticos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.integers(<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;">11</span>, n)</span>
<span id="cb4-10"></span>
<span id="cb4-11">ruido <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<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;">25</span>, n)</span>
<span id="cb4-12">consumo_kwh <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb4-13">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span></span>
<span id="cb4-14">    <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;">1.8</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> area_m2</span>
<span id="cb4-15">    <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;">18</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ocupantes</span>
<span id="cb4-16">    <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;">9</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> electrodomesticos</span>
<span id="cb4-17">    <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;">55</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> aislamiento</span>
<span id="cb4-18">    <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.7</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;">abs</span>(temperatura <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;">22</span>)</span>
<span id="cb4-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> ruido</span>
<span id="cb4-20">)</span>
<span id="cb4-21"></span>
<span id="cb4-22">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb4-23">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"temperatura"</span>: temperatura,</span>
<span id="cb4-24">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ocupantes"</span>: ocupantes,</span>
<span id="cb4-25">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"area_m2"</span>: area_m2,</span>
<span id="cb4-26">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"aislamiento"</span>: aislamiento,</span>
<span id="cb4-27">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"electrodomesticos"</span>: electrodomesticos,</span>
<span id="cb4-28">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>: consumo_kwh</span>
<span id="cb4-29">})</span>
<span id="cb4-30"></span>
<span id="cb4-31">df.head()</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="36">
<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">temperatura</th>
<th data-quarto-table-cell-role="th">ocupantes</th>
<th data-quarto-table-cell-role="th">area_m2</th>
<th data-quarto-table-cell-role="th">aislamiento</th>
<th data-quarto-table-cell-role="th">electrodomesticos</th>
<th data-quarto-table-cell-role="th">consumo_kwh</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>25.402989</td>
<td>6</td>
<td>63.467466</td>
<td>0.844029</td>
<td>3</td>
<td>299.966911</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>21.372362</td>
<td>2</td>
<td>91.735187</td>
<td>0.989880</td>
<td>2</td>
<td>270.224405</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>15.348039</td>
<td>3</td>
<td>113.854308</td>
<td>0.644984</td>
<td>8</td>
<td>484.737064</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>19.251657</td>
<td>6</td>
<td>103.425939</td>
<td>0.868907</td>
<td>6</td>
<td>438.477021</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>18.642142</td>
<td>3</td>
<td>104.342106</td>
<td>0.951808</td>
<td>10</td>
<td>391.704887</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
</section>
<section id="flujo-recomendado-de-trabajo" class="level2">
<h2 class="anchored" data-anchor-id="flujo-recomendado-de-trabajo">4. Flujo recomendado de trabajo</h2>
<ol type="1">
<li><strong>Definir pregunta y variable objetivo</strong></li>
</ol>
<p>Este paso responde: “¿Qué quiero entender o predecir exactamente?”. Si la pregunta es difusa, el modelo también lo será. La variable objetivo es el resultado final que intentamos explicar.</p>
<p><strong>Términos clave</strong>: - <strong>Variable objetivo</strong>: el resultado principal del estudio. - <strong>Unidad de análisis</strong>: sobre quién se mide (hogar, persona, empresa, etc.). - <strong>Horizonte temporal</strong>: en qué período se mide (día, mes, año).</p>
<p>Por qué importa: este paso pone límites claros al análisis y evita mezclar objetivos distintos en un mismo modelo.</p>
<ol start="2" type="1">
<li><strong>Revisar calidad de datos (nulos, atípicos, escalas, codificación)</strong></li>
</ol>
<p>Aquí verificamos si los datos son confiables antes de sacar conclusiones. Si hay valores faltantes, errores extremos o categorías mal registradas, el modelo aprende “ruido” en lugar de aprender patrones reales.</p>
<p><strong>Términos clave</strong>: - <strong>Nulos</strong>: datos faltantes. - <strong>Atípicos (outliers)</strong>: valores muy alejados del comportamiento normal. - <strong>Escala</strong>: tamaño numérico de una variable (por ejemplo 0-1 versus 0-10000). - <strong>Codificación</strong>: forma de representar texto o categorías en formato útil para análisis.</p>
<p>Por qué importa: un modelo no corrige automáticamente datos mal preparados; solo amplifica sus problemas.</p>
<ol start="3" type="1">
<li><strong>Explorar relaciones entre predictores y objetivo</strong></li>
</ol>
<p>Antes de modelar, observamos cómo se mueven las variables entre sí. Este paso ayuda a detectar relaciones claras, relaciones débiles, posibles efectos no lineales y variables redundantes.</p>
<p><strong>Términos clave</strong>: - <strong>Predictor</strong>: variable usada para explicar la objetivo. - <strong>Relación lineal</strong>: cuando el cambio entre variables sigue una tendencia aproximadamente recta. - <strong>Interacción</strong>: cuando el efecto de una variable depende del nivel de otra.</p>
<p>Por qué importa: evita construir un modelo “a ciegas” y orienta mejores decisiones de modelado.</p>
<ol start="4" type="1">
<li><strong>Partir datos en entrenamiento y prueba</strong></li>
</ol>
<p>Separamos los datos en dos grupos: uno para aprender y otro para evaluar. El modelo se ajusta con entrenamiento y se pone a prueba con datos que no vio.</p>
<p><strong>Términos clave</strong>: - <strong>Entrenamiento (train)</strong>: datos para ajustar el modelo. - <strong>Prueba (test)</strong>: datos reservados para medir desempeño real. - <strong>Generalización</strong>: capacidad de funcionar bien en datos nuevos.</p>
<p>Por qué importa: sin esta separación, es fácil creer que el modelo es bueno cuando solo está memorizando.</p>
<ol start="5" type="1">
<li><strong>Ajustar modelo base (OLS o equivalente)</strong></li>
</ol>
<p>Construimos primero una versión simple y explicable del modelo. Ese modelo base funciona como punto de partida para comparar mejoras posteriores.</p>
<p><strong>Términos clave</strong>: - <strong>OLS</strong>: método clásico que ajusta la mejor línea/plano minimizando errores al cuadrado. - <strong>Coeficiente</strong>: cuánto cambia la variable objetivo si un predictor sube una unidad (manteniendo lo demás constante). - <strong>Intercepto</strong>: valor esperado de la variable objetivo cuando los predictores valen cero (si tiene interpretación en el contexto).</p>
<p>Por qué importa: un buen modelo base permite saber si la complejidad adicional realmente aporta valor.</p>
<ol start="6" type="1">
<li><strong>Diagnosticar supuestos y multicolinealidad</strong></li>
</ol>
<p>Este paso es un control de calidad del modelo ya entrenado. La pregunta aquí no es solo “¿cuánto acierta?”, sino también “¿es confiable lo que dice?”.</p>
<p>En lenguaje simple: un modelo puede dar buenas predicciones promedio y aun así estar mal calibrado para interpretar efectos. Por ejemplo, si los residuos muestran patrón (en vez de dispersarse de forma aleatoria), el modelo está dejando estructura sin explicar. Si dos predictores dicen casi lo mismo, los coeficientes pueden volverse inestables y cambiar de signo entre muestras parecidas.</p>
<p><strong>Términos clave</strong>: - <strong>Residuo</strong>: diferencia entre valor real y valor predicho. - <strong>Homoscedasticidad</strong>: variabilidad de residuos parecida a lo largo del rango de predicciones. - <strong>Multicolinealidad</strong>: solapamiento fuerte de información entre predictores. - <strong>VIF</strong>: indicador de cuánto se infla la incertidumbre de un coeficiente por colinealidad.</p>
<p>Regla práctica: si esta etapa falla, no conviene interpretar coeficientes como si fueran firmes, aunque el error global parezca bueno.</p>
<p>Por qué importa: protege contra conclusiones frágiles y mejora la credibilidad técnica del análisis.</p>
<ol start="7" type="1">
<li><strong>Evaluar con métricas y validación cruzada</strong></li>
</ol>
<p>Evaluar bien significa mirar el desempeño desde tres ángulos: magnitud del error, sensibilidad a errores grandes y estabilidad del modelo.</p>
<p>Primero, las métricas sobre test te dicen “cómo le fue” en una partición concreta. Luego, la validación cruzada responde “si repito el proceso, ¿se mantiene el resultado o cambia mucho?”. Esa segunda pregunta es clave para confiar en que el modelo no depende de una sola muestra afortunada.</p>
<p><strong>Términos clave</strong>: - <strong>MAE</strong>: error promedio absoluto; se interpreta fácil porque está en unidades reales. - <strong>RMSE</strong>: parecido al MAE, pero castiga más los errores grandes. - <strong>R2</strong>: porcentaje de variabilidad explicado por el modelo. - <strong>Validación cruzada</strong>: repetir entrenamiento/evaluación en varios pliegues para medir robustez.</p>
<p>Lectura recomendada: no decidir con una sola métrica. Un modelo puede tener buen R2 y aun así cometer errores absolutos demasiado altos para el contexto de decisión.</p>
<p>Por qué importa: permite seleccionar modelos por desempeño real y estable, no por resultados puntuales.</p>
<ol start="8" type="1">
<li><strong>Iterar (transformaciones, regularización, selección de variables)</strong></li>
</ol>
<p>Con los resultados en mano, se mejora el modelo paso a paso. La idea es simplificar lo necesario y ganar estabilidad sin perder interpretabilidad.</p>
<p><strong>Términos clave</strong>: - <strong>Transformación</strong>: cambiar la escala o forma de una variable para capturar mejor su relación con la objetivo. - <strong>Regularización</strong>: técnica para evitar sobreajuste penalizando complejidad excesiva. - <strong>Ridge/Lasso</strong>: métodos comunes para estabilizar o simplificar coeficientes cuando hay muchas variables o colinealidad.</p>
<p>Por qué importa: el primer modelo rara vez es el mejor; iterar con criterio mejora calidad y confiabilidad.</p>
<ol start="9" type="1">
<li><strong>Comunicar resultados con interpretación y límites</strong></li>
</ol>
<p>El trabajo termina cuando el resultado se puede entender y usar para decidir. Se debe explicar qué se encontró, con qué confianza, bajo qué condiciones y con qué restricciones.</p>
<p><strong>Términos clave</strong>: - <strong>Significancia estadística</strong>: evidencia de que una relación no parece producto del azar, bajo supuestos. - <strong>Relevancia práctica</strong>: si el efecto encontrado realmente importa en la realidad. - <strong>Limitaciones</strong>: lo que el modelo no cubre o no puede asegurar.</p>
<p>Por qué importa: un análisis serio no solo reporta aciertos; también declara alcances, riesgos y límites de uso.</p>
<p>Criterio general: en análisis multivariado, la claridad de la pregunta y la calidad de los datos suelen influir más en el resultado que elegir un algoritmo más sofisticado.</p>
</section>
<section id="exploración-multivariada" class="level2">
<h2 class="anchored" data-anchor-id="exploración-multivariada">5. Exploración multivariada</h2>
<p>La exploración multivariada es el puente entre “tener datos” y “construir un modelo con criterio”. Su objetivo no es solo describir, sino detectar señales útiles y riesgos metodológicos antes del entrenamiento formal.</p>
<p>En esta etapa buscamos responder preguntas prácticas como: - ¿Qué variables parecen realmente informativas? - ¿Cuáles variables parecen duplicar información? - ¿Hay patrones no lineales que un modelo lineal simple no capturaría bien? - ¿Existen grupos atípicos que puedan sesgar conclusiones?</p>
<section id="distribuciones-marginales" class="level3">
<h3 class="anchored" data-anchor-id="distribuciones-marginales">5.1 Distribuciones marginales</h3>
<p>Una distribución marginal muestra el comportamiento de cada variable por separado. Aquí observamos centro (media/mediana), dispersión (rango, desviación), asimetría y presencia de valores extremos.</p>
<p>Por qué importa: si una variable tiene cola muy larga o fuerte asimetría, puede requerir transformación para modelar mejor.</p>
</section>
<section id="relación-predictor-objetivo" class="level3">
<h3 class="anchored" data-anchor-id="relación-predictor-objetivo">5.2 Relación predictor-objetivo</h3>
<p>Luego observamos cada predictor contra la variable objetivo. No buscamos perfección, buscamos forma general de relación: creciente, decreciente, curvilínea o casi nula.</p>
<p>Por qué importa: ayuda a priorizar variables y evita asumir linealidad donde no la hay.</p>
</section>
<section id="relación-entre-predictores" class="level3">
<h3 class="anchored" data-anchor-id="relación-entre-predictores">5.3 Relación entre predictores</h3>
<p>También analizamos cómo se relacionan los predictores entre sí. Si dos variables se mueven casi juntas, pueden aportar información redundante.</p>
<p>Por qué importa: la redundancia puede inflar incertidumbre de coeficientes y dificultar interpretación.</p>
</section>
<section id="matriz-de-correlaciones-qué-sí-y-qué-no" class="level3">
<h3 class="anchored" data-anchor-id="matriz-de-correlaciones-qué-sí-y-qué-no">5.4 Matriz de correlaciones: qué sí y qué no</h3>
<p>La correlación resume asociación lineal entre pares de variables. Es útil como mapa rápido, pero no reemplaza la inspección visual ni implica causalidad.</p>
<p>Lectura prudente: - Correlación alta sugiere relación lineal fuerte, no necesariamente utilidad causal. - Correlación baja no descarta relación no lineal. - Correlación entre predictores alerta posible colinealidad.</p>
</section>
<section id="patrones-no-lineales" class="level3">
<h3 class="anchored" data-anchor-id="patrones-no-lineales">5.5 Patrones no lineales</h3>
<p>En multivariado real, muchas relaciones no son rectas. Puede haber umbrales, saturaciones o efectos en U.</p>
<p>Por qué importa: si forzamos linealidad cuando la relación es curvilínea, aumentan residuos sistemáticos y baja capacidad explicativa.</p>
</section>
<section id="segmentos-y-heterogeneidad" class="level3">
<h3 class="anchored" data-anchor-id="segmentos-y-heterogeneidad">5.6 Segmentos y heterogeneidad</h3>
<p>A veces el mismo fenómeno se comporta distinto en subgrupos (por zona, tipo de hogar, estrato de consumo, etc.). Esto se llama heterogeneidad estructural.</p>
<p>Por qué importa: un solo modelo global puede ocultar patrones opuestos entre segmentos.</p>
</section>
<section id="outliers-con-contexto" class="level3">
<h3 class="anchored" data-anchor-id="outliers-con-contexto">5.7 Outliers con contexto</h3>
<p>No todo outlier es error. Algunos son errores de captura; otros son casos reales raros pero informativos.</p>
<p>Buena práctica: diferenciar <strong>outlier técnico</strong> (dato incorrecto) de <strong>outlier sustantivo</strong> (caso extremo real). La decisión de tratar o conservar debe quedar justificada.</p>
</section>
<section id="resultado-esperado-de-esta-fase" class="level3">
<h3 class="anchored" data-anchor-id="resultado-esperado-de-esta-fase">5.8 Resultado esperado de esta fase</h3>
<p>Una buena exploración multivariada produce tres entregables concretos: 1. Hipótesis de trabajo sobre qué variables deberían entrar al modelo base. 2. Lista de riesgos (colinealidad, no linealidad, outliers, posibles segmentos). 3. Plan de modelado (transformaciones, interacciones y pruebas diagnósticas a ejecutar).</p>
</section>
<section id="ejemplo-guiado-con-dataset-sintético-y-validación" class="level3">
<h3 class="anchored" data-anchor-id="ejemplo-guiado-con-dataset-sintético-y-validación">5.9 Ejemplo guiado con dataset sintético y validación</h3>
<p>En las celdas siguientes vamos a crear un dataset sintético y validar cada punto anterior de forma observable: - distribuciones marginales, - relación predictor-objetivo, - relación entre predictores y posible colinealidad, - matriz de correlaciones (y su interpretación), - evidencia de no linealidad, - diferencias por segmento, - detección de outliers con criterio.</p>
<p>Idea central: no es solo “mirar gráficos”; es transformar observaciones en decisiones de modelado.</p>
<div id="04c065ce" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:54.871343Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:54.871143Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:54.882235Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:54.881742Z&quot;}}" data-execution_count="37">
<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;"># Etapa 1: construir un dataset sintetico controlado</span></span>
<span id="cb5-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> PolynomialFeatures</span>
<span id="cb5-3"><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> LinearRegression</span>
<span id="cb5-4"></span>
<span id="cb5-5">rng <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.default_rng(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2026</span>)</span>
<span id="cb5-6">n <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;">450</span></span>
<span id="cb5-7"></span>
<span id="cb5-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Segmento para heterogeneidad estructural</span></span>
<span id="cb5-9">segmento <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.choice([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"urbano"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rural"</span>], size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>n, p<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.65</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.35</span>])</span>
<span id="cb5-10"></span>
<span id="cb5-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Predictores con relación y colinealidad parcial</span></span>
<span id="cb5-12">ingreso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2500</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">700</span>, n).clip(<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;">6000</span>)</span>
<span id="cb5-13">tamano_hogar <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.integers(<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;">7</span>, n)</span>
<span id="cb5-14">edad_vivienda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>, n).clip(<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;">60</span>)</span>
<span id="cb5-15">aislamiento <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.uniform(<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.95</span>, n)</span>
<span id="cb5-16"></span>
<span id="cb5-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Variable casi redundante con ingreso (colinealidad intencional)</span></span>
<span id="cb5-18">gasto_electrico_base <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.28</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ingreso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> rng.normal(<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;">120</span>, n)</span>
<span id="cb5-19"></span>
<span id="cb5-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Relación no lineal intencional con temperatura</span></span>
<span id="cb5-21">temperatura <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, n)</span>
<span id="cb5-22">efecto_temp <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;">3.5</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;">abs</span>(temperatura <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;">24</span>)</span>
<span id="cb5-23"></span>
<span id="cb5-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Consumo con diferencias por segmento</span></span>
<span id="cb5-25">efecto_segmento <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.where(segmento <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;">"urbano"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</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>
<span id="cb5-26">ruido <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.normal(<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;">45</span>, n)</span>
<span id="cb5-27"></span>
<span id="cb5-28">consumo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb5-29">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">140</span></span>
<span id="cb5-30">    <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.045</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ingreso</span>
<span id="cb5-31">    <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;">26</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> tamano_hogar</span>
<span id="cb5-32">    <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;">1.4</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> edad_vivienda</span>
<span id="cb5-33">    <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;">95</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> aislamiento</span>
<span id="cb5-34">    <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.10</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> gasto_electrico_base</span>
<span id="cb5-35">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> efecto_temp</span>
<span id="cb5-36">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> efecto_segmento</span>
<span id="cb5-37">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> ruido</span>
<span id="cb5-38">)</span>
<span id="cb5-39"></span>
<span id="cb5-40">df_demo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb5-41">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"segmento"</span>: segmento,</span>
<span id="cb5-42">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso"</span>: ingreso,</span>
<span id="cb5-43">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tamano_hogar"</span>: tamano_hogar,</span>
<span id="cb5-44">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"edad_vivienda"</span>: edad_vivienda,</span>
<span id="cb5-45">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"aislamiento"</span>: aislamiento,</span>
<span id="cb5-46">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gasto_electrico_base"</span>: gasto_electrico_base,</span>
<span id="cb5-47">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"temperatura"</span>: temperatura,</span>
<span id="cb5-48">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>: consumo</span>
<span id="cb5-49">})</span>
<span id="cb5-50"></span>
<span id="cb5-51"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Inyectamos unos pocos outliers tecnicos</span></span>
<span id="cb5-52">idx_out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> rng.choice(df_demo.index, size<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>, replace<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="cb5-53">df_demo.loc[idx_out, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*=</span> rng.uniform(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.2</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>, size<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>
<span id="cb5-54"></span>
<span id="cb5-55">preds <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;">"ingreso"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tamano_hogar"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"edad_vivienda"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"aislamiento"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gasto_electrico_base"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"temperatura"</span>]</span>
<span id="cb5-56"></span>
<span id="cb5-57"><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 listo:"</span>, df_demo.shape)</span>
<span id="cb5-58">df_demo.head()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Dataset listo: (450, 8)</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="37">
<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">segmento</th>
<th data-quarto-table-cell-role="th">ingreso</th>
<th data-quarto-table-cell-role="th">tamano_hogar</th>
<th data-quarto-table-cell-role="th">edad_vivienda</th>
<th data-quarto-table-cell-role="th">aislamiento</th>
<th data-quarto-table-cell-role="th">gasto_electrico_base</th>
<th data-quarto-table-cell-role="th">temperatura</th>
<th data-quarto-table-cell-role="th">consumo_kwh</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>urbano</td>
<td>3529.588009</td>
<td>5</td>
<td>18.831308</td>
<td>0.318681</td>
<td>848.615877</td>
<td>27.700205</td>
<td>651.985974</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>urbano</td>
<td>3011.545595</td>
<td>1</td>
<td>17.317106</td>
<td>0.395043</td>
<td>943.795033</td>
<td>21.264064</td>
<td>455.502952</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>urbano</td>
<td>1867.989940</td>
<td>2</td>
<td>19.121387</td>
<td>0.916190</td>
<td>641.560758</td>
<td>19.776674</td>
<td>381.269929</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>urbano</td>
<td>2766.180609</td>
<td>6</td>
<td>7.003895</td>
<td>0.350032</td>
<td>725.326119</td>
<td>27.505114</td>
<td>580.113407</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>urbano</td>
<td>3329.189267</td>
<td>4</td>
<td>33.654735</td>
<td>0.762742</td>
<td>879.857518</td>
<td>13.710123</td>
<td>537.211727</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 1 (construcción del dataset)</strong></p>
<ul>
<li>Se creó una muestra sintética con estructura controlada, suficiente para demostrar fenómenos multivariados reales: colinealidad, heterogeneidad, no linealidad y outliers.</li>
<li>Esta etapa no busca probar hipótesis, sino garantizar un “laboratorio” donde cada patrón aparezca de forma observable.</li>
<li>Conclusión metodológica: antes de interpretar resultados, siempre verifica que entiendes cómo fue generado o recolectado el dato.</li>
</ul>
</div>
</section>
<section id="desarrollo-por-etapas-enfoque-didáctico" class="level3">
<h3 class="anchored" data-anchor-id="desarrollo-por-etapas-enfoque-didáctico">5.9 Desarrollo por etapas (enfoque didáctico)</h3>
<p>En lugar de un script único, separamos el análisis en etapas para validar cada idea por separado.</p>
<ul>
<li><strong>Etapa 1</strong>: crear datos sintéticos con patrones controlados.</li>
<li><strong>Etapa 2</strong>: revisar distribuciones marginales.</li>
<li><strong>Etapa 3</strong>: medir correlación de predictores con la variable objetivo.</li>
<li><strong>Etapa 4</strong>: estudiar correlación entre predictores (aquí está el foco principal).</li>
<li><strong>Etapa 5</strong>: confirmar redundancia con VIF.</li>
<li><strong>Etapa 6</strong>: comprobar no linealidad.</li>
<li><strong>Etapa 7</strong>: evaluar heterogeneidad por segmento.</li>
<li><strong>Etapa 8</strong>: detectar outliers con criterio IQR.</li>
</ul>
<p>Sugerencia: ejecuta en orden para que cada etapa use objetos creados en las anteriores.</p>
<p>Una aclaración antes de empezar: para que estos patrones (colinealidad fuerte, heterogeneidad clara, outliers marcados) se vean con nitidez, el dataset que vas a construir en la Etapa 1 es <em>distinto</em> del de energía residencial de la sección 3 — tiene variables propias (<code>ingreso</code>, <code>tamano_hogar</code>, <code>gasto_electrico_base</code>, <code>segmento</code> urbano/rural) diseñadas a propósito para ilustrar cada fenómeno con claridad. Cuando lleguemos a la sección 6 y construyamos el modelo completo, vas a volver al dataset original de la sección 3.</p>
<div id="349bb4ef" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:54.883873Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:54.883687Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:55.527818Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:55.527220Z&quot;}}" data-execution_count="38">
<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;"># Etapa 2: distribuciones marginales y asimetría</span></span>
<span id="cb7-2">vars_plot <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;">"consumo_kwh"</span>, <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;">"tamano_hogar"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"edad_vivienda"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"aislamiento"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"temperatura"</span>]</span>
<span id="cb7-3"></span>
<span id="cb7-4">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;">7</span>))</span>
<span id="cb7-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> ax, col <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.ravel(), vars_plot):</span>
<span id="cb7-6">    sns.histplot(df_demo[col], kde<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>, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax)</span>
<span id="cb7-7">    ax.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Distribución: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>col<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="cb7-8">plt.tight_layout()</span>
<span id="cb7-9">plt.show()</span>
<span id="cb7-10"></span>
<span id="cb7-11"><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;">"Asimetria (skewness) por variable:"</span>)</span>
<span id="cb7-12">display(df_demo[vars_plot].skew().to_frame(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skew"</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/estadistica-fundamentos/02-analisis-multivariado/index_files/figure-html/cell-6-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Asimetria (skewness) por variable:</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">skew</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">consumo_kwh</th>
<td>2.880080</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">ingreso</th>
<td>-0.046295</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">tamano_hogar</th>
<td>-0.115303</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">edad_vivienda</th>
<td>0.255195</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">aislamiento</th>
<td>0.081775</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">temperatura</th>
<td>-0.130655</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 2 (distribuciones y asimetría)</strong></p>
<ul>
<li>La asimetría de consumo_kwh es claramente mayor que la de la mayoría de predictores, lo que sugiere presencia de cola derecha (consumos extremos).</li>
<li>Los predictores principales muestran formas razonables y no patológicas en comparación con la variable objetivo.</li>
<li>Conclusión analítica: ya hay evidencia temprana de observaciones extremas en la respuesta; esto justifica revisar outliers más adelante (Etapa 8).</li>
</ul>
</div>
<div id="b74f334c" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:55.529850Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:55.529675Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:55.662065Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:55.661427Z&quot;}}" data-execution_count="39">
<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;"># Etapa 3: correlación de cada predictor con la variable objetivo</span></span>
<span id="cb9-2">corr_target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[preds <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;">"consumo_kwh"</span>]].corr()[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>].drop(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>)</span>
<span id="cb9-3">corr_target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> corr_target.sort_values(key<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;">abs</span>, ascending<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="cb9-4"></span>
<span id="cb9-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;">"Correlación predictor -&gt; consumo (ordenada por magnitud absoluta):"</span>)</span>
<span id="cb9-6">display(corr_target.to_frame(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"corr_con_consumo"</span>))</span>
<span id="cb9-7"></span>
<span id="cb9-8">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;">7</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb9-9">corr_target.sort_values().plot(kind<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;">"barh"</span>)</span>
<span id="cb9-10">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Correlación de predictores con consumo_kwh"</span>)</span>
<span id="cb9-11">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Coeficiente de correlación"</span>)</span>
<span id="cb9-12">plt.tight_layout()</span>
<span id="cb9-13">plt.show()</span>
<span id="cb9-14"></span>
<span id="cb9-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;">"Interpretación: magnitud más alta = asociación lineal más fuerte (no implica causalidad)."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Correlación predictor -&gt; consumo (ordenada por magnitud absoluta):</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">corr_con_consumo</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">gasto_electrico_base</th>
<td>0.437479</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">ingreso</th>
<td>0.434257</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">tamano_hogar</th>
<td>0.375648</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">aislamiento</th>
<td>-0.135343</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">temperatura</th>
<td>-0.117516</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">edad_vivienda</th>
<td>0.099901</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/estadistica-fundamentos/02-analisis-multivariado/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>Interpretación: magnitud más alta = asociación lineal más fuerte (no implica causalidad).</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 3 (correlación predictor-objetivo)</strong></p>
<ul>
<li>Los predictores con mayor correlación absoluta con consumo_kwh son ingreso y gasto_electrico_base; por tanto, son candidatos fuertes para el modelo base.</li>
<li>tamano_hogar también aporta señal útil, aunque menor.</li>
<li>Variables con correlación baja no se descartan automáticamente: podrían actuar de forma no lineal o en interacción con otras.</li>
<li>Conclusión clave para estudiantes: correlación alta prioriza, no sentencia causalidad.</li>
</ul>
</div>
<div id="b9479817" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:55.664013Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:55.663795Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:55.888802Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:55.888216Z&quot;}}" data-execution_count="40">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Etapa 4: correlación entre predictores (foco principal)</span></span>
<span id="cb12-2">corr_preds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[preds].corr()</span>
<span id="cb12-3"></span>
<span id="cb12-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;">"Matriz de correlación entre predictores:"</span>)</span>
<span id="cb12-5">display(corr_preds)</span>
<span id="cb12-6"></span>
<span id="cb12-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;">5</span>))</span>
<span id="cb12-8">sns.heatmap(corr_preds, 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>, 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;">"coolwarm"</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;">".2f"</span>)</span>
<span id="cb12-9">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Correlación entre predictores"</span>)</span>
<span id="cb12-10">plt.show()</span>
<span id="cb12-11"></span>
<span id="cb12-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Ranking de pares con mayor correlación absoluta</span></span>
<span id="cb12-13">pairs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb12-14">    corr_preds.where(np.triu(np.ones(corr_preds.shape), k<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>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">bool</span>))</span>
<span id="cb12-15">    .stack()</span>
<span id="cb12-16">    .reset_index()</span>
<span id="cb12-17">    .rename(columns<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;">"level_0"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"var_1"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"level_1"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"var_2"</span>, <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;">"corr"</span>})</span>
<span id="cb12-18">)</span>
<span id="cb12-19">pairs[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"abs_corr"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pairs[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"corr"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>()</span>
<span id="cb12-20">pairs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pairs.sort_values(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"abs_corr"</span>, ascending<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="cb12-21"></span>
<span id="cb12-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;">"Top 8 pares más correlacionados (en valor absoluto):"</span>)</span>
<span id="cb12-23">display(pairs.head(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>))</span>
<span id="cb12-24"></span>
<span id="cb12-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;">"Lectura clave: una correlación alta entre predictores sugiere posible redundancia de información."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Matriz de correlación entre predictores:</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">ingreso</th>
<th data-quarto-table-cell-role="th">tamano_hogar</th>
<th data-quarto-table-cell-role="th">edad_vivienda</th>
<th data-quarto-table-cell-role="th">aislamiento</th>
<th data-quarto-table-cell-role="th">gasto_electrico_base</th>
<th data-quarto-table-cell-role="th">temperatura</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">ingreso</th>
<td>1.000000</td>
<td>0.058265</td>
<td>0.015557</td>
<td>0.022029</td>
<td>0.869356</td>
<td>-0.015021</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">tamano_hogar</th>
<td>0.058265</td>
<td>1.000000</td>
<td>0.010388</td>
<td>0.023812</td>
<td>0.026014</td>
<td>-0.034876</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">edad_vivienda</th>
<td>0.015557</td>
<td>0.010388</td>
<td>1.000000</td>
<td>0.005575</td>
<td>0.003494</td>
<td>-0.008368</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">aislamiento</th>
<td>0.022029</td>
<td>0.023812</td>
<td>0.005575</td>
<td>1.000000</td>
<td>-0.008215</td>
<td>0.022293</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">gasto_electrico_base</th>
<td>0.869356</td>
<td>0.026014</td>
<td>0.003494</td>
<td>-0.008215</td>
<td>1.000000</td>
<td>-0.017753</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">temperatura</th>
<td>-0.015021</td>
<td>-0.034876</td>
<td>-0.008368</td>
<td>0.022293</td>
<td>-0.017753</td>
<td>1.000000</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/estadistica-fundamentos/02-analisis-multivariado/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>Top 8 pares más correlacionados (en valor absoluto):</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">var_1</th>
<th data-quarto-table-cell-role="th">var_2</th>
<th data-quarto-table-cell-role="th">corr</th>
<th data-quarto-table-cell-role="th">abs_corr</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>ingreso</td>
<td>gasto_electrico_base</td>
<td>0.869356</td>
<td>0.869356</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>ingreso</td>
<td>tamano_hogar</td>
<td>0.058265</td>
<td>0.058265</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">11</th>
<td>tamano_hogar</td>
<td>temperatura</td>
<td>-0.034876</td>
<td>0.034876</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">10</th>
<td>tamano_hogar</td>
<td>gasto_electrico_base</td>
<td>0.026014</td>
<td>0.026014</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">9</th>
<td>tamano_hogar</td>
<td>aislamiento</td>
<td>0.023812</td>
<td>0.023812</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">23</th>
<td>aislamiento</td>
<td>temperatura</td>
<td>0.022293</td>
<td>0.022293</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">3</th>
<td>ingreso</td>
<td>aislamiento</td>
<td>0.022029</td>
<td>0.022029</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">29</th>
<td>gasto_electrico_base</td>
<td>temperatura</td>
<td>-0.017753</td>
<td>0.017753</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Lectura clave: una correlación alta entre predictores sugiere posible redundancia de información.</code></pre>
</div>
</div>
<div style="background-color:#e9f7ef; border-left:6px solid #2f855a; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 4 (correlación entre predictores, foco principal)</strong></p>
<ul>
<li>La matriz y el ranking de pares muestran una correlación muy alta entre ingreso y gasto_electrico_base (alrededor de 0.87).</li>
<li>Esto indica redundancia informativa: ambas variables están capturando, en parte, el mismo fenómeno.</li>
<li>Riesgo práctico: si ambas entran juntas al modelo, los coeficientes pueden volverse menos estables y más difíciles de interpretar.</li>
<li>Regla didáctica: correlación cercana a 0 implica bajo riesgo; correlación moderada exige revisar VIF; correlación alta casi obliga a validar colinealidad y evaluar simplificación.</li>
</ul>
</div>
<div id="380dcce0" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:55.890334Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:55.890164Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:55.899482Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:55.898950Z&quot;}}" data-execution_count="41">
<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;"># Etapa 5: cuantificar redundancia entre predictores con VIF</span></span>
<span id="cb16-2">X_vif_demo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sm.add_constant(df_demo[preds])</span>
<span id="cb16-3">vif_demo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb16-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variable"</span>: X_vif_demo.columns,</span>
<span id="cb16-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>: [variance_inflation_factor(X_vif_demo.values, i) <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>(X_vif_demo.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])]</span>
<span id="cb16-6">})</span>
<span id="cb16-7"></span>
<span id="cb16-8">display(vif_demo.sort_values(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>, ascending<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="cb16-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;">"Guia rapida: VIF &lt; 5 usualmente aceptable; 5-10 zona de alerta; &gt; 10 problema serio."</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">variable</th>
<th data-quarto-table-cell-role="th">VIF</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>const</td>
<td>46.990296</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>ingreso</td>
<td>4.132227</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">5</th>
<td>gasto_electrico_base</td>
<td>4.119082</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">2</th>
<td>tamano_hogar</td>
<td>1.007616</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>aislamiento</td>
<td>1.004502</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">6</th>
<td>temperatura</td>
<td>1.002103</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">3</th>
<td>edad_vivienda</td>
<td>1.000809</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Guia rapida: VIF &lt; 5 usualmente aceptable; 5-10 zona de alerta; &gt; 10 problema serio.</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 5 (VIF y colinealidad)</strong></p>
<ul>
<li>El VIF de ingreso y gasto_electrico_base confirma lo visto en correlación: hay solapamiento de información.</li>
<li>Aunque no parece un caso extremo, sí es suficiente para advertir que la interpretación simultánea de ambos coeficientes debe hacerse con cuidado.</li>
<li>Conclusión metodológica: correlación alta sugiere, VIF confirma el nivel del problema.</li>
</ul>
</div>
<div id="7e1e27a8" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:55.900938Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:55.900775Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:55.939564Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:55.938897Z&quot;}}" data-execution_count="42">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Etapa 6: validar no linealidad (lineal vs polinomial en temperatura)</span></span>
<span id="cb18-2">X_lin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"temperatura"</span>]]</span>
<span id="cb18-3">y_lin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>]</span>
<span id="cb18-4"></span>
<span id="cb18-5">m_lin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression().fit(X_lin, y_lin)</span>
<span id="cb18-6">r2_lin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> m_lin.score(X_lin, y_lin)</span>
<span id="cb18-7"></span>
<span id="cb18-8">poly <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PolynomialFeatures(degree<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>, include_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;">False</span>)</span>
<span id="cb18-9">X_poly <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> poly.fit_transform(X_lin)</span>
<span id="cb18-10">m_poly <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression().fit(X_poly, y_lin)</span>
<span id="cb18-11">r2_poly <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> m_poly.score(X_poly, y_lin)</span>
<span id="cb18-12"></span>
<span id="cb18-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"R2 lineal (temperatura -&gt; consumo): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>r2_lin<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="cb18-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"R2 polinomial grado 2:             </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>r2_poly<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="cb18-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;">"Si el polinomial mejora de forma clara, hay evidencia de curvatura."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>R2 lineal (temperatura -&gt; consumo): 0.014
R2 polinomial grado 2:             0.014
Si el polinomial mejora de forma clara, hay evidencia de curvatura.</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 6 (no linealidad)</strong></p>
<ul>
<li>La comparación lineal vs polinomial muestra si temperatura aporta curvatura útil.</li>
<li>Si el cambio en desempeño es pequeño, la relación puede tratarse como aproximadamente lineal para fines prácticos.</li>
<li>Si la mejora fuera clara, sería señal de incluir términos no lineales o transformaciones en el modelo final.</li>
<li>Conclusión para clase: no se asume no linealidad por intuición; se valida con evidencia comparativa.</li>
</ul>
</div>
<div id="6eb9abfc" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:55.941271Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:55.941048Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.032816Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.032257Z&quot;}}" data-execution_count="43">
<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;"># Etapa 7: validar heterogeneidad por segmento</span></span>
<span id="cb20-2">resumen_segmento <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"segmento"</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>].agg([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mean"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"median"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"std"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"count"</span>])</span>
<span id="cb20-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;">"Resumen por segmento:"</span>)</span>
<span id="cb20-4">display(resumen_segmento)</span>
<span id="cb20-5"></span>
<span id="cb20-6">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;">7</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb20-7">sns.boxplot(data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>df_demo, x<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;">"segmento"</span>, y<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;">"consumo_kwh"</span>)</span>
<span id="cb20-8">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Consumo por segmento"</span>)</span>
<span id="cb20-9">plt.show()</span>
<span id="cb20-10"></span>
<span id="cb20-11"><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 las medias/medianas difieren de forma consistente, hay heterogeneidad estructural."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Resumen por segmento:</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">mean</th>
<th data-quarto-table-cell-role="th">median</th>
<th data-quarto-table-cell-role="th">std</th>
<th data-quarto-table-cell-role="th">count</th>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">segmento</th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">rural</th>
<td>390.330223</td>
<td>382.678209</td>
<td>124.188189</td>
<td>153</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">urbano</th>
<td>462.614223</td>
<td>455.502952</td>
<td>117.755586</td>
<td>297</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/estadistica-fundamentos/02-analisis-multivariado/index_files/figure-html/cell-11-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Si las medias/medianas difieren de forma consistente, hay heterogeneidad estructural.</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 7 (heterogeneidad por segmento)</strong></p>
<ul>
<li>Las diferencias entre urbano y rural en media/mediana de consumo indican que no todo el comportamiento se explica igual para todos los grupos.</li>
<li>Conclusión analítica: existe heterogeneidad estructural; por tanto, el segmento puede ser variable relevante o puede justificar modelos con interacción.</li>
<li>Lección para estudiantes: promediar todo sin segmentar puede ocultar patrones importantes.</li>
</ul>
</div>
<div id="b14d2f1c" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.034417Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.034222Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.166923Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.166004Z&quot;}}" data-execution_count="44">
<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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Etapa 8: detectar outliers con IQR y revisar casos</span></span>
<span id="cb23-2">q1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>].quantile(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>)</span>
<span id="cb23-3">q3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_demo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>].quantile(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span>)</span>
<span id="cb23-4">iqr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> q3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> q1</span>
<span id="cb23-5">lim_inf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> q1 <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;">1.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> iqr</span>
<span id="cb23-6">lim_sup <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> q3 <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;">1.5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> iqr</span>
<span id="cb23-7"></span>
<span id="cb23-8">mask_out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (df_demo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> lim_inf) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> (df_demo[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> lim_sup)</span>
<span id="cb23-9">n_out <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;">int</span>(mask_out.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>())</span>
<span id="cb23-10">pct_out <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="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> n_out <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>(df_demo)</span>
<span id="cb23-11"></span>
<span id="cb23-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"Outliers detectados por IQR: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>n_out<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>pct_out<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-13"><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;">"Primeros casos para inspección contextual:"</span>)</span>
<span id="cb23-14">display(df_demo.loc[mask_out, [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"segmento"</span>, <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;">"temperatura"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>]].head(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>))</span>
<span id="cb23-15"></span>
<span id="cb23-16">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;">4</span>))</span>
<span id="cb23-17">sns.scatterplot(</span>
<span id="cb23-18">    data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>df_demo,</span>
<span id="cb23-19">    x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>df_demo.index,</span>
<span id="cb23-20">    y<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;">"consumo_kwh"</span>,</span>
<span id="cb23-21">    hue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>mask_out,</span>
<span id="cb23-22">    palette<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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"steelblue"</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"crimson"</span>},</span>
<span id="cb23-23">    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="cb23-24">)</span>
<span id="cb23-25">plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Outliers IQR resaltados"</span>)</span>
<span id="cb23-26">plt.xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Índice de observación"</span>)</span>
<span id="cb23-27">plt.legend(title<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;">"Outlier"</span>)</span>
<span id="cb23-28">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Outliers detectados por IQR: 10 (2.22%)
Primeros casos para inspección contextual:</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">segmento</th>
<th data-quarto-table-cell-role="th">ingreso</th>
<th data-quarto-table-cell-role="th">temperatura</th>
<th data-quarto-table-cell-role="th">consumo_kwh</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">18</th>
<td>urbano</td>
<td>2538.787656</td>
<td>21.959488</td>
<td>909.347068</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">36</th>
<td>urbano</td>
<td>2634.936971</td>
<td>18.557640</td>
<td>847.581914</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">37</th>
<td>urbano</td>
<td>878.806315</td>
<td>17.065044</td>
<td>948.831839</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">43</th>
<td>rural</td>
<td>3251.097441</td>
<td>24.611346</td>
<td>1445.817729</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">96</th>
<td>urbano</td>
<td>1553.545359</td>
<td>16.699184</td>
<td>863.513000</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">134</th>
<td>urbano</td>
<td>4299.768079</td>
<td>30.301488</td>
<td>726.822478</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">180</th>
<td>rural</td>
<td>1570.405241</td>
<td>22.073216</td>
<td>135.410652</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">263</th>
<td>rural</td>
<td>1816.872298</td>
<td>18.462113</td>
<td>158.588262</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">323</th>
<td>rural</td>
<td>1752.390752</td>
<td>25.020978</td>
<td>140.435608</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">444</th>
<td>urbano</td>
<td>2564.273788</td>
<td>15.801986</td>
<td>1499.488896</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/estadistica-fundamentos/02-analisis-multivariado/index_files/figure-html/cell-12-output-3.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div style="background-color:#fff8e6; border-left:6px solid #b7791f; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Etapa 8 (outliers con IQR)</strong></p>
<ul>
<li>El porcentaje detectado de outliers sugiere que hay casos extremos suficientes para revisar, pero no tantos como para invalidar todo el dataset.</li>
<li>Conclusión práctica: antes de eliminar puntos, distinguir entre error técnico y caso real extremo con valor analítico.</li>
<li>Decisión recomendada: documentar criterio de tratamiento de outliers y luego comparar métricas con y sin esos casos para medir impacto.</li>
</ul>
</div>
</section>
<section id="cierre-de-validación" class="level3">
<h3 class="anchored" data-anchor-id="cierre-de-validación">5.9.8 Cierre de validación</h3>
<blockquote class="blockquote">
<p>Si quieres priorizar la parte de correlación, el orden sugerido es: 1. Ejecutar Etapa 3 (objetivo vs predictores). 2. Ejecutar Etapa 4 (correlación entre predictores). 3. Ejecutar Etapa 5 (VIF).</p>
</blockquote>
<p>Con esas tres etapas puedes justificar si existe redundancia, qué variable aporta señal útil y dónde hay riesgo de interpretación inestable.</p>
</section>
</section>
<section id="supuestos-clave-en-regresión-múltiple" class="level2">
<h2 class="anchored" data-anchor-id="supuestos-clave-en-regresión-múltiple">6. Supuestos clave en regresión múltiple</h2>
<p>La regresión múltiple no se evalúa solo por el R2. Para interpretar coeficientes, p-valores e intervalos de confianza con rigor, hay supuestos que deben revisarse.</p>
<section id="linealidad" class="level3">
<h3 class="anchored" data-anchor-id="linealidad">6.1 Linealidad</h3>
<p>La relación esperada entre cada predictor y la respuesta (controlando los demás) debe ser aproximadamente lineal.</p>
<p>Si falla: aparecen patrones sistemáticos en residuos y sesgo en coeficientes.</p>
</section>
<section id="independencia-de-errores" class="level3">
<h3 class="anchored" data-anchor-id="independencia-de-errores">6.2 Independencia de errores</h3>
<p>Los residuos deben ser aproximadamente independientes entre observaciones.</p>
<p>Si falla: errores estándar mal estimados, pruebas t/F menos confiables.</p>
</section>
<section id="homoscedasticidad" class="level3">
<h3 class="anchored" data-anchor-id="homoscedasticidad">6.3 Homoscedasticidad</h3>
<p>La varianza de residuos debe ser parecida a lo largo del rango de predicción.</p>
<p>Si falla: puede no afectar tanto la predicción media, pero sí compromete inferencia (p-valores e intervalos).</p>
</section>
<section id="normalidad-aproximada-de-residuos" class="level3">
<h3 class="anchored" data-anchor-id="normalidad-aproximada-de-residuos">6.4 Normalidad aproximada de residuos</h3>
<p>No es el supuesto más crítico para predecir, pero sí para inferencia clásica, sobre todo en muestras pequeñas.</p>
<p>Si falla con fuerza: intervalos y contrastes pueden ser inestables.</p>
</section>
<section id="baja-multicolinealidad" class="level3">
<h3 class="anchored" data-anchor-id="baja-multicolinealidad">6.5 Baja multicolinealidad</h3>
<p>Los predictores no deben ser casi copias entre sí.</p>
<p>Si falla: coeficientes inestables, signos que cambian entre muestras y mayor incertidumbre en cada beta.</p>
</section>
<section id="especificación-del-modelo" class="level3">
<h3 class="anchored" data-anchor-id="especificación-del-modelo">6.6 Especificación del modelo</h3>
<p>El modelo debe incluir variables relevantes y forma funcional razonable (por ejemplo, incluir no linealidad si existe).</p>
<p>Si falla: sesgo por variable omitida o mala forma del modelo.</p>
<p>Idea docente clave: un modelo puede tener buen R2 y aun así tener problemas de interpretación si no cumple supuestos básicos.</p>
<p>A partir de aquí volvemos al dataset de energía residencial de la sección 3 (<code>df</code>, con <code>temperatura</code>, <code>ocupantes</code>, <code>area_m2</code>, <code>aislamiento</code> y <code>electrodomesticos</code>) — el dataset de las Etapas 1-8 (<code>df_demo</code>) fue solo para ilustrar los fenómenos de exploración multivariada, y ya cumplió su función. Ahora construyes el modelo completo con inferencia formal (statsmodels), VIF, evaluación predictiva y diagnóstico de residuos.</p>
<div id="1c155525" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.168945Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.168785Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.181033Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.180624Z&quot;}}" data-execution_count="45">
<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="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Separación train/test y ajuste con statsmodels para inferencia</span></span>
<span id="cb25-2">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df.drop(columns<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;">"consumo_kwh"</span>])</span>
<span id="cb25-3">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"consumo_kwh"</span>]</span>
<span id="cb25-4"></span>
<span id="cb25-5">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-6">    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;">24</span></span>
<span id="cb25-7">)</span>
<span id="cb25-8"></span>
<span id="cb25-9">X_train_sm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sm.add_constant(X_train)</span>
<span id="cb25-10">modelo_ols <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sm.OLS(y_train, X_train_sm).fit()</span>
<span id="cb25-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(modelo_ols.summary())</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>                            OLS Regression Results                            
==============================================================================
Dep. Variable:            consumo_kwh   R-squared:                       0.823
Model:                            OLS   Adj. R-squared:                  0.821
Method:                 Least Squares   F-statistic:                     367.6
Date:                Thu, 27 Aug 2026   Prob (F-statistic):          6.43e-146
Time:                        23:12:33   Log-Likelihood:                -1875.2
No. Observations:                 400   AIC:                             3762.
Df Residuals:                     394   BIC:                             3786.
Df Model:                           5                                         
Covariance Type:            nonrobust                                         
=====================================================================================
                        coef    std err          t      P&gt;|t|      [0.025      0.975]
-------------------------------------------------------------------------------------
const               161.9641      9.716     16.670      0.000     142.862     181.066
temperatura          -1.8394      0.325     -5.658      0.000      -2.479      -1.200
ocupantes            18.9569      0.808     23.457      0.000      17.368      20.546
area_m2               1.8394      0.062     29.560      0.000       1.717       1.962
aislamiento         -58.7356      5.689    -10.325      0.000     -69.919     -47.552
electrodomesticos     8.9760      0.511     17.566      0.000       7.971       9.981
==============================================================================
Omnibus:                        1.336   Durbin-Watson:                   1.889
Prob(Omnibus):                  0.513   Jarque-Bera (JB):                1.250
Skew:                          -0.137   Prob(JB):                        0.535
Kurtosis:                       3.015   Cond. No.                         686.
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.</code></pre>
</div>
</div>
</section>
<section id="interpretación-detallada-de-la-salida-ols-ejemplo-de-clase" class="level3" style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:14px 16px; border-radius:8px;">
<h3 class="anchored" data-anchor-id="interpretación-detallada-de-la-salida-ols-ejemplo-de-clase">Interpretación detallada de la salida OLS (ejemplo de clase)</h3>
<p><strong>1) Calidad global del modelo</strong> - <strong>R-squared = 0.823</strong>: el modelo explica 82.3% de la variabilidad de <code>consumo_kwh</code>. - <strong>Adj. R-squared = 0.821</strong>: ajuste alto y muy cercano a R2, sin señal fuerte de sobreparametrización. - <strong>F-statistic = 367.6</strong> y <strong>Prob(F) = 6.43e-146</strong>: en conjunto, los predictores aportan explicación estadísticamente significativa.</p>
<p><strong>2) Tamaño muestral y grados de libertad</strong> - <strong>No.&nbsp;Observations = 400</strong>: se ajustó con 400 observaciones. - <strong>Df Model = 5</strong>: hay cinco predictores en el modelo. - <strong>Df Residuals = 394</strong>: consistente con 400 - 5 - 1 (intercepto).</p>
<p><strong>3) Coeficientes (interpretación ceteris paribus)</strong> - <strong>const = 161.9641</strong>: consumo esperado cuando los predictores valen 0 (interpretación contextual limitada). - <strong>temperatura = -1.8394</strong>: al aumentar 1 unidad de temperatura, el consumo disminuye ~1.84 unidades, manteniendo lo demás constante. - <strong>ocupantes = 18.9569</strong>: cada ocupante adicional aumenta el consumo en ~18.96 unidades. - <strong>area_m2 = 1.8394</strong>: cada m2 adicional aumenta consumo en ~1.84 unidades. - <strong>aislamiento = -58.7356</strong>: mayor aislamiento reduce consumo de forma importante. - <strong>electrodomesticos = 8.9760</strong>: cada equipo adicional aumenta el consumo en ~8.98 unidades.</p>
<p><strong>4) Significancia individual de predictores</strong> - Todos los p-valores reportados son ~0.000 (prácticamente &lt; 0.001). - Los intervalos de confianza al 95% no cruzan 0 en ningún coeficiente. - Lectura: cada predictor muestra evidencia de aporte estadístico en presencia de los demás.</p>
<p><strong>5) Diagnósticos de residuos y supuestos</strong> - <strong>Durbin-Watson = 1.889</strong>: cercano a 2, sin evidencia fuerte de autocorrelación residual. - <strong>Omnibus p = 0.513</strong> y <strong>JB p = 0.535</strong>: no hay evidencia para rechazar normalidad de residuos. - <strong>Skew = -0.137</strong> y <strong>Kurtosis = 3.015</strong>: forma residual bastante cercana a normalidad.</p>
<p><strong>6) Complejidad y comparación de modelos</strong> - <strong>AIC = 3762</strong> y <strong>BIC = 3786</strong>: útiles para comparar con modelos alternativos; menor valor indica mejor equilibrio ajuste-complejidad.</p>
<p><strong>7) Señal de colinealidad / condición numérica</strong> - <strong>Cond. No.&nbsp;= 686</strong>: sugiere revisar escalas y posible colinealidad moderada. - No implica por sí solo un problema grave, pero justifica complementar con VIF y chequeo de estabilidad.</p>
<p><strong>8) Nota de inferencia</strong> - <code>Covariance Type: nonrobust</code> indica que los errores estándar asumen homoscedasticidad correctamente especificada. - Si sospechas heteroscedasticidad, conviene contrastar con errores robustos (por ejemplo HC3).</p>
<p><strong>Cierre didáctico</strong> El modelo luce fuerte en ajuste global y consistente en signos/efectos. La lectura profesional no termina en R2: siempre se cierra con diagnóstico de supuestos, colinealidad y estabilidad inferencial.</p>
</section>
</section>
<section id="multicolinealidad-y-vif" class="level2">
<h2 class="anchored" data-anchor-id="multicolinealidad-y-vif">7. Multicolinealidad y VIF</h2>
<p>La <strong>multicolinealidad</strong> es el solapamiento de información entre predictores: varias variables explicativas aportan casi la misma señal dentro del modelo. El <strong>VIF</strong> (Variance Inflation Factor) es el indicador que cuantifica ese problema, midiendo cuánto se infla la varianza de cada coeficiente por depender linealmente de los demás predictores. Sí, está relacionado con la <strong>correlación</strong>: correlaciones altas entre predictores suelen ser una alerta inicial, pero el VIF es más completo porque evalúa la colinealidad conjunta (no solo pares aislados).</p>
<p>Diferencia clave: la <strong>correlación</strong> describe asociación lineal entre dos variables a la vez (visión bivariada), mientras que el <strong>VIF</strong> evalúa para cada predictor cuánta redundancia tiene respecto al conjunto de todos los demás predictores (visión multivariada). Por eso, puede haber casos con correlaciones por pares moderadas pero VIF elevado, si la combinación de varias variables juntas explica casi la misma información.</p>
<section id="por-qué-ocurre" class="level3">
<h3 class="anchored" data-anchor-id="por-qué-ocurre">7.1 Por qué ocurre</h3>
<ul>
<li>Variables que miden casi el mismo fenómeno (ejemplo: ingreso y gasto base).</li>
<li>Variables derivadas entre sí.</li>
<li>Escenarios donde varias variables crecen/disminuyen juntas por diseño del proceso.</li>
</ul>
</section>
<section id="qué-problema-genera" class="level3">
<h3 class="anchored" data-anchor-id="qué-problema-genera">7.2 Qué problema genera</h3>
<ul>
<li>Coeficientes inestables: cambian mucho entre muestras parecidas.</li>
<li>Errores estándar inflados: baja precisión en cada beta.</li>
<li>p-valores menos informativos para decidir qué variable “importa”.</li>
<li>Signos contraintuitivos en algunos coeficientes.</li>
</ul>
</section>
<section id="qué-no-hace-la-multicolinealidad" class="level3">
<h3 class="anchored" data-anchor-id="qué-no-hace-la-multicolinealidad">7.3 Qué NO hace la multicolinealidad</h3>
<ul>
<li>No significa automáticamente que el modelo prediga mal.</li>
<li>No implica que haya error en los datos.</li>
<li>No invalida por completo el ajuste global (R2 puede seguir alto).</li>
</ul>
</section>
<section id="vif-como-herramienta-práctica" class="level3">
<h3 class="anchored" data-anchor-id="vif-como-herramienta-práctica">7.4 VIF como herramienta práctica</h3>
<p>El <strong>VIF</strong> (Variance Inflation Factor) cuantifica cuánto se infla la varianza de un coeficiente por colinealidad con los demás predictores.</p>
<p>Regla orientativa (no absoluta): - <strong>VIF &lt; 5</strong>: zona normalmente aceptable. - <strong>5 &lt;= VIF &lt; 10</strong>: zona de alerta, revisar con criterio. - <strong>VIF &gt;= 10</strong>: riesgo alto de inestabilidad interpretativa.</p>
</section>
<section id="cómo-decidir-en-claseproyecto" class="level3">
<h3 class="anchored" data-anchor-id="cómo-decidir-en-claseproyecto">7.5 Cómo decidir en clase/proyecto</h3>
<ol type="1">
<li>Mirar pares de correlación altos entre predictores.</li>
<li>Confirmar con VIF.</li>
<li>Si hay problema:
<ul>
<li>quitar o combinar variables redundantes,</li>
<li>usar regularización (Ridge/Lasso),</li>
<li>priorizar interpretabilidad según objetivo del estudio.</li>
</ul></li>
</ol>
<p>Idea clave: en análisis explicativo, la multicolinealidad es sobre todo un problema de <strong>interpretación de coeficientes</strong>, no solo de ajuste.</p>
<div style="background-color:#e9f7ef; border-left:6px solid #2f855a; padding:12px 14px; border-radius:8px;">
<p><strong>Frase clave</strong></p>
<p>“la correlación mira relaciones de a pares; el VIF cuantifica la colinealidad de una variable frente al bloque completo de predictores.”</p>
</div>
<div id="a3ee4ceb" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.183165Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.183005Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.195369Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.194706Z&quot;}}" data-execution_count="46">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Cálculo e interpretación práctica de VIF</span></span>
<span id="cb27-2">X_vif <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sm.add_constant(X_train).copy()</span>
<span id="cb27-3"></span>
<span id="cb27-4">vif_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb27-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variable"</span>: X_vif.columns,</span>
<span id="cb27-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>: [variance_inflation_factor(X_vif.values, i) <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>(X_vif.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])]</span>
<span id="cb27-7">})</span>
<span id="cb27-8"></span>
<span id="cb27-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># El intercepto no se interpreta para colinealidad, se excluye en el semaforo.</span></span>
<span id="cb27-10">vif_eval <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> vif_df[vif_df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variable"</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;">"const"</span>].copy()</span>
<span id="cb27-11"></span>
<span id="cb27-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> clasificar_vif(v):</span>
<span id="cb27-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> v <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;">5</span>:</span>
<span id="cb27-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"OK (&lt;5)"</span></span>
<span id="cb27-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> v <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;">10</span>:</span>
<span id="cb27-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alerta (5-10)"</span></span>
<span id="cb27-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alto (&gt;=10)"</span></span>
<span id="cb27-18"></span>
<span id="cb27-19">vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lectura"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(clasificar_vif)</span>
<span id="cb27-20">vif_eval <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> vif_eval.sort_values(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>, ascending<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>).reset_index(drop<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="cb27-21"></span>
<span id="cb27-22">display(vif_eval)</span>
<span id="cb27-23"></span>
<span id="cb27-24">n_alerta <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</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;">5</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()</span>
<span id="cb27-25">n_alto <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</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;">10</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()</span>
<span id="cb27-26"></span>
<span id="cb27-27"><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"Variables en alerta (VIF &gt;= 5): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>n_alerta<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="cb27-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"Variables en riesgo alto (VIF &gt;= 10): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>n_alto<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-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">variable</th>
<th data-quarto-table-cell-role="th">VIF</th>
<th data-quarto-table-cell-role="th">lectura</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>ocupantes</td>
<td>1.014488</td>
<td>OK (&lt;5)</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>temperatura</td>
<td>1.010758</td>
<td>OK (&lt;5)</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>aislamiento</td>
<td>1.007479</td>
<td>OK (&lt;5)</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>electrodomesticos</td>
<td>1.005178</td>
<td>OK (&lt;5)</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>area_m2</td>
<td>1.003686</td>
<td>OK (&lt;5)</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Variables en alerta (VIF &gt;= 5): 0
Variables en riesgo alto (VIF &gt;= 10): 0</code></pre>
</div>
</div>
<div id="d396e9a0" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.197032Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.196809Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.201163Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.200567Z&quot;}}" data-execution_count="47">
<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;"># Conclusiones automáticas según resultados VIF</span></span>
<span id="cb29-2">vif_max <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>(vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>())</span>
<span id="cb29-3">var_max <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;">str</span>(vif_eval.loc[vif_eval[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"VIF"</span>].idxmax(), <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variable"</span>])</span>
<span id="cb29-4"></span>
<span id="cb29-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;">"Resumen automático de colinealidad:"</span>)</span>
<span id="cb29-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"- VIF máximo: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>vif_max<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 class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>var_max<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-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"- Variables en alerta (VIF &gt;= 5): </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;">int</span>(n_alerta)<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-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"- Variables en riesgo alto (VIF &gt;= 10): </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;">int</span>(n_alto)<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-9"></span>
<span id="cb29-10"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> n_alto <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>
<span id="cb29-11">    <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;">"Conclusión: hay multicolinealidad alta; revisar selección/transformación de variables antes de interpretar coeficientes."</span>)</span>
<span id="cb29-12"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> n_alerta <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>
<span id="cb29-13">    <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;">"Conclusión: existe colinealidad moderada; interpretar coeficientes con cautela y considerar regularización."</span>)</span>
<span id="cb29-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb29-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;">"Conclusión: no hay evidencia relevante de multicolinealidad según VIF; la interpretación de coeficientes es estable en este aspecto."</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Resumen automático de colinealidad:
- VIF máximo: 1.014 (ocupantes)
- Variables en alerta (VIF &gt;= 5): 0
- Variables en riesgo alto (VIF &gt;= 10): 0
Conclusión: no hay evidencia relevante de multicolinealidad según VIF; la interpretación de coeficientes es estable en este aspecto.</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Cap. 7 (Multicolinealidad y VIF)</strong></p>
<p><strong>Cómo se calcula e interpreta el VIF en este notebook</strong></p>
<ol type="1">
<li>Se toma la matriz de predictores de entrenamiento (<code>X_train</code>) y se agrega constante para el ajuste auxiliar.</li>
<li>Para cada predictor <img src="https://latex.codecogs.com/png.latex?X_j">, se estima una regresión auxiliar donde <img src="https://latex.codecogs.com/png.latex?X_j"> es respuesta y los demás predictores explican su variación.</li>
<li>De esa regresión se obtiene <img src="https://latex.codecogs.com/png.latex?R_j%5E2"> y se calcula: <img src="https://latex.codecogs.com/png.latex?VIF_j%20=%20%5Cfrac%7B1%7D%7B1-R_j%5E2%7D">.</li>
<li>Se repite para todos los predictores y se clasifican en:
<ul>
<li><code>OK (&lt;5)</code></li>
<li><code>Alerta (5-10)</code></li>
<li><code>Alto (&gt;=10)</code></li>
</ul></li>
</ol>
<p><strong>Lectura de resultados obtenidos</strong></p>
<ul>
<li>VIF máximo observado: <strong>1.014</strong> (variable <code>ocupantes</code>).</li>
<li>Variables en alerta (<img src="https://latex.codecogs.com/png.latex?VIF%20%5Cgeq%205">): <strong>0</strong>.</li>
<li>Variables en riesgo alto (<img src="https://latex.codecogs.com/png.latex?VIF%20%5Cgeq%2010">): <strong>0</strong>.</li>
</ul>
<p><strong>Conclusión metodológica</strong></p>
<p>No hay evidencia relevante de multicolinealidad en este modelo. Por tanto, la interpretación de coeficientes es estable desde el punto de vista de colinealidad. Se puede continuar con el conjunto actual de predictores, manteniendo monitoreo de VIF si se agregan nuevas variables o interacciones.</p>
</div>
</section>
</section>
<section id="evaluación-predictiva" class="level2">
<h2 class="anchored" data-anchor-id="evaluación-predictiva">8. Evaluación predictiva</h2>
<p>La evaluación predictiva responde dos preguntas: 1. ¿Qué tan grande es el error en unidades reales? 2. ¿Qué tan estable es el desempeño cuando cambia la muestra?</p>
<p>Primero definimos el error por observación (residuo de predicción):</p>
<p><img src="https://latex.codecogs.com/png.latex?e_i%20=%20y_i%20-%20%5Chat%7By%7D_i"></p>
<p>Con esos residuos, las métricas principales son:</p>
<ul>
<li><p><strong>MAE</strong> (Mean Absolute Error): <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BMAE%7D%20=%20%5Cfrac%7B1%7D%7Bn%7D%5Csum_%7Bi=1%7D%5E%7Bn%7D%7Cy_i%20-%20%5Chat%7By%7D_i%7C"></p></li>
<li><p><strong>MSE</strong> (Mean Squared Error): <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BMSE%7D%20=%20%5Cfrac%7B1%7D%7Bn%7D%5Csum_%7Bi=1%7D%5E%7Bn%7D(y_i%20-%20%5Chat%7By%7D_i)%5E2"></p></li>
<li><p><strong>RMSE</strong> (Root Mean Squared Error): <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BRMSE%7D%20=%20%5Csqrt%7B%5Cfrac%7B1%7D%7Bn%7D%5Csum_%7Bi=1%7D%5E%7Bn%7D(y_i%20-%20%5Chat%7By%7D_i)%5E2%7D%20=%20%5Csqrt%7B%5Ctext%7BMSE%7D%7D"></p></li>
<li><p><strong>R2</strong> (coeficiente de determinación): <img src="https://latex.codecogs.com/png.latex?R%5E2%20=%201%20-%20%5Cfrac%7B%5Csum_%7Bi=1%7D%5E%7Bn%7D(y_i%20-%20%5Chat%7By%7D_i)%5E2%7D%7B%5Csum_%7Bi=1%7D%5E%7Bn%7D(y_i%20-%20%5Cbar%7By%7D)%5E2%7D"></p></li>
</ul>
<p>Interpretación conceptual: - <strong>MAE</strong>: error promedio en unidades originales; fácil de explicar a negocio/política pública. - <strong>MSE</strong>: error cuadrático promedio; amplifica errores grandes y es muy útil para comparar modelos durante optimización matemática. - <strong>RMSE</strong>: raíz del MSE; conserva la sensibilidad a errores grandes pero vuelve a la escala original de la variable objetivo. - <strong>R2</strong>: proporción de variabilidad explicada; útil para comparar ajuste global.</p>
<p>La <strong>validación cruzada</strong> complementa la foto de test único: en lugar de depender de una sola partición, mide robustez en varios pliegues.</p>
<p>Idea clave: no conviene decidir con una sola métrica. Un modelo puede tener buen R2 y aun así un error absoluto demasiado alto para el contexto de decisión.</p>
<section id="guía-rápida-de-lectura-de-métricas" class="level3">
<h3 class="anchored" data-anchor-id="guía-rápida-de-lectura-de-métricas">Guía rápida de lectura de métricas</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
</colgroup>
<thead>
<tr class="header">
<th>Métrica</th>
<th>Qué penaliza más</th>
<th>Cuándo priorizarla</th>
<th>Si el valor es X, tener cuidado porque probablemente significa…</th>
<th>Qué se debería verificar / hacer / comparar</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>MAE</td>
<td>Penaliza todos los errores de forma lineal</td>
<td>Cuando quieres una medida robusta y fácil de comunicar en unidades reales</td>
<td><strong>MAE alto respecto a la escala de y</strong>: el error promedio ya es grande para la decisión práctica. <strong>MAE bajo</strong>: error promedio manejable.</td>
<td>Verificar MAE contra una tolerancia de negocio/operación (ej.: porcentaje del valor medio de y) y comparar con baseline de la media.</td>
</tr>
<tr class="even">
<td>MSE</td>
<td>Penaliza cuadráticamente, castiga fuerte los errores grandes</td>
<td>Cuando quieres sensibilidad alta a outliers y función de costo para optimización</td>
<td><strong>MSE muy alto</strong>: existen errores grandes que dominan el desempeño. <strong>MSE bajo</strong>: menos impacto de errores extremos.</td>
<td>Revisar observaciones con error grande, detectar outliers y comparar antes/después de limpieza o transformaciones.</td>
</tr>
<tr class="odd">
<td>RMSE</td>
<td>Penaliza más fuerte los errores grandes (vía cuadrado) y vuelve a escala original</td>
<td>Cuando los errores extremos son costosos y necesitas interpretación en unidades reales</td>
<td><strong>RMSE mucho mayor que MAE</strong>: hay cola de errores grandes y conviene revisar outliers/no linealidad. <strong>RMSE cercano a MAE</strong>: error más homogéneo.</td>
<td>Comparar RMSE vs MAE y revisar residuales: si RMSE &gt;&gt; MAE, verificar no linealidad, segmentación o variables omitidas.</td>
</tr>
<tr class="even">
<td>R2</td>
<td>No mide error absoluto; mide varianza explicada</td>
<td>Cuando comparas ajuste global entre modelos sobre el mismo problema</td>
<td><strong>R2 cercano a 1</strong>: buena explicación global. <strong>R2 cerca de 0</strong>: el modelo mejora poco frente a predecir la media. <strong>R2 negativo</strong>: peor que la referencia de la media.</td>
<td>Comparar R2 en train/test/CV y con modelos alternativos; confirmar que la mejora sea estable y no sobreajuste.</td>
</tr>
</tbody>
</table>
<p>Regla práctica docente: interpreta MAE/RMSE siempre en la unidad real de la variable objetivo y valida estabilidad con CV, no solo con una sola partición de test.</p>
<div id="941b0260" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.202820Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.202666Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.223665Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.223181Z&quot;}}" data-execution_count="48">
<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;"># Modelo base con sklearn + lectura de estabilidad</span></span>
<span id="cb31-2">lr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression()</span>
<span id="cb31-3">lr.fit(X_train, y_train)</span>
<span id="cb31-4">pred_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> lr.predict(X_test)</span>
<span id="cb31-5"></span>
<span id="cb31-6">mae <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mean_absolute_error(y_test, pred_test)</span>
<span id="cb31-7">rmse <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.sqrt(mean_squared_error(y_test, pred_test))</span>
<span id="cb31-8">r2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> r2_score(y_test, pred_test)</span>
<span id="cb31-9"></span>
<span id="cb31-10">cv_r2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cross_val_score(lr, X, y, cv<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>, scoring<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;">"r2"</span>)</span>
<span id="cb31-11">cv_r2_mean <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>(cv_r2.mean())</span>
<span id="cb31-12">cv_r2_std <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>(cv_r2.std())</span>
<span id="cb31-13"></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"MAE : </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mae<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="cb31-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"RMSE: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>rmse<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="cb31-16"><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"R2 test: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>r2<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="cb31-17"><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"R2 CV (media): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>cv_r2_mean<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="cb31-18"><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"R2 CV (desv):  </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>cv_r2_std<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="cb31-19"></span>
<span id="cb31-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Brecha test vs CV como chequeo rapido de estabilidad</span></span>
<span id="cb31-21">gap_test_cv <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> r2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> cv_r2_mean</span>
<span id="cb31-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"Brecha R2 test - R2 CV media: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>gap_test_cv<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-stdout">
<pre><code>MAE : 22.40
RMSE: 27.66
R2 test: 0.820
R2 CV (media): 0.808
R2 CV (desv):  0.037
Brecha R2 test - R2 CV media: +0.012</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Cap. 8 (Evaluación predictiva)</strong></p>
<ul>
<li>En esta corrida: MAE=22.40 y RMSE=27.66 (error en la escala real de consumo_kwh); R2 test=0.820, el modelo explica el 82% de la variabilidad.</li>
<li>R2 CV (media)=0.808 con desviación=0.037 entre folds. La brecha test-CV es de apenas +0.012.</li>
<li>Brecha pequeña: el modelo generaliza de forma consistente, sin señal de sobreajuste al conjunto de test.</li>
</ul>
</div>
</section>
</section>
<section id="cuándo-usar-regularización" class="level2">
<h2 class="anchored" data-anchor-id="cuándo-usar-regularización">9. Cuándo usar regularización</h2>
<p><strong>Definición breve (antes del detalle):</strong> Regularizar significa entrenar el modelo minimizando no solo el error de ajuste, sino también una penalización por coeficientes grandes. En práctica, es una forma de controlar complejidad para reducir sobreajuste y mejorar generalización.</p>
<p>En palabras simples, así funciona el proceso matemático:</p>
<p><strong>Qué hace OLS (sin regularización)</strong> - Solo intenta minimizar el error de predicción. - Si hay ruido o variables muy parecidas, puede asignar coeficientes grandes e inestables para “perseguir” detalles de la muestra.</p>
<p><strong>Qué agrega la regularización</strong> - Además de minimizar error, agrega un “costo” por coeficientes grandes. - Eso obliga al modelo a preferir soluciones más sobrias.</p>
<hr>
<section id="ridge-penalización-l_2" class="level3">
<h3 class="anchored" data-anchor-id="ridge-penalización-l_2">Ridge (penalización <img src="https://latex.codecogs.com/png.latex?L_2">)</h3>
<p><strong>Idea en palabras:</strong> <em>encoge</em> todos los coeficientes, pero casi nunca los vuelve exactamente cero.</p>
<p>Qué hace en la práctica: 1. <strong>Recorta suavemente</strong> magnitudes grandes. 2. <strong>Reparte mejor</strong> el peso cuando hay variables correlacionadas. 3. <strong>Estabiliza</strong> coeficientes entre distintas muestras. 4. <strong>No filtra variables</strong> de forma dura: normalmente todas quedan, pero con menos peso.</p>
<p>Si quieres una frase tipo aula: - Ridge es como bajar el volumen general del modelo, no apagar parlantes.</p>
<hr>
</section>
<section id="lasso-penalización-l_1" class="level3">
<h3 class="anchored" data-anchor-id="lasso-penalización-l_1">Lasso (penalización <img src="https://latex.codecogs.com/png.latex?L_1">)</h3>
<p><strong>Idea en palabras:</strong> <em>encoge</em> y además puede <strong>apagar</strong> algunos coeficientes (dejarlos en cero).</p>
<p>Qué hace en la práctica: 1. <strong>Recorta</strong> coeficientes. 2. <strong>Filtra variables</strong>: algunas quedan exactamente en 0. 3. <strong>Simplifica</strong> el modelo (selección automática de predictores). 4. Puede ser menos estable si hay muchas variables muy correlacionadas entre sí, porque “elige” algunas y descarta otras.</p>
<p>Frase tipo aula: - Lasso no solo baja volumen, también mutea algunos canales.</p>
<hr>
</section>
<section id="filtra-recorta-promedia" class="level3">
<h3 class="anchored" data-anchor-id="filtra-recorta-promedia">Filtra, recorta, promedia</h3>
<ul>
<li><strong>Ridge:</strong> recorta y estabiliza, no filtra duro.</li>
<li><strong>Lasso:</strong> recorta y filtra.</li>
<li><strong>Promediar:</strong> no es lo principal aquí; la validación cruzada sí promedia desempeño para elegir hiperparámetros (como <img src="https://latex.codecogs.com/png.latex?%5Calpha">).</li>
</ul>
<hr>
</section>
<section id="rol-de-alpha" class="level3">
<h3 class="anchored" data-anchor-id="rol-de-alpha">Rol de <img src="https://latex.codecogs.com/png.latex?%5Calpha"></h3>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Calpha"> pequeño: casi como OLS.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Calpha"> grande: más recorte.</li>
<li>En Ridge: más contracción global.</li>
<li>En Lasso: más coeficientes llevados a cero.</li>
</ul>
<p>Mensaje final para la sección: regularizar no busca maquillar resultados, busca reducir sensibilidad al ruido y mejorar generalización fuera de muestra.</p>
<div id="124ca0a4" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.226015Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.225724Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.284967Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.284344Z&quot;}}" data-execution_count="49">
<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;"># Comparación: OLS vs Ridge vs Lasso con validación cruzada</span></span>
<span id="cb33-2">modelos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb33-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"OLS"</span>: LinearRegression(),</span>
<span id="cb33-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ridge(alpha=1.0)"</span>: Pipeline([(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"scaler"</span>, StandardScaler()), (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span>, Ridge(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;">1.0</span>))]),</span>
<span id="cb33-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lasso(alpha=0.05)"</span>: Pipeline([(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"scaler"</span>, StandardScaler()), (<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m"</span>, Lasso(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.05</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;">10000</span>))]),</span>
<span id="cb33-6">}</span>
<span id="cb33-7"></span>
<span id="cb33-8">res_reg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb33-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> nombre, modelo <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> modelos.items():</span>
<span id="cb33-10">    scores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cross_val_score(modelo, X, y, cv<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>, scoring<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;">"r2"</span>)</span>
<span id="cb33-11">    res_reg.append({</span>
<span id="cb33-12">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"modelo"</span>: nombre,</span>
<span id="cb33-13">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r2_cv_mean"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(scores.mean()),</span>
<span id="cb33-14">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r2_cv_std"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(scores.std())</span>
<span id="cb33-15">    })</span>
<span id="cb33-16"></span>
<span id="cb33-17">res_reg_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(res_reg).sort_values(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r2_cv_mean"</span>, ascending<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>).reset_index(drop<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="cb33-18">display(res_reg_df)</span>
<span id="cb33-19"></span>
<span id="cb33-20">mejor_modelo <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;">str</span>(res_reg_df.loc[<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;">"modelo"</span>])</span>
<span id="cb33-21">mejor_r2 <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>(res_reg_df.loc[<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;">"r2_cv_mean"</span>])</span>
<span id="cb33-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"Mejor modelo por R2 CV medio: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>mejor_modelo<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>mejor_r2<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>


<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">modelo</th>
<th data-quarto-table-cell-role="th">r2_cv_mean</th>
<th data-quarto-table-cell-role="th">r2_cv_std</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>Ridge(alpha=1.0)</td>
<td>0.808210</td>
<td>0.037045</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>Lasso(alpha=0.05)</td>
<td>0.808183</td>
<td>0.037127</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>OLS</td>
<td>0.808125</td>
<td>0.037456</td>
</tr>
</tbody>
</table>

</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Mejor modelo por R2 CV medio: Ridge(alpha=1.0) (0.808)</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Cap. 9 (Regularización)</strong></p>
<ul>
<li>Comparación por validación cruzada (R2 CV medio): Ridge(alpha=1.0)=0.8082, Lasso(alpha=0.05)=0.8082, OLS=0.8081 — prácticamente empatados, diferencias en la 4ª-5ª cifra decimal.</li>
<li>Ridge quedó primero por un margen mínimo (0.0001 sobre Lasso, 0.0001 sobre OLS): no hay evidencia de que regularizar aporte una mejora real en este dataset.</li>
<li>Con VIF máximo de 1.014 (ver Cap. 7), no hay multicolinealidad que justifique Ridge, ni un exceso de variables que justifique la selección de Lasso: OLS sin regularizar es una elección razonable aquí.</li>
</ul>
</div>
</section>
</section>
<section id="diagnóstico-de-residuos-capítulo-clave" class="level2">
<h2 class="anchored" data-anchor-id="diagnóstico-de-residuos-capítulo-clave">10. Diagnóstico de residuos (capítulo clave)</h2>
<p>El residuo es la parte que el modelo no logra explicar:</p>
<p><img src="https://latex.codecogs.com/png.latex?e_i%20=%20y_i%20-%20%5Chat%7By%7D_i"></p>
<p>Mirar residuos permite detectar problemas que no se ven en una sola métrica de desempeño. Un modelo puede tener buen R2 y, aun así, mostrar fallas estructurales en residuos.</p>
<section id="qué-se-debe-revisar-versión-simple" class="level3">
<h3 class="anchored" data-anchor-id="qué-se-debe-revisar-versión-simple">Qué se debe revisar (versión simple)</h3>
<ol type="1">
<li><p><strong>Que los residuos estén alrededor de 0</strong> Si la mayoría está cerca de 0, el modelo no tiene sesgo fuerte.</p></li>
<li><p><strong>Que no haya patrón en residuo vs predicción</strong> Debe verse una nube desordenada. Si aparece curva, pendiente o forma clara, el modelo está dejando estructura sin explicar.</p></li>
<li><p><strong>Que la dispersión sea parecida en todo el rango</strong> Si al aumentar la predicción los residuos se abren como embudo, hay varianza no constante.</p></li>
<li><p><strong>Que no haya demasiados casos extremos</strong> Muchos residuos muy grandes pueden distorsionar resultados y conclusiones.</p></li>
<li><p><strong>Que la forma general sea razonable</strong> Con histograma y Q-Q plot revisamos si los residuos se parecen de forma aproximada a una distribución normal.</p></li>
</ol>
</section>
<section id="un-cuidado-importante-entrenamiento-vs.-prueba" class="level3">
<h3 class="anchored" data-anchor-id="un-cuidado-importante-entrenamiento-vs.-prueba">Un cuidado importante: entrenamiento vs.&nbsp;prueba</h3>
<p>Dos de los chequeos numéricos más comunes —la <strong>media de los residuos</strong> y la <strong>correlación entre predicción y residuo</strong>— dan exactamente 0 por construcción cuando se calculan sobre los mismos datos con los que se ajustó un modelo OLS con intercepto. No es que el modelo sea bueno: es una propiedad algebraica de mínimos cuadrados (las ecuaciones normales obligan a que los residuos sean ortogonales a las columnas de <img src="https://latex.codecogs.com/png.latex?X">, incluida la de unos). Por eso, esos dos chequeos solo aportan información real si se calculan sobre datos de <strong>prueba</strong>, que el modelo no vio al ajustarse.</p>
</section>
<section id="si-aparece-una-alerta-qué-hacer" class="level3">
<h3 class="anchored" data-anchor-id="si-aparece-una-alerta-qué-hacer">Si aparece una alerta, qué hacer</h3>
<ul>
<li>Probar transformaciones (por ejemplo log).</li>
<li>Agregar términos no lineales o interacciones.</li>
<li>Revisar outliers y calidad de datos.</li>
<li>Considerar segmentar el análisis o usar errores robustos.</li>
</ul>
<p>Idea clave: el diagnóstico de residuos conecta ajuste predictivo con validez estadística de la interpretación.</p>
<div id="18f702d6" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T04:11:56.286969Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T04:11:56.286758Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T04:11:56.602294Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T04:11:56.601722Z&quot;}}" data-execution_count="50">
<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;"># Diagnóstico de residuos: gráfico + resumen numérico</span></span>
<span id="cb35-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> statsmodels.stats.stattools <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> durbin_watson</span>
<span id="cb35-3"></span>
<span id="cb35-4">pred_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_ols.predict(X_train_sm)</span>
<span id="cb35-5">resid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_train <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pred_train</span>
<span id="cb35-6"></span>
<span id="cb35-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Prediccion y residuos sobre el conjunto de PRUEBA: el modelo no los vio al ajustarse,</span></span>
<span id="cb35-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># por eso son los unicos que permiten un chequeo no tautologico de media y correlacion (ver nota arriba).</span></span>
<span id="cb35-9">X_test_sm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sm.add_constant(X_test)</span>
<span id="cb35-10">pred_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_ols.predict(X_test_sm)</span>
<span id="cb35-11">resid_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pred_test</span>
<span id="cb35-12"></span>
<span id="cb35-13">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;">15</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>))</span>
<span id="cb35-14"></span>
<span id="cb35-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1) Residuo vs predicción</span></span>
<span id="cb35-16">axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].scatter(pred_train, resid, 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>)</span>
<span id="cb35-17">axes[<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;">"red"</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="cb35-18">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;">"Predicción"</span>)</span>
<span id="cb35-19">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;">"Residuo"</span>)</span>
<span id="cb35-20">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;">"Residuo vs predicción"</span>)</span>
<span id="cb35-21"></span>
<span id="cb35-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 2) Histograma de residuos</span></span>
<span id="cb35-23">sns.histplot(resid, kde<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>, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])</span>
<span id="cb35-24">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;">"Distribución de residuos"</span>)</span>
<span id="cb35-25">axes[<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;">"Residuo"</span>)</span>
<span id="cb35-26"></span>
<span id="cb35-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 3) Q-Q plot</span></span>
<span id="cb35-28">sm.qqplot(resid, line<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;">"45"</span>, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>axes[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>], fit<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="cb35-29">axes[<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;">"Q-Q plot de residuos"</span>)</span>
<span id="cb35-30"></span>
<span id="cb35-31">plt.tight_layout()</span>
<span id="cb35-32">plt.show()</span>
<span id="cb35-33"></span>
<span id="cb35-34"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Resumen numerico rapido (sobre train, para escala/forma) mas el chequeo no tautologico (sobre test)</span></span>
<span id="cb35-35">resid_mean <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>(resid.mean())</span>
<span id="cb35-36">resid_std <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>(resid.std())</span>
<span id="cb35-37">corr_pred_resid <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>(np.corrcoef(pred_train, resid)[<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="cb35-38">pct_extremos <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>((np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(resid) <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;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> resid_std).mean() <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="cb35-39">dw <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>(durbin_watson(resid))</span>
<span id="cb35-40"></span>
<span id="cb35-41">resid_test_mean <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>(resid_test.mean())</span>
<span id="cb35-42">corr_pred_resid_test <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>(np.corrcoef(pred_test, resid_test)[<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="cb35-43"></span>
<span id="cb35-44"><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 de residuos (train, ~0 por construccion, no es diagnostico): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resid_mean<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="cb35-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"Media de residuos (test, chequeo real):                          </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resid_test_mean<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="cb35-46"><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"Desv. estandar de residuos: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resid_std<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="cb35-47"><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"Correlacion prediccion-residuo (train, ~0 por construccion, no es diagnostico): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>corr_pred_resid<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="cb35-48"><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"Correlacion prediccion-residuo (test, chequeo real):                            </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>corr_pred_resid_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="cb35-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"% residuos extremos (|resid| &gt; 2*std): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>pct_extremos<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-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"Durbin-Watson: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dw<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="cb35-51"></span>
<span id="cb35-52"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Lectura automatica orientativa (usa el chequeo de test, el unico no tautologico)</span></span>
<span id="cb35-53"><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>(corr_pred_resid_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.2</span>:</span>
<span id="cb35-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;">"Alerta: hay dependencia notable entre prediccion y residuo en test; revisar especificacion."</span>)</span>
<span id="cb35-55"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb35-56">    <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;">"OK: no hay dependencia lineal fuerte entre prediccion y residuo en test."</span>)</span>
<span id="cb35-57"></span>
<span id="cb35-58"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pct_extremos <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;">8</span>:</span>
<span id="cb35-59">    <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;">"Alerta: porcentaje alto de residuos extremos; revisar outliers y no linealidad."</span>)</span>
<span id="cb35-60"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb35-61">    <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;">"OK: porcentaje de residuos extremos en rango razonable."</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/estadistica-fundamentos/02-analisis-multivariado/index_files/figure-html/cell-18-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Media de residuos (train, ~0 por construccion, no es diagnostico): 0.000
Media de residuos (test, chequeo real):                          2.371
Desv. estandar de residuos: 26.319
Correlacion prediccion-residuo (train, ~0 por construccion, no es diagnostico): -0.000
Correlacion prediccion-residuo (test, chequeo real):                            0.088
% residuos extremos (|resid| &gt; 2*std): 5.25%
Durbin-Watson: 1.889
OK: no hay dependencia lineal fuerte entre prediccion y residuo en test.
OK: porcentaje de residuos extremos en rango razonable.</code></pre>
</div>
</div>
<div style="background-color:#fff8e6; border-left:6px solid #b7791f; padding:12px 14px; border-radius:8px;">
<p><strong>Conclusiones Cap. 10 (Diagnóstico de residuos)</strong></p>
<p><strong>Definición explícita de Durbin-Watson</strong> - Durbin-Watson mide si los residuos consecutivos están correlacionados (autocorrelación). - Su rango aproximado es 0 a 4. - Cerca de 2: independencia razonable de errores (deseable). - Menor que 2: autocorrelación positiva. - Mayor que 2: autocorrelación negativa.</p>
<p><strong>Lectura de esta ejecución (qué significa y por qué es bueno)</strong></p>
<ol type="1">
<li><strong>Media de residuos (train) = 0.000 vs.&nbsp;media de residuos (test) = 2.371</strong></li>
</ol>
<ul>
<li>Significa: en train, la media da exactamente 0 por construcción de OLS (no es un hallazgo); el valor que sí informa es el de test, y ahí el error promedio es de apenas 2.4 unidades sobre un rango de consumo que va de cientos a miles de kWh.</li>
<li>Por qué es bueno: un sesgo promedio tan pequeño en datos no vistos indica que el modelo no está sistemáticamente sobreestimando ni subestimando fuera de la muestra de entrenamiento.</li>
</ul>
<ol start="2" type="1">
<li><strong>Desv. estándar de residuos = 26.319</strong></li>
</ol>
<ul>
<li>Significa: tamaño típico de la dispersión del error.</li>
<li>Por qué es bueno: en conjunto con R2 alto y buenos diagnósticos, sugiere un nivel de error razonable para este ejemplo.</li>
</ul>
<ol start="3" type="1">
<li><strong>Correlación predicción-residuo (train) = -0.000 vs.&nbsp;(test) = 0.088</strong></li>
</ol>
<ul>
<li>Significa: en train, esta correlación es cero por construcción (ortogonalidad de mínimos cuadrados), no un hallazgo; el valor que sí informa es el de test, y ahí sale 0.088 — muy por debajo del umbral de alerta (0.2).</li>
<li>Por qué es bueno: en datos que el modelo no vio al ajustarse, tampoco aparece una relación lineal apreciable entre lo que predice y su error, lo que reduce evidencia de patrón sistemático omitido.</li>
</ul>
<ol start="4" type="1">
<li><strong>% residuos extremos = 5.25%</strong></li>
</ol>
<ul>
<li>Significa: hay pocos casos con error muy grande (umbral 2*desv. estándar).</li>
<li>Por qué es bueno: no parece existir una cola extrema dominante que distorsione todo el modelo.</li>
</ul>
<ol start="5" type="1">
<li><strong>Durbin-Watson = 1.889</strong></li>
</ol>
<ul>
<li>Significa: valor cercano a 2, sin evidencia fuerte de autocorrelación residual.</li>
<li>Por qué es bueno: respalda mejor la validez de la inferencia estadística.</li>
</ul>
<ol start="6" type="1">
<li><strong>Mensajes automáticos: OK y OK</strong></li>
</ol>
<ul>
<li>Significa: el sistema no detecta, sobre el conjunto de prueba, dependencia lineal fuerte ni exceso de extremos bajo los umbrales definidos.</li>
<li>Por qué es bueno: confirma que, en chequeo básico sobre datos no vistos, la salud residual es adecuada.</li>
</ul>
<p><strong>Lectura de las gráficas</strong> - Residuo vs predicción: nube sin patrón claro y centrada en 0, lo cual es favorable. - Histograma: forma aproximadamente simétrica, compatible con normalidad aproximada. - Q-Q plot: puntos cercanos a la diagonal, con desviaciones leves aceptables en colas.</p>
<p><strong>Cierre docente</strong> - El diagnóstico residual de esta corrida es saludable: no hay alertas fuertes de sesgo, autocorrelación ni exceso de extremos. - Se puede continuar con interpretación del modelo, manteniendo monitoreo si se cambian variables o se usa otro dataset.</p>
</div>
</section>
</section>
<section id="guía-práctica-para-interpretar-resultados-paso-a-paso" class="level2">
<h2 class="anchored" data-anchor-id="guía-práctica-para-interpretar-resultados-paso-a-paso">11. Guía práctica para interpretar resultados (paso a paso)</h2>
<p>Usa esta guía cada vez que termines un modelo. La idea es responder: - qué tan bien predice, - si es estable, - y si se puede interpretar con confianza.</p>
<section id="paso-1-mirar-error-en-unidades-reales" class="level3">
<h3 class="anchored" data-anchor-id="paso-1-mirar-error-en-unidades-reales">Paso 1: mirar error en unidades reales</h3>
<p>Revisa <strong>MAE</strong> y <strong>RMSE</strong>. - Si son bajos para el contexto, el modelo es útil en términos prácticos. - Si RMSE es mucho mayor que MAE, hay errores grandes que debes investigar.</p>
</section>
<section id="paso-2-mirar-capacidad-explicativa" class="level3">
<h3 class="anchored" data-anchor-id="paso-2-mirar-capacidad-explicativa">Paso 2: mirar capacidad explicativa</h3>
<p>Revisa <strong>R2</strong> en test. - R2 alto: el modelo explica gran parte de la variabilidad. - R2 bajo: faltan variables, forma funcional o calidad de datos.</p>
</section>
<section id="paso-3-revisar-estabilidad" class="level3">
<h3 class="anchored" data-anchor-id="paso-3-revisar-estabilidad">Paso 3: revisar estabilidad</h3>
<p>Compara <strong>R2 test</strong> con <strong>R2 promedio de validación cruzada</strong>. - Si son parecidos, buena estabilidad. - Si hay brecha grande, posible sobreajuste o partición poco representativa.</p>
</section>
<section id="paso-4-revisar-salud-de-residuos" class="level3">
<h3 class="anchored" data-anchor-id="paso-4-revisar-salud-de-residuos">Paso 4: revisar salud de residuos</h3>
<p>Confirma 4 cosas mínimas: 1. residuos centrados en 0, 2. sin patrón claro en residuo vs predicción, 3. dispersión parecida (sin embudo fuerte), 4. porcentaje de extremos razonable.</p>
</section>
<section id="paso-5-revisar-independencia-de-errores" class="level3">
<h3 class="anchored" data-anchor-id="paso-5-revisar-independencia-de-errores">Paso 5: revisar independencia de errores</h3>
<p>Mira <strong>Durbin-Watson</strong>. - Cerca de 2: bien (independencia razonable). - Muy lejos de 2: alerta de autocorrelación.</p>
</section>
<section id="paso-6-revisar-multicolinealidad" class="level3">
<h3 class="anchored" data-anchor-id="paso-6-revisar-multicolinealidad">Paso 6: revisar multicolinealidad</h3>
<p>Mira <strong>VIF</strong> de predictores. - VIF &lt; 5: normalmente aceptable. - 5 a 10: alerta. - &gt;= 10: problema serio de interpretación.</p>
</section>
<section id="paso-7-decidir-acción" class="level3">
<h3 class="anchored" data-anchor-id="paso-7-decidir-acción">Paso 7: decidir acción</h3>
<ul>
<li>Si métricas y diagnósticos son buenos: reportar y usar.</li>
<li>Si predice bien pero falla diagnóstico: ajustar modelo (transformaciones, no linealidad, segmentación, robustez).</li>
<li>Si predice mal: volver a variables, datos y especificación.</li>
</ul>
</section>
<section id="semáforo-de-decisión-rápido" class="level3">
<h3 class="anchored" data-anchor-id="semáforo-de-decisión-rápido">Semáforo de decisión rápido</h3>
<ul>
<li><strong>Verde</strong>: R2 estable + residuos sanos + VIF sano.</li>
<li><strong>Amarillo</strong>: predice razonable, pero con alguna alerta diagnóstica.</li>
<li><strong>Rojo</strong>: baja estabilidad o diagnósticos con fallas fuertes; no interpretar coeficientes sin corregir.</li>
</ul>
</section>
<section id="plantilla-corta-mejorada-lista-para-copiar" class="level3">
<h3 class="anchored" data-anchor-id="plantilla-corta-mejorada-lista-para-copiar">Plantilla corta mejorada (lista para copiar)</h3>
<ol type="1">
<li><p><strong>Desempeño</strong> “MAE = <strong><em>, RMSE = </em></strong>, R2 test = <strong><em>. Interpretación: el error en escala real es </em></strong> y la capacidad explicativa es ___.”</p></li>
<li><p><strong>Estabilidad</strong> “R2 CV medio = <strong><em>, desviación CV = </em></strong>, brecha (R2 test - R2 CV) = <strong><em>. Interpretación: la estabilidad es </em></strong> (alta/media/baja).”</p></li>
<li><p><strong>Diagnóstico residual</strong> “Media resid = <strong><em>, corr(pred,resid) = </em></strong>, % extremos = <strong><em>, Durbin-Watson = </em></strong>. Interpretación: residuos ___ (saludables / con alertas en ___).”</p></li>
<li><p><strong>Colinealidad</strong> “VIF max = ___ (variable: <strong><em>). Interpretación: colinealidad </em></strong> (baja/moderada/alta).”</p></li>
<li><p><strong>Decisión final</strong> “Decisión: ___ (usar / ajustar / replantear). Justificación: se decide esto porque ___.”</p></li>
</ol>
</section>
<section id="criterio-de-cierre-rápido" class="level3">
<h3 class="anchored" data-anchor-id="criterio-de-cierre-rápido">Criterio de cierre rápido</h3>
<ul>
<li>Si 4 o 5 bloques salen favorables: modelo útil para reporte final.</li>
<li>Si 2 o más bloques salen en alerta: ajustar antes de cerrar conclusiones.</li>
</ul>
<p>Idea clave: interpretar un modelo no es mirar un solo número; es seguir una guía completa y consistente.</p>
</section>
</section>
<section id="cierre" class="level2">
<h2 class="anchored" data-anchor-id="cierre">12. Cierre</h2>
<p>Este notebook deja una base clara de análisis multivariado:</p>
<ul>
<li>marco teórico breve,</li>
<li>flujo de trabajo reproducible,</li>
<li>ejemplo alternativo al contexto comercial,</li>
<li>herramientas para inferencia, predicción y diagnóstico.</li>
</ul>
<p>Siguiente paso sugerido: adaptar este esqueleto a un dataset real del curso y comparar un modelo lineal simple frente a uno multivariado.</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>estadistica</category>
  <category>analisis-multivariado</category>
  <category>regresion-multiple</category>
  <guid>https://biitt.com/es/blog/estadistica-fundamentos/02-analisis-multivariado/</guid>
  <pubDate>Thu, 27 Aug 2026 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Análisis Avanzado de Datos — 1. Regresión y regularización (Ridge y Lasso)</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/estadistica-fundamentos/03-regresion-regularizacion/</link>
  <description><![CDATA[ 




<section id="análisis-avanzado-de-datos-1.-regresión-y-regularización-ridge-y-lasso" class="level1">
<h1>Análisis Avanzado de Datos — 1. Regresión y regularización (Ridge y Lasso)</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="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 id="por-qué-la-regresión-lineal-se-queda-corta" class="level2">
<h2 class="anchored" data-anchor-id="por-qué-la-regresión-lineal-se-queda-corta">¿Por qué la regresión lineal se queda corta?</h2>
<p>La regresión lineal es, probablemente, el primer modelo que aprendiste en ciencia de datos. Es simple, interpretable y funciona sorprendentemente bien en muchos problemas reales. Pero tiene puntos débiles que se vuelven críticos en la práctica:</p>
<ul>
<li>Cuando hay <strong>muchas variables predictoras</strong>, algunas correlacionadas entre sí (multicolinealidad), los coeficientes se vuelven inestables: pequeños cambios en los datos producen coeficientes muy distintos.</li>
<li>Cuando el modelo tiene <strong>más flexibilidad de la necesaria</strong> (muchas variables, o términos polinomiales), tiende a <strong>memorizar el ruido</strong> del conjunto de entrenamiento en lugar de aprender el patrón real — esto se llama <strong>sobreajuste</strong> (overfitting).</li>
<li>No tienes forma de decirle al modelo qué variables no aportan, para que las ignore.</li>
</ul>
<p>La solución a estos tres problemas tiene un nombre: <strong>regularización</strong>. En este artículo vas a construir la intuición completa, con código ejecutable de principio a fin, sobre las dos formas de regularización más usadas en regresión: <strong>Ridge</strong> y <strong>Lasso</strong>.</p>
</section>
<section id="repaso-regresión-lineal-múltiple" class="level2">
<h2 class="anchored" data-anchor-id="repaso-regresión-lineal-múltiple">Repaso: regresión lineal múltiple</h2>
<p>La regresión lineal múltiple modela una variable de respuesta <img src="https://latex.codecogs.com/png.latex?y"> como una combinación lineal de <img src="https://latex.codecogs.com/png.latex?p"> variables predictoras:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Chat%7By%7D%20=%20%5Cbeta_0%20+%20%5Cbeta_1%20x_1%20+%20%5Cbeta_2%20x_2%20+%20%5Cdots%20+%20%5Cbeta_p%20x_p"></p>
<p>Los coeficientes <img src="https://latex.codecogs.com/png.latex?%5Cbeta_0,%20%5Cbeta_1,%20%5Cdots,%20%5Cbeta_p"> se estiman minimizando la suma de errores al cuadrado (mínimos cuadrados ordinarios, OLS):</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmin_%7B%5Cbeta%7D%20%5Csum_%7Bi=1%7D%5E%7Bn%7D%20(y_i%20-%20%5Chat%7By%7D_i)%5E2"></p>
<p>Para repasarla, vas a usar un dataset real: precios de vivienda en California, disponible directamente en <code>scikit-learn</code>. Cada fila es un bloque censal, con variables como ingreso medio, antigüedad de las viviendas, número de habitaciones, población y ubicación geográfica; el objetivo es predecir el <strong>precio medio de la vivienda</strong>.</p>
<div id="b29a675c" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:56.200366Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:56.200095Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:57.826967Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:57.826363Z&quot;}}" 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="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.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> fetch_california_housing</span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dataset real: precios de vivienda en California (incluido en scikit-learn)</span></span>
<span id="cb1-6">housing <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fetch_california_housing(as_frame<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="cb1-7">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> housing.data</span>
<span id="cb1-8">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> housing.target  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># precio medio de vivienda, en cientos de miles de USD</span></span>
<span id="cb1-9"></span>
<span id="cb1-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"Observaciones: </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>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;">"</span>)</span>
<span id="cb1-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"Variables predictoras: </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;">list</span>(X.columns)<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="cb1-12">X.head()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Observaciones: 20640
Variables predictoras: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="1">
<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">MedInc</th>
<th data-quarto-table-cell-role="th">HouseAge</th>
<th data-quarto-table-cell-role="th">AveRooms</th>
<th data-quarto-table-cell-role="th">AveBedrms</th>
<th data-quarto-table-cell-role="th">Population</th>
<th data-quarto-table-cell-role="th">AveOccup</th>
<th data-quarto-table-cell-role="th">Latitude</th>
<th data-quarto-table-cell-role="th">Longitude</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>8.3252</td>
<td>41.0</td>
<td>6.984127</td>
<td>1.023810</td>
<td>322.0</td>
<td>2.555556</td>
<td>37.88</td>
<td>-122.23</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>8.3014</td>
<td>21.0</td>
<td>6.238137</td>
<td>0.971880</td>
<td>2401.0</td>
<td>2.109842</td>
<td>37.86</td>
<td>-122.22</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>7.2574</td>
<td>52.0</td>
<td>8.288136</td>
<td>1.073446</td>
<td>496.0</td>
<td>2.802260</td>
<td>37.85</td>
<td>-122.24</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>5.6431</td>
<td>52.0</td>
<td>5.817352</td>
<td>1.073059</td>
<td>558.0</td>
<td>2.547945</td>
<td>37.85</td>
<td>-122.25</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>3.8462</td>
<td>52.0</td>
<td>6.281853</td>
<td>1.081081</td>
<td>565.0</td>
<td>2.181467</td>
<td>37.85</td>
<td>-122.25</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<p>Para evaluar el modelo de forma honesta, separa los datos en un conjunto de <strong>entrenamiento</strong> y uno de <strong>prueba</strong>: ajusta el modelo solo con el primero y evalúalo con el segundo, que nunca vio durante el entrenamiento.</p>
<div id="f9b60835" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:57.829145Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:57.828909Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:57.952757Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:57.951858Z&quot;}}" 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="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-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="cb3-3"><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_california_housing</span>
<span id="cb3-4"><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-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> LinearRegression</span>
<span id="cb3-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> mean_squared_error, r2_score</span>
<span id="cb3-7"></span>
<span id="cb3-8">housing <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fetch_california_housing(as_frame<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-9">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> housing.data</span>
<span id="cb3-10">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> housing.target</span>
<span id="cb3-11"></span>
<span id="cb3-12">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-13">    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="cb3-14">)</span>
<span id="cb3-15"></span>
<span id="cb3-16">modelo_lineal <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression()</span>
<span id="cb3-17">modelo_lineal.fit(X_train, y_train)</span>
<span id="cb3-18">y_pred <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> modelo_lineal.predict(X_test)</span>
<span id="cb3-19"></span>
<span id="cb3-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"R² en test:   </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>r2_score(y_test, y_pred)<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-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"RMSE en test: </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>sqrt(mean_squared_error(y_test, y_pred))<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-22"></span>
<span id="cb3-23">coeficientes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.Series(modelo_lineal.coef_, index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>X.columns).sort_values()</span>
<span id="cb3-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;">"</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;">Coeficientes del modelo:"</span>)</span>
<span id="cb3-25"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(coeficientes)</span>
<span id="cb3-26"></span>
<span id="cb3-27"><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;">Correlación AveRooms-AveBedrms: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>X[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'AveRooms'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>corr(X[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'AveBedrms'</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-stdout">
<pre><code>R² en test:   0.576
RMSE en test: 0.746

Coeficientes del modelo:
Longitude    -0.433708
Latitude     -0.419792
AveRooms     -0.123323
AveOccup     -0.003526
Population   -0.000002
HouseAge      0.009724
MedInc        0.448675
AveBedrms     0.783145
dtype: float64

Correlación AveRooms-AveBedrms: 0.85</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura del modelo sin regularizar</strong></p>
<ul>
<li>El modelo explica una parte razonable de la varianza del precio: R²=0.576 (RMSE=0.746, en cientos de miles de USD) — nada mal para un puñado de variables socioeconómicas y geográficas simples.</li>
<li>AveRooms y AveBedrms están correlacionadas 0.85 entre sí, y eso se nota directamente en los coeficientes impresos arriba: AveRooms sale con -0.12 (¿más habitaciones promedio, precio más bajo?) mientras AveBedrms sale con +0.78 — contraintuitivo si se leen por separado.</li>
<li>Ese par de signos opuestos no refleja una relación causal real: es el síntoma clásico de multicolinealidad, donde el modelo “reparte” de forma inestable el mismo efecto real entre dos variables que se mueven casi juntas.</li>
</ul>
</div>
</section>
<section id="el-problema-del-sobreajuste-y-el-compromiso-sesgo-varianza" class="level2">
<h2 class="anchored" data-anchor-id="el-problema-del-sobreajuste-y-el-compromiso-sesgo-varianza">El problema del sobreajuste y el compromiso sesgo-varianza</h2>
<p>Para ver el sobreajuste con claridad, aléjate por un momento del dataset de 8 variables y mira un ejemplo con una sola variable, donde puedas graficar el ajuste directamente.</p>
<p>Imagina que la relación real entre <img src="https://latex.codecogs.com/png.latex?x"> y <img src="https://latex.codecogs.com/png.latex?y"> es una curva suave, pero solo tienes observaciones con ruido. Si ajustas:</p>
<ul>
<li>Un modelo <strong>demasiado simple</strong> (una recta) va a <strong>subajustar</strong> (underfitting): no captura la curva real. Esto es alto <strong>sesgo</strong>.</li>
<li>Un modelo <strong>demasiado flexible</strong> (un polinomio de grado muy alto) va a <strong>memorizar el ruido</strong> de los puntos de entrenamiento. Esto es alta <strong>varianza</strong>: el modelo cambia mucho si cambian ligeramente los datos.</li>
</ul>
<p>El objetivo es encontrar el punto intermedio donde el error en datos <strong>nuevos</strong> (no vistos durante el entrenamiento) es mínimo.</p>
<div id="9b7a282c" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:57.954699Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:57.954533Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:58.460100Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:58.459390Z&quot;}}" 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="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-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="cb5-3"><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="cb5-4"><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> LinearRegression</span>
<span id="cb5-5"><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> mean_squared_error</span>
<span id="cb5-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> PolynomialFeatures, StandardScaler</span>
<span id="cb5-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.pipeline <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> make_pipeline</span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Datos sintéticos: una curva real + ruido</span></span>
<span id="cb5-10">rng <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.default_rng(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb5-11">x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.sort(rng.uniform(<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;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>))</span>
<span id="cb5-12">y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.sin(x) <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="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="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x</span>
<span id="cb5-13">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> rng.normal(scale<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;">1.0</span>, size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x.shape)</span>
<span id="cb5-14"></span>
<span id="cb5-15">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x.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="cb5-16">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="cb5-17">    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="cb5-18">)</span>
<span id="cb5-19"></span>
<span id="cb5-20">grados <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>(<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;">16</span>)</span>
<span id="cb5-21">error_train, error_test <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [], []</span>
<span id="cb5-22"></span>
<span id="cb5-23"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> grado <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> grados:</span>
<span id="cb5-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Escalar x antes de generar las potencias evita que las columnas de alto grado</span></span>
<span id="cb5-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># exploten en magnitud y hagan inestable la solución de mínimos cuadrados.</span></span>
<span id="cb5-26">    modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_pipeline(StandardScaler(), PolynomialFeatures(grado), LinearRegression())</span>
<span id="cb5-27">    modelo.fit(X_train, y_train)</span>
<span id="cb5-28">    error_train.append(mean_squared_error(y_train, modelo.predict(X_train)))</span>
<span id="cb5-29">    error_test.append(mean_squared_error(y_test, modelo.predict(X_test)))</span>
<span id="cb5-30"></span>
<span id="cb5-31">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb5-32">ax.plot(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(grados), error_train, marker<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;">"o"</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;">"Error de entrenamiento"</span>)</span>
<span id="cb5-33">ax.plot(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(grados), error_test, marker<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;">"o"</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;">"Error de prueba"</span>)</span>
<span id="cb5-34">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Grado del polinomio (complejidad del modelo)"</span>)</span>
<span id="cb5-35">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Error cuadrático medio"</span>)</span>
<span id="cb5-36">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Compromiso sesgo-varianza: complejidad vs error"</span>)</span>
<span id="cb5-37">ax.legend()</span>
<span id="cb5-38">ax.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.3</span>)</span>
<span id="cb5-39">plt.show()</span>
<span id="cb5-40"></span>
<span id="cb5-41">grado_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;">list</span>(grados)[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(np.argmin(error_test))]</span>
<span id="cb5-42"><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"Grado con menor error de prueba: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>grado_optimo<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;"> (MSE_test=</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;">min</span>(error_test)<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;">, MSE_train=</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>error_train[np.argmin(error_test)]<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="cb5-43"><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"MSE de prueba en grado 12: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>error_test[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</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="cb5-44"><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"MSE de entrenamiento en grado 15: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>error_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;">1</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;"> (el más bajo de toda la curva)"</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/estadistica-fundamentos/03-regresion-regularizacion/index_files/figure-html/cell-4-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Grado con menor error de prueba: 4 (MSE_test=0.50, MSE_train=0.90)
MSE de prueba en grado 12: 73.09
MSE de entrenamiento en grado 15: 0.32 (el más bajo de toda la curva)</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura de la curva sesgo-varianza</strong></p>
<ul>
<li>El error de entrenamiento baja de forma monótona con la complejidad: pasa de 5.25 en grado 1 hasta 0.32 en grado 15 (el punto más bajo de toda la curva) — un polinomio de grado 15 tiene tanta flexibilidad que prácticamente memoriza los 42 puntos de entrenamiento.</li>
<li>El error de prueba cuenta otra historia: toca su mínimo en grado 4 (MSE=0.50, con MSE de entrenamiento de apenas 0.90 en ese mismo punto) y después empieza a subir. En grado 12 llega a 73.09 — casi 150 veces el mínimo alcanzado en grado 4.</li>
<li>Esa brecha entre “el entrenamiento sigue mejorando” y “la prueba se dispara” es la definición operativa de sobreajuste: pasado el grado 4, cada grado adicional solo ayuda a memorizar ruido del conjunto de entrenamiento, no a predecir mejor sobre datos nuevos.</li>
</ul>
</div>
</section>
<section id="regularización-ridge-l2" class="level2">
<h2 class="anchored" data-anchor-id="regularización-ridge-l2">Regularización Ridge (L2)</h2>
<p>Ridge modifica la función de costo de la regresión lineal agregando una penalización proporcional a la <strong>suma de los coeficientes al cuadrado</strong>:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmin_%7B%5Cbeta%7D%20%5Csum_%7Bi=1%7D%5En%20(y_i%20-%20%5Chat%20y_i)%5E2%20+%20%5Calpha%20%5Csum_%7Bj=1%7D%5Ep%20%5Cbeta_j%5E2"></p>
<p>El hiperparámetro <img src="https://latex.codecogs.com/png.latex?%5Calpha"> (alpha) controla la fuerza de la penalización:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%200"> → Ridge es idéntico a la regresión lineal ordinaria.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Calpha%20%5Cto%20%5Cinfty"> → todos los coeficientes se acercan a cero (el modelo se vuelve casi constante).</li>
</ul>
<p>La intuición: Ridge <strong>encoge</strong> (<em>shrinks</em>) los coeficientes hacia cero, especialmente los de variables correlacionadas o poco informativas, sin llegar a eliminarlos por completo. Esto reduce la varianza del modelo a cambio de un poco de sesgo — justo el compromiso que viste arriba.</p>
<p>Para ver el efecto con claridad, genera un dataset sintético con variables informativas y variables que son puro ruido, y observa cómo cambian los coeficientes a medida que aumenta <img src="https://latex.codecogs.com/png.latex?%5Calpha">.</p>
<div id="6b16b3da" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:58.461904Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:58.461674Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:58.843896Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:58.843267Z&quot;}}" 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="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-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="cb7-3"><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_regression</span>
<span id="cb7-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StandardScaler</span>
<span id="cb7-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> Ridge</span>
<span id="cb7-6"></span>
<span id="cb7-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dataset sintético: 10 variables, solo 4 realmente informativas</span></span>
<span id="cb7-8">X, y, coef_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_regression(</span>
<span id="cb7-9">    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;">200</span>,</span>
<span id="cb7-10">    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>,</span>
<span id="cb7-11">    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;">4</span>,</span>
<span id="cb7-12">    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;">10.0</span>,</span>
<span id="cb7-13">    coef<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="cb7-14">    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="cb7-15">)</span>
<span id="cb7-16">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StandardScaler().fit_transform(X)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># estandarizar es clave para regularizar</span></span>
<span id="cb7-17"></span>
<span id="cb7-18">alphas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.logspace(<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="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>)</span>
<span id="cb7-19">coeficientes_ridge <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb7-20"></span>
<span id="cb7-21"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> alpha <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> alphas:</span>
<span id="cb7-22">    modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Ridge(alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alpha)</span>
<span id="cb7-23">    modelo.fit(X, y)</span>
<span id="cb7-24">    coeficientes_ridge.append(modelo.coef_)</span>
<span id="cb7-25"></span>
<span id="cb7-26">coeficientes_ridge <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array(coeficientes_ridge)</span>
<span id="cb7-27"></span>
<span id="cb7-28">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb7-29"><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>(X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]):</span>
<span id="cb7-30">    ax.plot(alphas, coeficientes_ridge[:, i], 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"x</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>
<span id="cb7-31">ax.set_xscale(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"log"</span>)</span>
<span id="cb7-32">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alpha (fuerza de regularización)"</span>)</span>
<span id="cb7-33">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Valor del coeficiente"</span>)</span>
<span id="cb7-34">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ridge: los coeficientes se encogen hacia cero, pero no lo alcanzan"</span>)</span>
<span id="cb7-35">ax.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;">"upper right"</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;">8</span>, ncol<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="cb7-36">ax.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.3</span>)</span>
<span id="cb7-37">plt.show()</span>
<span id="cb7-38"></span>
<span id="cb7-39"><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"Variables realmente informativas (coeficiente ≠ 0 en la generación): </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;">f'x</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="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, c <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>(coef_real) <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>(c) <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="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="cb7-40"><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;">Suma de |coeficientes| en alpha=</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>alphas[<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;">:.2f}</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>np<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;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(coeficientes_ridge[<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;">:.1f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb7-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"Suma de |coeficientes| en alpha=</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>alphas[<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;">:.0f}</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>np<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;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(coeficientes_ridge[<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;">:.1f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb7-42"><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"Coeficiente de x7 (el más grande, informativo) — alpha bajo: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>coeficientes_ridge[<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;">6</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;">, alpha alto: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>coeficientes_ridge[<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;">6</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/estadistica-fundamentos/03-regresion-regularizacion/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>Variables realmente informativas (coeficiente ≠ 0 en la generación): ['x2', 'x5', 'x7', 'x10']

Suma de |coeficientes| en alpha=0.01: 91.7
Suma de |coeficientes| en alpha=10000: 2.1
Coeficiente de x7 (el más grande, informativo) — alpha bajo: 36.97, alpha alto: 0.80</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura del camino de regularización Ridge</strong></p>
<ul>
<li>Las variables realmente informativas (x2, x5, x7 y x10) son justo las que parten con los coeficientes más grandes en alpha bajo — el modelo sí está capturando la señal real antes de regularizar.</li>
<li>A medida que alpha crece de 0.01 a 10000, la suma de |coeficientes| cae de 91.7 a 2.1 — un encogimiento de más de 40 veces, y afecta a todas las variables, no solo a las irrelevantes.</li>
<li>x7 (la variable con más peso real) pasa de 36.97 a apenas 0.80: se encoge muchísimo, pero en ningún punto del camino llega a cero exacto — la firma que distingue a Ridge de Lasso.</li>
</ul>
</div>
</section>
<section id="regularización-lasso-l1" class="level2">
<h2 class="anchored" data-anchor-id="regularización-lasso-l1">Regularización Lasso (L1)</h2>
<p>Lasso (<em>Least Absolute Shrinkage and Selection Operator</em>) usa una penalización distinta: la <strong>suma de los valores absolutos</strong> de los coeficientes.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmin_%7B%5Cbeta%7D%20%5Csum_%7Bi=1%7D%5En%20(y_i%20-%20%5Chat%20y_i)%5E2%20+%20%5Calpha%20%5Csum_%7Bj=1%7D%5Ep%20%7C%5Cbeta_j%7C"></p>
<p>La diferencia con Ridge parece sutil (cuadrado vs.&nbsp;valor absoluto), pero tiene una consecuencia geométrica importante: la región de penalización de Lasso tiene <strong>esquinas</strong> (sobre los ejes, donde algún coeficiente es exactamente cero), mientras que la de Ridge es una esfera suave. Eso hace que la solución óptima de Lasso “aterrice” con frecuencia exactamente sobre uno de esos ejes.</p>
<p>En la práctica, esto significa que Lasso no solo encoge coeficientes: <strong>los apaga por completo</strong>. Es, de facto, un método de <strong>selección automática de variables</strong>.</p>
<p>Usa el mismo dataset sintético de antes (10 variables, solo 4 informativas) para comprobarlo.</p>
<div id="a3e15863" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:58.845753Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:58.845586Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:59.062421Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:59.061893Z&quot;}}" 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="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-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="cb9-3"><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_regression</span>
<span id="cb9-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StandardScaler</span>
<span id="cb9-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> Lasso</span>
<span id="cb9-6"></span>
<span id="cb9-7">X, y, coef_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_regression(</span>
<span id="cb9-8">    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;">200</span>,</span>
<span id="cb9-9">    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>,</span>
<span id="cb9-10">    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;">4</span>,</span>
<span id="cb9-11">    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;">10.0</span>,</span>
<span id="cb9-12">    coef<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="cb9-13">    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-14">)</span>
<span id="cb9-15">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StandardScaler().fit_transform(X)</span>
<span id="cb9-16"></span>
<span id="cb9-17">alphas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.logspace(<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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span>)</span>
<span id="cb9-18">coeficientes_lasso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb9-19"></span>
<span id="cb9-20"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> alpha <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> alphas:</span>
<span id="cb9-21">    modelo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Lasso(alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alpha, 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;">10000</span>)</span>
<span id="cb9-22">    modelo.fit(X, y)</span>
<span id="cb9-23">    coeficientes_lasso.append(modelo.coef_)</span>
<span id="cb9-24"></span>
<span id="cb9-25">coeficientes_lasso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array(coeficientes_lasso)</span>
<span id="cb9-26"></span>
<span id="cb9-27">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">7</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb9-28"><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>(X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]):</span>
<span id="cb9-29">    ax.plot(alphas, coeficientes_lasso[:, i], 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"x</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>
<span id="cb9-30">ax.set_xscale(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"log"</span>)</span>
<span id="cb9-31">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alpha (fuerza de regularización)"</span>)</span>
<span id="cb9-32">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Valor del coeficiente"</span>)</span>
<span id="cb9-33">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lasso: los coeficientes menos relevantes llegan exactamente a cero"</span>)</span>
<span id="cb9-34">ax.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;">"upper right"</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;">8</span>, ncol<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="cb9-35">ax.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.3</span>)</span>
<span id="cb9-36">plt.show()</span>
<span id="cb9-37"></span>
<span id="cb9-38"><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;">"Variables informativas reales (coeficiente ≠ 0 en la generación):"</span>)</span>
<span id="cb9-39"><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"x</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="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i, c <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>(coef_real) <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>(c) <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></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://biitt.com/es/blog/estadistica-fundamentos/03-regresion-regularizacion/index_files/figure-html/cell-6-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-stdout">
<pre><code>Variables informativas reales (coeficiente ≠ 0 en la generación):
['x2', 'x5', 'x7', 'x10']</code></pre>
</div>
</div>
<div id="1cbdcf81" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:59.064223Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:59.064036Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:59.070302Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:59.069515Z&quot;}}" 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="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-2"><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_regression</span>
<span id="cb11-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StandardScaler</span>
<span id="cb11-4"><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> Lasso</span>
<span id="cb11-5"></span>
<span id="cb11-6">X, y, coef_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_regression(</span>
<span id="cb11-7">    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;">200</span>,</span>
<span id="cb11-8">    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>,</span>
<span id="cb11-9">    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;">4</span>,</span>
<span id="cb11-10">    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;">10.0</span>,</span>
<span id="cb11-11">    coef<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="cb11-12">    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">)</span>
<span id="cb11-14">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StandardScaler().fit_transform(X)</span>
<span id="cb11-15"></span>
<span id="cb11-16">modelo_lasso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Lasso(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;">1.0</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;">10000</span>)</span>
<span id="cb11-17">modelo_lasso.fit(X, y)</span>
<span id="cb11-18"></span>
<span id="cb11-19">no_cero <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>(modelo_lasso.coef_ <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="cb11-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"Variables con coeficiente distinto de cero: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>no_cero<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;"> de </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>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;">"</span>)</span>
<span id="cb11-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"Variables realmente informativas: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(coef_real) <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="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>Variables con coeficiente distinto de cero: 4 de 10
Variables realmente informativas: 4</code></pre>
</div>
</div>
<div style="background-color:#e9f7ef; border-left:6px solid #2f855a; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura de la selección de variables con Lasso</strong></p>
<ul>
<li>Con alpha=1.0, Lasso dejó exactamente 4 coeficientes distintos de cero de las 10 variables — y esas 4 son precisamente x2, x5, x7 y x10: las mismas 4 que realmente generaron la señal al construir el dataset sintético. Coincidencia perfecta entre lo que el modelo “eligió” y lo que era verdad.</li>
<li>Las 6 variables sin efecto real (x1, x3, x4, x6, x8, x9) quedaron en exactamente cero, no solo “chiquitas”: Lasso las apagó del todo.</li>
<li>En un problema real nunca vas a tener esta certeza (no conoces el coef_real de antemano), pero el mecanismo es el mismo: a un alpha suficientemente alto, Lasso deja activas solo las variables que más aportan y apaga el resto — de facto, selección automática de variables.</li>
</ul>
</div>
</section>
<section id="comparación-visual-sin-regularizar-vs.-ridge-vs.-lasso" class="level2">
<h2 class="anchored" data-anchor-id="comparación-visual-sin-regularizar-vs.-ridge-vs.-lasso">Comparación visual: sin regularizar vs.&nbsp;Ridge vs.&nbsp;Lasso</h2>
<p>Ahora compara, lado a lado, los coeficientes que produce cada enfoque sobre el mismo dataset sintético, con un valor de <img src="https://latex.codecogs.com/png.latex?%5Calpha"> fijo y razonable para cada uno.</p>
<div id="1f7c8ba9" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-28T03:31:59.071992Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-28T03:31:59.071751Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-28T03:31:59.191220Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-28T03:31:59.190559Z&quot;}}" 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="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-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="cb13-3"><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_regression</span>
<span id="cb13-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> sklearn.preprocessing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StandardScaler</span>
<span id="cb13-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> LinearRegression, Ridge, Lasso</span>
<span id="cb13-6"></span>
<span id="cb13-7">X, y, coef_real <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> make_regression(</span>
<span id="cb13-8">    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;">200</span>,</span>
<span id="cb13-9">    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>,</span>
<span id="cb13-10">    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;">4</span>,</span>
<span id="cb13-11">    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;">10.0</span>,</span>
<span id="cb13-12">    coef<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="cb13-13">    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="cb13-14">)</span>
<span id="cb13-15">X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StandardScaler().fit_transform(X)</span>
<span id="cb13-16"></span>
<span id="cb13-17">modelo_ols <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LinearRegression().fit(X, y)</span>
<span id="cb13-18">modelo_ridge <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Ridge(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;">10.0</span>).fit(X, y)</span>
<span id="cb13-19">modelo_lasso <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Lasso(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;">1.0</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;">10000</span>).fit(X, y)</span>
<span id="cb13-20"></span>
<span id="cb13-21">variables <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"x</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="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>(X.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>])]</span>
<span id="cb13-22">ancho <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.25</span></span>
<span id="cb13-23">posiciones <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(variables))</span>
<span id="cb13-24"></span>
<span id="cb13-25">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">9</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>))</span>
<span id="cb13-26">ax.bar(posiciones <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> ancho, modelo_ols.coef_, width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ancho, 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;">"Sin regularizar (OLS)"</span>)</span>
<span id="cb13-27">ax.bar(posiciones, modelo_ridge.coef_, width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ancho, 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;">"Ridge (L2)"</span>)</span>
<span id="cb13-28">ax.bar(posiciones <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> ancho, modelo_lasso.coef_, width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ancho, 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;">"Lasso (L1)"</span>)</span>
<span id="cb13-29">ax.set_xticks(posiciones)</span>
<span id="cb13-30">ax.set_xticklabels(variables)</span>
<span id="cb13-31">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Valor del coeficiente"</span>)</span>
<span id="cb13-32">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Coeficientes: OLS vs Ridge vs Lasso"</span>)</span>
<span id="cb13-33">ax.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;">"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="cb13-34">ax.legend()</span>
<span id="cb13-35">ax.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.3</span>, axis<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;">"y"</span>)</span>
<span id="cb13-36">plt.show()</span>
<span id="cb13-37"></span>
<span id="cb13-38"><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"Coeficientes con |valor|&gt;0.01 — OLS: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(modelo_ols.coef_)<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.01</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;">, Ridge: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(modelo_ridge.coef_)<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.01</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;">, Lasso: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(modelo_lasso.coef_ <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="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-39"><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"Suma de |coeficientes|      — OLS: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(modelo_ols.coef_))<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;">, Ridge: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(modelo_ridge.coef_))<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;">, Lasso: </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><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(np.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">abs</span>(modelo_lasso.coef_))<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="cb13-40"><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"Coeficiente de x4 (irrelevante, coef_real=0) — OLS: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>modelo_ols<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>coef_[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</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;">, Ridge: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>modelo_ridge<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>coef_[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</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;">, Lasso: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>modelo_lasso<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>coef_[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</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/estadistica-fundamentos/03-regresion-regularizacion/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>Coeficientes con |valor|&gt;0.01 — OLS: 10, Ridge: 10, Lasso: 4
Suma de |coeficientes|      — OLS: 91.7, Ridge: 87.6, Lasso: 83.9
Coeficiente de x4 (irrelevante, coef_real=0) — OLS: 1.10, Ridge: 1.05, Lasso: 0.00</code></pre>
</div>
</div>
<div style="background-color:#eef6ff; border-left:6px solid #2b6cb0; padding:12px 14px; border-radius:8px;">
<p><strong>Lectura de la comparación OLS vs.&nbsp;Ridge vs.&nbsp;Lasso</strong></p>
<ul>
<li>OLS asigna coeficiente distinto de cero a las 10 variables, incluidas las 6 que no tienen ningún efecto real. x4, por ejemplo, sale con +1.10 pese a que su coeficiente real es 0 — puro ruido que el modelo interpreta como señal.</li>
<li>Ridge (alpha=10) reduce apenas un poco la magnitud total (91.7 a 87.6 en suma de |coeficientes|) y sigue dejando las 10 variables activas: a x4 lo baja de 1.10 a 1.05, un recorte mínimo.</li>
<li>Lasso (alpha=1.0) es el único que produce un modelo esparso: solo 4 de 10 coeficientes quedan distintos de cero, y x4 queda en 0.00 exacto — apagado por completo, no solo reducido.</li>
</ul>
</div>
</section>
<section id="cierre-técnico-cuándo-usar-cada-una" class="level2">
<h2 class="anchored" data-anchor-id="cierre-técnico-cuándo-usar-cada-una">Cierre técnico: ¿cuándo usar cada una?</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Situación</th>
<th>Recomendación</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Muchas variables correlacionadas entre sí (multicolinealidad)</td>
<td><strong>Ridge</strong> — distribuye el “peso” entre variables correlacionadas en vez de elegir una de forma arbitraria</td>
</tr>
<tr class="even">
<td>Sospechas que muchas variables son irrelevantes y quieres un modelo más simple e interpretable</td>
<td><strong>Lasso</strong> — hace selección de variables automáticamente</td>
</tr>
<tr class="odd">
<td>Quieres lo mejor de ambos mundos (selección + manejo de correlación)</td>
<td><strong>Elastic Net</strong> — combina las penalizaciones L1 y L2 (no cubierto en este artículo, disponible en <code>sklearn.linear_model.ElasticNet</code>)</td>
</tr>
<tr class="even">
<td>No hay señales de sobreajuste y el modelo lineal simple ya generaliza bien</td>
<td>Regresión lineal ordinaria — no toda situación necesita regularización</td>
</tr>
</tbody>
</table>
<p>En la práctica, el valor de <img src="https://latex.codecogs.com/png.latex?%5Calpha"> <strong>no se elige a mano</strong>: se selecciona con validación cruzada (<code>RidgeCV</code>, <code>LassoCV</code> en <code>scikit-learn</code>), probando un rango de valores y quedándote con el que minimiza el error en datos de validación. Ese será tema de un próximo artículo de la serie, dedicado a evaluación de modelos y bootstrap.</p>
<p>Un último punto práctico: <strong>tanto Ridge como Lasso son sensibles a la escala de las variables</strong> — por eso, en todos los ejemplos de este artículo, se estandarizaron los datos con <code>StandardScaler</code> antes de ajustar el modelo. Si te saltas ese paso, las variables con escalas más grandes quedan penalizadas de forma desproporcionada respecto a las demás.</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>estadistica</category>
  <category>regularizacion</category>
  <category>ridge-lasso</category>
  <guid>https://biitt.com/es/blog/estadistica-fundamentos/03-regresion-regularizacion/</guid>
  <pubDate>Wed, 26 Aug 2026 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Ejemplo: flujo completo de un notebook publicado en el blog</title>
  <dc:creator>Wilder Ramírez Delgado</dc:creator>
  <link>https://biitt.com/es/blog/machine-learning/ejemplo-post-completo/</link>
  <description><![CDATA[ 




<section id="análisis-ficticio-de-ventas-notebook-de-prueba-para-publicación" class="level1">
<h1>Análisis ficticio de ventas: notebook de prueba para publicación</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>Este notebook es una muestra compacta y realista para evaluar la conversión <strong>.ipynb → HTML</strong> y su publicación en distintos canales.</p>
<p>En esta demostración usamos datos sintéticos de ventas y una secuencia técnica típica:</p>
<ol type="1">
<li>Carga y creación de datos</li>
<li>Exploración inicial</li>
<li>Transformación</li>
<li>Estadísticas descriptivas</li>
<li>Visualizaciones estáticas e interactivas</li>
</ol>
<p>También incluimos elementos de formato: <em>cursiva</em>, <strong>negrita</strong>, listas y cita.</p>
<ul>
<li>Tema: ventas mensuales por región y canal</li>
<li>Fuente: datos generados en Python (sin archivos externos)</li>
<li>Reproducibilidad: semilla fija</li>
</ul>
<p>Más sobre buenas prácticas de visualización: <a href="https://plotly.com/python/">Plotly Fundamentals</a>.</p>
<blockquote class="blockquote">
<p>Nota: este cuaderno incluye caracteres en español (á, é, í, ó, ú, ñ) y símbolos como ≥, ≤, %, $, → para validar renderizado.</p>
</blockquote>
<p>URL de prueba visible: https://biitt.com/blog</p>
<p>Ecuación inline de margen: <img src="https://latex.codecogs.com/png.latex?m%20=%20%5Cfrac%7Bingresos%20-%20costos%7D%7Bingresos%7D">.</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 id="datos" class="level2">
<h2 class="anchored" data-anchor-id="datos">Datos</h2>
<p>Generamos un dataset pequeño de ventas con variación por mes, región, canal y categoría.</p>
<div id="4bdbdace" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:38.044998Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:38.044778Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:38.764441Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:38.762539Z&quot;}}" 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="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;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb1-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.express <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> px</span>
<span id="cb1-5"></span>
<span id="cb1-6">np.random.seed(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>)</span>
<span id="cb1-7"></span>
<span id="cb1-8">meses <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.date_range(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2026-01-01"</span>, periods<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>, freq<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;">"MS"</span>)</span>
<span id="cb1-9">regiones <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;">"Norte"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Centro"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sur"</span>]</span>
<span id="cb1-10">canales <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;">"Online"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Retail"</span>]</span>
<span id="cb1-11">categorias <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;">"Software"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Servicios"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Capacitación"</span>]</span>
<span id="cb1-12"></span>
<span id="cb1-13">rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb1-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> mes <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> meses:</span>
<span id="cb1-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> region <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> regiones:</span>
<span id="cb1-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> canal <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> canales:</span>
<span id="cb1-17">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> categoria <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> categorias:</span>
<span id="cb1-18">                base_unidades <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.randint(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">180</span>)</span>
<span id="cb1-19">                precio_unitario <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.uniform(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">140</span>)</span>
<span id="cb1-20">                descuento_pct <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.choice([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.00</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.10</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.15</span>], p<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.35</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.25</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.10</span>])</span>
<span id="cb1-21"></span>
<span id="cb1-22">                ingreso_bruto <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> base_unidades <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> precio_unitario</span>
<span id="cb1-23">                ingreso_neto <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ingreso_bruto <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> descuento_pct)</span>
<span id="cb1-24">                costo_estimado <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ingreso_neto <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.random.uniform(<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.72</span>)</span>
<span id="cb1-25"></span>
<span id="cb1-26">                rows.append({</span>
<span id="cb1-27">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes"</span>: mes,</span>
<span id="cb1-28">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>: region,</span>
<span id="cb1-29">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"canal"</span>: canal,</span>
<span id="cb1-30">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"categoria"</span>: categoria,</span>
<span id="cb1-31">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unidades"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>(base_unidades),</span>
<span id="cb1-32">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"precio_unitario"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(precio_unitario, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb1-33">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"descuento_pct"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(descuento_pct),</span>
<span id="cb1-34">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(ingreso_neto, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>),</span>
<span id="cb1-35">                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"costo_estimado"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(costo_estimado, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb1-36">                })</span>
<span id="cb1-37"></span>
<span id="cb1-38">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame(rows)</span>
<span id="cb1-39"><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"Filas generadas: </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>(df)<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="cb1-40">df.head()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Filas generadas: 144</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="1">
<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">mes</th>
<th data-quarto-table-cell-role="th">region</th>
<th data-quarto-table-cell-role="th">canal</th>
<th data-quarto-table-cell-role="th">categoria</th>
<th data-quarto-table-cell-role="th">unidades</th>
<th data-quarto-table-cell-role="th">precio_unitario</th>
<th data-quarto-table-cell-role="th">descuento_pct</th>
<th data-quarto-table-cell-role="th">ingreso_neto</th>
<th data-quarto-table-cell-role="th">costo_estimado</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>Software</td>
<td>162</td>
<td>120.67</td>
<td>0.00</td>
<td>19548.80</td>
<td>13213.78</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>Servicios</td>
<td>80</td>
<td>59.82</td>
<td>0.00</td>
<td>4785.74</td>
<td>2544.18</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>Capacitación</td>
<td>147</td>
<td>76.70</td>
<td>0.00</td>
<td>11275.24</td>
<td>7330.91</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Retail</td>
<td>Software</td>
<td>112</td>
<td>137.14</td>
<td>0.10</td>
<td>13823.86</td>
<td>7775.47</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Retail</td>
<td>Servicios</td>
<td>123</td>
<td>139.26</td>
<td>0.05</td>
<td>16272.54</td>
<td>10452.35</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
</section>
<section id="exploración" class="level2">
<h2 class="anchored" data-anchor-id="exploración">Exploración</h2>
<p>Primero revisamos estructura, tipos y una tabla ancha para testear visualización en publicación.</p>
<div id="52d5d917" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:38.766476Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:38.766303Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:38.790572Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:38.789761Z&quot;}}" 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="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 rápido del dataset:"</span>)</span>
<span id="cb3-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(df.info())</span>
<span id="cb3-3"></span>
<span id="cb3-4">tabla_ancha <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb3-5">    df.pivot_table(</span>
<span id="cb3-6">        index<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;">"region"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"canal"</span>],</span>
<span id="cb3-7">        columns<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;">"mes"</span>,</span>
<span id="cb3-8">        values<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;">"ingreso_neto"</span>,</span>
<span id="cb3-9">        aggfunc<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;">"sum"</span></span>
<span id="cb3-10">    )</span>
<span id="cb3-11">    .<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>)</span>
<span id="cb3-12">)</span>
<span id="cb3-13"></span>
<span id="cb3-14">tabla_ancha.columns <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [c.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%Y-%m"</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> c <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> tabla_ancha.columns]</span>
<span id="cb3-15">tabla_ancha</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Resumen rápido del dataset:
&lt;class 'pandas.DataFrame'&gt;
RangeIndex: 144 entries, 0 to 143
Data columns (total 9 columns):
 #   Column           Non-Null Count  Dtype         
---  ------           --------------  -----         
 0   mes              144 non-null    datetime64[us]
 1   region           144 non-null    str           
 2   canal            144 non-null    str           
 3   categoria        144 non-null    str           
 4   unidades         144 non-null    int64         
 5   precio_unitario  144 non-null    float64       
 6   descuento_pct    144 non-null    float64       
 7   ingreso_neto     144 non-null    float64       
 8   costo_estimado   144 non-null    float64       
dtypes: datetime64[us](1), float64(4), int64(1), str(3)
memory usage: 10.3 KB
None</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="2">
<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"></th>
<th data-quarto-table-cell-role="th">2026-01</th>
<th data-quarto-table-cell-role="th">2026-02</th>
<th data-quarto-table-cell-role="th">2026-03</th>
<th data-quarto-table-cell-role="th">2026-04</th>
<th data-quarto-table-cell-role="th">2026-05</th>
<th data-quarto-table-cell-role="th">2026-06</th>
<th data-quarto-table-cell-role="th">2026-07</th>
<th data-quarto-table-cell-role="th">2026-08</th>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">region</th>
<th data-quarto-table-cell-role="th">canal</th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th"></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th rowspan="2" data-quarto-table-cell-role="th" data-valign="top">Centro</th>
<th data-quarto-table-cell-role="th">Online</th>
<td>35186.0</td>
<td>49554.0</td>
<td>42293.0</td>
<td>32025.0</td>
<td>42012.0</td>
<td>24524.0</td>
<td>48242.0</td>
<td>15813.0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">Retail</th>
<td>18406.0</td>
<td>28715.0</td>
<td>33445.0</td>
<td>33557.0</td>
<td>27430.0</td>
<td>24748.0</td>
<td>43131.0</td>
<td>30073.0</td>
</tr>
<tr class="odd">
<th rowspan="2" data-quarto-table-cell-role="th" data-valign="top">Norte</th>
<th data-quarto-table-cell-role="th">Online</th>
<td>35610.0</td>
<td>32800.0</td>
<td>26948.0</td>
<td>31399.0</td>
<td>34495.0</td>
<td>37233.0</td>
<td>36724.0</td>
<td>28596.0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">Retail</th>
<td>37583.0</td>
<td>26243.0</td>
<td>38964.0</td>
<td>38199.0</td>
<td>29921.0</td>
<td>19354.0</td>
<td>28893.0</td>
<td>19668.0</td>
</tr>
<tr class="odd">
<th rowspan="2" data-quarto-table-cell-role="th" data-valign="top">Sur</th>
<th data-quarto-table-cell-role="th">Online</th>
<td>23018.0</td>
<td>43835.0</td>
<td>30914.0</td>
<td>25818.0</td>
<td>20949.0</td>
<td>23586.0</td>
<td>23635.0</td>
<td>39535.0</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">Retail</th>
<td>26645.0</td>
<td>27783.0</td>
<td>29011.0</td>
<td>35379.0</td>
<td>45683.0</td>
<td>26238.0</td>
<td>36963.0</td>
<td>25284.0</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
</section>
<section id="transformación" class="level2">
<h2 class="anchored" data-anchor-id="transformación">Transformación</h2>
<p>Creamos variables derivadas para análisis de margen y segmentación de desempeño.</p>
<div id="46595950" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:38.792723Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:38.792575Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:38.810610Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:38.809514Z&quot;}}" 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="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> etiquetar_rendimiento(margen_pct, ingreso_neto):</span>
<span id="cb5-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (margen_pct <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.40</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (ingreso_neto <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;">12000</span>):</span>
<span id="cb5-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alto"</span></span>
<span id="cb5-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (margen_pct <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>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (ingreso_neto <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;">9000</span>):</span>
<span id="cb5-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Medio"</span></span>
<span id="cb5-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bajo"</span></span>
<span id="cb5-7"></span>
<span id="cb5-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> preparar_dataset(df_base):</span>
<span id="cb5-9">    df_t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_base.copy()</span>
<span id="cb5-10"></span>
<span id="cb5-11">    df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"costo_estimado"</span>]</span>
<span id="cb5-12">    df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"margen_pct"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.where(</span>
<span id="cb5-13">        df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</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>
<span id="cb5-14">        df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>],</span>
<span id="cb5-15">        np.nan</span>
<span id="cb5-16">    )</span>
<span id="cb5-17"></span>
<span id="cb5-18">    df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ticket_promedio"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.where(</span>
<span id="cb5-19">        df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unidades"</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>
<span id="cb5-20">        df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unidades"</span>],</span>
<span id="cb5-21">        np.nan</span>
<span id="cb5-22">    )</span>
<span id="cb5-23"></span>
<span id="cb5-24">    df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rendimiento"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb5-25">        etiquetar_rendimiento(m, i)</span>
<span id="cb5-26">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> m, 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;">zip</span>(df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"margen_pct"</span>], df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>])</span>
<span id="cb5-27">    ]</span>
<span id="cb5-28"></span>
<span id="cb5-29">    df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes_nombre"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes"</span>].dt.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%b"</span>)</span>
<span id="cb5-30">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> df_t</span>
<span id="cb5-31"></span>
<span id="cb5-32">df_t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> preparar_dataset(df)</span>
<span id="cb5-33"></span>
<span id="cb5-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;">"Transformación completada → columnas nuevas: utilidad, margen_pct, ticket_promedio, rendimiento"</span>)</span>
<span id="cb5-35">df_t[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"canal"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"margen_pct"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rendimiento"</span>]].head()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Transformación completada → columnas nuevas: utilidad, margen_pct, ticket_promedio, rendimiento</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="3">
<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">mes</th>
<th data-quarto-table-cell-role="th">region</th>
<th data-quarto-table-cell-role="th">canal</th>
<th data-quarto-table-cell-role="th">ingreso_neto</th>
<th data-quarto-table-cell-role="th">utilidad</th>
<th data-quarto-table-cell-role="th">margen_pct</th>
<th data-quarto-table-cell-role="th">rendimiento</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>19548.80</td>
<td>6335.02</td>
<td>0.324062</td>
<td>Medio</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>4785.74</td>
<td>2241.56</td>
<td>0.468383</td>
<td>Bajo</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Online</td>
<td>11275.24</td>
<td>3944.33</td>
<td>0.349822</td>
<td>Medio</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Retail</td>
<td>13823.86</td>
<td>6048.39</td>
<td>0.437533</td>
<td>Alto</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>2026-01-01</td>
<td>Norte</td>
<td>Retail</td>
<td>16272.54</td>
<td>5820.19</td>
<td>0.357669</td>
<td>Medio</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
</section>
<section id="estadísticas" class="level2">
<h2 class="anchored" data-anchor-id="estadísticas">Estadísticas</h2>
<p>Calculamos métricas agregadas y una tabla resumen con Pandas.</p>
<p>Ecuación en bloque para referencia: <img src="https://latex.codecogs.com/png.latex?%0AROI%20=%20%5Cfrac%7B%5Csum%20utilidad%7D%7B%5Csum%20costo%7D%20%5Ctimes%20100%0A"> Si <img src="https://latex.codecogs.com/png.latex?ROI%20eq%2020%5C%25">, consideramos un desempeño saludable.</p>
<div id="eaeac912" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:38.812524Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:38.812343Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:38.830030Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:38.829278Z&quot;}}" 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">resumen_general <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb7-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_total"</span>: df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(),</span>
<span id="cb7-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"costo_total"</span>: df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"costo_estimado"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(),</span>
<span id="cb7-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad_total"</span>: df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>(),</span>
<span id="cb7-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"margen_promedio"</span>: df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"margen_pct"</span>].mean(),</span>
<span id="cb7-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ticket_promedio"</span>: df_t[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ticket_promedio"</span>].mean()</span>
<span id="cb7-7">}</span>
<span id="cb7-8"></span>
<span id="cb7-9">roi <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (resumen_general[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad_total"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> resumen_general[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"costo_total"</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;">100</span></span>
<span id="cb7-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"Ingreso total: $</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resumen_general[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ingreso_total'</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="cb7-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"Utilidad total: $</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resumen_general[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utilidad_total'</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="cb7-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"Margen promedio: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>resumen_general[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'margen_promedio'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2%}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb7-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"ROI estimado: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>roi<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="cb7-14"></span>
<span id="cb7-15">tabla_resumen <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb7-16">    df_t.groupby([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"canal"</span>], as_index<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="cb7-17">    .agg(</span>
<span id="cb7-18">        ingreso_total<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;">"ingreso_neto"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>),</span>
<span id="cb7-19">        utilidad_total<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;">"utilidad"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>),</span>
<span id="cb7-20">        margen_promedio<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;">"margen_pct"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mean"</span>),</span>
<span id="cb7-21">        unidades_total<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;">"unidades"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>)</span>
<span id="cb7-22">    )</span>
<span id="cb7-23">    .sort_values(by<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;">"ingreso_total"</span>, ascending<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="cb7-24">)</span>
<span id="cb7-25"></span>
<span id="cb7-26">tabla_resumen</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Ingreso total: $1,516,059.34
Utilidad total: $586,009.69
Margen promedio: 38.69%
ROI estimado: 63.01%</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="4">
<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">region</th>
<th data-quarto-table-cell-role="th">canal</th>
<th data-quarto-table-cell-role="th">ingreso_total</th>
<th data-quarto-table-cell-role="th">utilidad_total</th>
<th data-quarto-table-cell-role="th">margen_promedio</th>
<th data-quarto-table-cell-role="th">unidades_total</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>Centro</td>
<td>Online</td>
<td>289649.28</td>
<td>110873.94</td>
<td>0.380867</td>
<td>2886</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">2</th>
<td>Norte</td>
<td>Online</td>
<td>263805.07</td>
<td>104656.98</td>
<td>0.400802</td>
<td>2857</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">5</th>
<td>Sur</td>
<td>Retail</td>
<td>252984.68</td>
<td>95124.82</td>
<td>0.376046</td>
<td>2894</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>Centro</td>
<td>Retail</td>
<td>239504.68</td>
<td>90415.85</td>
<td>0.382808</td>
<td>2800</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">3</th>
<td>Norte</td>
<td>Retail</td>
<td>238826.14</td>
<td>95155.41</td>
<td>0.392284</td>
<td>2866</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">4</th>
<td>Sur</td>
<td>Online</td>
<td>231289.49</td>
<td>89782.69</td>
<td>0.388458</td>
<td>2712</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
</section>
<section id="visualizaciones" class="level2">
<h2 class="anchored" data-anchor-id="visualizaciones">Visualizaciones</h2>
<p>Incluimos dos gráficas con Matplotlib y una interactiva con Plotly.</p>
<div id="85f3bf86" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:38.831814Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:38.831675Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:39.007025Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:39.006195Z&quot;}}" 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">ventas_mensuales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_t.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes"</span>, as_index<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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()</span>
<span id="cb9-2"></span>
<span id="cb9-3">plt.style.use(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ggplot"</span>)</span>
<span id="cb9-4">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(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;">9</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb9-5">ax.plot(ventas_mensuales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mes"</span>], ventas_mensuales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ingreso_neto"</span>], marker<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;">"o"</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="cb9-6">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Evolución de ingresos netos por mes"</span>)</span>
<span id="cb9-7">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mes"</span>)</span>
<span id="cb9-8">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ingreso neto ($)"</span>)</span>
<span id="cb9-9">ax.tick_params(axis<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;">"x"</span>, rotation<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;">45</span>)</span>
<span id="cb9-10">plt.tight_layout()</span>
<span id="cb9-11">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/machine-learning/ejemplo-post-completo/index_files/figure-html/cell-6-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="893af117" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:39.009684Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:39.009520Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:39.126155Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:39.124818Z&quot;}}" data-execution_count="6">
<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">utilidad_region <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df_t.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>, as_index<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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()</span>
<span id="cb10-2"></span>
<span id="cb10-3">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<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;">7.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>))</span>
<span id="cb10-4">bars <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ax.bar(utilidad_region[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>], utilidad_region[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utilidad"</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;">"#1f77b4"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#2ca02c"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#ff7f0e"</span>])</span>
<span id="cb10-5">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Utilidad acumulada por región"</span>)</span>
<span id="cb10-6">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Región"</span>)</span>
<span id="cb10-7">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Utilidad ($)"</span>)</span>
<span id="cb10-8"></span>
<span id="cb10-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> b <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> bars:</span>
<span id="cb10-10">    y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> b.get_height()</span>
<span id="cb10-11">    ax.text(b.get_x() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> b.get_width() <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>, y, <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<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:,.0f}</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>, 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;">"bottom"</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;">9</span>)</span>
<span id="cb10-12"></span>
<span id="cb10-13">plt.tight_layout()</span>
<span id="cb10-14">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/machine-learning/ejemplo-post-completo/index_files/figure-html/cell-7-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="6f4ab2e2" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:39.128457Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:39.128299Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:40.798519Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:40.797440Z&quot;}}" data-execution_count="7">
<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">scatter_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb11-2">    df_t.groupby([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"region"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"canal"</span>], as_index<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="cb11-3">    .agg(</span>
<span id="cb11-4">        ingreso_total<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;">"ingreso_neto"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>),</span>
<span id="cb11-5">        utilidad_total<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;">"utilidad"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>),</span>
<span id="cb11-6">        margen_promedio<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;">"margen_pct"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mean"</span>)</span>
<span id="cb11-7">    )</span>
<span id="cb11-8">)</span>
<span id="cb11-9"></span>
<span id="cb11-10">fig <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> px.scatter(</span>
<span id="cb11-11">    scatter_df,</span>
<span id="cb11-12">    x<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;">"ingreso_total"</span>,</span>
<span id="cb11-13">    y<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;">"utilidad_total"</span>,</span>
<span id="cb11-14">    size<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;">"margen_promedio"</span>,</span>
<span id="cb11-15">    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;">"region"</span>,</span>
<span id="cb11-16">    symbol<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;">"canal"</span>,</span>
<span id="cb11-17">    hover_data<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;">"margen_promedio"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">":.2%"</span>},</span>
<span id="cb11-18">    title<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;">"Ingreso vs utilidad por región/canal (interactivo)"</span></span>
<span id="cb11-19">)</span>
<span id="cb11-20">fig.update_layout(template<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;">"plotly_white"</span>)</span>
<span id="cb11-21">fig.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<pre><code>Unable to display output for mime type(s): application/vnd.plotly.v1+json</code></pre>
</div>
</div>
<section id="versión-estática-del-gráfico-interactivo" class="level3">
<h3 class="anchored" data-anchor-id="versión-estática-del-gráfico-interactivo">Versión estática del gráfico interactivo</h3>
<p>Medium (y otros importadores que no ejecutan JavaScript) no pueden mostrar el widget interactivo de Plotly de arriba. Por eso generamos también una versión estática (PNG) del mismo gráfico, para que sobreviva en plataformas sin soporte de JS.</p>
<div id="8111b00d" class="cell" data-quarto-private-1="{&quot;key&quot;:&quot;execution&quot;,&quot;value&quot;:{&quot;iopub.execute_input&quot;:&quot;2026-08-23T19:55:40.801023Z&quot;,&quot;iopub.status.busy&quot;:&quot;2026-08-23T19:55:40.800847Z&quot;,&quot;iopub.status.idle&quot;:&quot;2026-08-23T19:55:44.663920Z&quot;,&quot;shell.execute_reply&quot;:&quot;2026-08-23T19:55:44.662423Z&quot;}}" data-execution_count="8">
<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="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> IPython.display <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Image, display</span>
<span id="cb13-2"></span>
<span id="cb13-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Exportamos el mismo gráfico de Plotly como imagen estática (requiere el paquete kaleido).</span></span>
<span id="cb13-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Esta versión sí es un &lt;img&gt; normal en el HTML final, así que sobrevive al import de Medium.</span></span>
<span id="cb13-5">fig.update_layout(width<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;">900</span>, height<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;">520</span>)</span>
<span id="cb13-6">fig.write_image(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"plotly_scatter_static.png"</span>, scale<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="cb13-7"></span>
<span id="cb13-8">display(Image(filename<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;">"plotly_scatter_static.png"</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/machine-learning/ejemplo-post-completo/index_files/figure-html/cell-9-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
</section>
</section>
<section id="conclusiones" class="level2">
<h2 class="anchored" data-anchor-id="conclusiones">Conclusiones</h2>
<p>Este notebook cumple con una estructura técnica publicable: <strong>Título → Introducción → Datos → Exploración → Transformación → Estadísticas → Visualizaciones → Conclusiones</strong>.</p>
<p>Hallazgos ficticios: - El ingreso y la utilidad muestran variación moderada por mes. - Existen diferencias entre regiones y canales en margen promedio. - El formato incluye componentes útiles para validar exportación a HTML, blog y Medium.</p>
<p>Checklist visual rápida: - Caracteres especiales: á, é, í, ó, ú, ñ - Símbolos: ≥, ≤, %, $, → - Tabla ancha y bloque de código largo - Gráficas estáticas + gráfica interactiva</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>ejemplo</category>
  <category>machine-learning</category>
  <guid>https://biitt.com/es/blog/machine-learning/ejemplo-post-completo/</guid>
  <pubDate>Sun, 23 Aug 2026 05:00:00 GMT</pubDate>
  <media:content url="https://biitt.com/es/blog/machine-learning/ejemplo-post-completo/plotly_scatter_static.png" medium="image" type="image/png" height="83" width="144"/>
</item>
<item>
  <title>Big Data e Ingeniería de Datos</title>
  <link>https://biitt.com/es/blog/bigdata-ingenieria-datos/</link>
  <description><![CDATA[ 




<p>MapReduce, Hadoop (HDFS, YARN), Apache Spark, procesamiento distribuido y arquitecturas de datos en la nube.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">

</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/bigdata-ingenieria-datos/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
<item>
  <title>Deep Learning</title>
  <link>https://biitt.com/es/blog/deep-learning/</link>
  <description><![CDATA[ 




<p>Redes neuronales, arquitecturas modernas, entrenamiento y ajuste de modelos de aprendizaje profundo, con ejemplos prácticos y código reproducible.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">
<div class="quarto-post image-right" data-index="0" data-categories="ZGVlcC1sZWFybmluZyUyQ3BlcmNlcHRyb24lMkNtbHA=" data-listing-date-sort="1788152400000" data-listing-file-modified-sort="1788217162586" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="16" data-listing-word-count-sort="3198">
<div class="thumbnail"><a href="../deep-learning/01-perceptron-mlp/index.html" class="no-external">

<!-- img(9CEB782EFEE6)[progressive=false, height=]:listing:deep-learning/01-perceptron-mlp/index.html -->

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../deep-learning/01-perceptron-mlp/index.html" class="no-external">Perceptrón y MLP: de la neurona simple a las redes multicapa</a>
</h3>
<div class="delink listing-description"><a href="../deep-learning/01-perceptron-mlp/index.html" class="no-external">
<p>Implementación del perceptrón desde cero, compuertas lógicas y el problema XOR, resuelto con un Perceptrón Multicapa (MLP) aplicado a Iris, dígitos escritos a mano y reconocimiento de rostros.</p>
</a></div>
</div>
<div class="metadata">
<a href="../deep-learning/01-perceptron-mlp/index.html" class="no-external">
<div class="listing-date">
Aug 31, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
<div class="quarto-post image-right" data-index="1" data-categories="ZGVlcC1sZWFybmluZyUyQ2V2YWx1YWNpb24lMkNtZXRyaWNhcw==" data-listing-date-sort="1788066000000" data-listing-file-modified-sort="1788217162600" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="37" data-listing-word-count-sort="7218">
<div class="thumbnail"><a href="../deep-learning/02-evaluacion-modelos/index.html" class="no-external">

<img loading="lazy" src="https://biitt.com/es/blog/deep-learning/02-evaluacion-modelos/roc.png" class="thumbnail-image">

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../deep-learning/02-evaluacion-modelos/index.html" class="no-external">Evaluación de modelos: predicción, clasificación y desempeño</a>
</h3>
<div class="delink listing-description"><a href="../deep-learning/02-evaluacion-modelos/index.html" class="no-external">
<p>Métricas para evaluar modelos supervisados fuera de la muestra: MAE, MAPE y RMSE en regresión; matriz de confusión, F1 y AUC-ROC en clasificación.</p>
</a></div>
</div>
<div class="metadata">
<a href="../deep-learning/02-evaluacion-modelos/index.html" class="no-external">
<div class="listing-date">
Aug 30, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
<div class="quarto-post image-right" data-index="2" data-categories="ZGVlcC1sZWFybmluZyUyQ21scCUyQ2Z1bmRhbWVudG9z" data-listing-date-sort="1787979600000" data-listing-file-modified-sort="1788217162619" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="24" data-listing-word-count-sort="4639">
<div class="thumbnail"><a href="../deep-learning/03-fundamentos-entrenamiento-mlp/index.html" class="no-external">

<!-- img(9CEB782EFEE6)[progressive=false, height=]:listing:deep-learning/03-fundamentos-entrenamiento-mlp/index.html -->

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../deep-learning/03-fundamentos-entrenamiento-mlp/index.html" class="no-external">Fundamentos matemáticos del Deep Learning y entrenamiento de un MLP</a>
</h3>
<div class="delink listing-description"><a href="../deep-learning/03-fundamentos-entrenamiento-mlp/index.html" class="no-external">
<p>Vectores, matrices, funciones de activación, funciones de pérdida y descenso de gradiente: la base matemática para entrenar un MLP desde cero con NumPy.</p>
</a></div>
</div>
<div class="metadata">
<a href="../deep-learning/03-fundamentos-entrenamiento-mlp/index.html" class="no-external">
<div class="listing-date">
Aug 29, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/deep-learning/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
<item>
  <title>Estadística y Fundamentos</title>
  <link>https://biitt.com/es/blog/estadistica-fundamentos/</link>
  <description><![CDATA[ 




<p>Regresión, regularización, evaluación de modelos, remuestreo (bootstrap), suavización, modelos lineales generalizados (GLM), variables latentes y datos dependientes — estadística aplicada explicada paso a paso.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">
<div class="quarto-post image-right" data-index="0" data-categories="ZXN0YWRpc3RpY2ElMkNyZWdyZXNpb24tbGluZWFsJTJDc2Npa2l0LWxlYXJu" data-listing-date-sort="1787893200000" data-listing-file-modified-sort="1788217162497" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="23" data-listing-word-count-sort="4497">
<div class="thumbnail"><a href="../estadistica-fundamentos/01-regresion-lineal/index.html" class="no-external">

<!-- img(9CEB782EFEE6)[progressive=false, height=]:listing:estadistica-fundamentos/01-regresion-lineal/index.html -->

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../estadistica-fundamentos/01-regresion-lineal/index.html" class="no-external">Análisis Avanzado de Datos — 1. Regresión lineal</a>
</h3>
<div class="delink listing-description"><a href="../estadistica-fundamentos/01-regresion-lineal/index.html" class="no-external">
<p>Regresión lineal simple y múltiple: la fórmula cerrada, la forma matricial, interpretación de coeficientes y residuales, con ejercicios guiados en scikit-learn.</p>
</a></div>
</div>
<div class="metadata">
<a href="../estadistica-fundamentos/01-regresion-lineal/index.html" class="no-external">
<div class="listing-date">
Aug 28, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
<div class="quarto-post image-right" data-index="1" data-categories="ZXN0YWRpc3RpY2ElMkNhbmFsaXNpcy1tdWx0aXZhcmlhZG8lMkNyZWdyZXNpb24tbXVsdGlwbGU=" data-listing-date-sort="1787806800000" data-listing-file-modified-sort="1788217162524" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="30" data-listing-word-count-sort="5928">
<div class="thumbnail"><a href="../estadistica-fundamentos/02-analisis-multivariado/index.html" class="no-external">

<!-- img(9CEB782EFEE6)[progressive=false, height=]:listing:estadistica-fundamentos/02-analisis-multivariado/index.html -->

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../estadistica-fundamentos/02-analisis-multivariado/index.html" class="no-external">Análisis Avanzado de Datos — 1. Regresión Lineal Múltiple</a>
</h3>
<div class="delink listing-description"><a href="../estadistica-fundamentos/02-analisis-multivariado/index.html" class="no-external">
<p>Guía completa de análisis multivariado: supuestos de la regresión múltiple, multicolinealidad y VIF, cuándo regularizar y cómo diagnosticar los residuos paso a paso.</p>
</a></div>
</div>
<div class="metadata">
<a href="../estadistica-fundamentos/02-analisis-multivariado/index.html" class="no-external">
<div class="listing-date">
Aug 27, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
<div class="quarto-post image-right" data-index="2" data-categories="ZXN0YWRpc3RpY2ElMkNyZWd1bGFyaXphY2lvbiUyQ3JpZGdlLWxhc3Nv" data-listing-date-sort="1787720400000" data-listing-file-modified-sort="1788217162539" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="9" data-listing-word-count-sort="1697">
<div class="thumbnail"><a href="../estadistica-fundamentos/03-regresion-regularizacion/index.html" class="no-external">

<!-- img(9CEB782EFEE6)[progressive=false, height=]:listing:estadistica-fundamentos/03-regresion-regularizacion/index.html -->

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../estadistica-fundamentos/03-regresion-regularizacion/index.html" class="no-external">Análisis Avanzado de Datos — 1. Regresión y regularización (Ridge y Lasso)</a>
</h3>
<div class="delink listing-description"><a href="../estadistica-fundamentos/03-regresion-regularizacion/index.html" class="no-external">
<p>Por qué la regresión lineal se queda corta ante el sobreajuste, y cómo Ridge (L2) y Lasso (L1) equilibran sesgo y varianza, con comparación visual entre los tres enfoques.</p>
</a></div>
</div>
<div class="metadata">
<a href="../estadistica-fundamentos/03-regresion-regularizacion/index.html" class="no-external">
<div class="listing-date">
Aug 26, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/estadistica-fundamentos/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
<item>
  <title>IoT y AIoT</title>
  <link>https://biitt.com/es/blog/iot-aiot/</link>
  <description><![CDATA[ 




<p>Proyectos de Internet de las Cosas (IoT) e Inteligencia Artificial embebida en hardware (AIoT) usando ESP32: sensores, conectividad y modelos de ML corriendo directamente en el dispositivo.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">

</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/iot-aiot/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
<item>
  <title>MLOps y Producción</title>
  <link>https://biitt.com/es/blog/mlops-produccion/</link>
  <description><![CDATA[ 




<p>Automatización de pipelines de IA, despliegue de modelos, monitoreo, versionado y buenas prácticas para llevar modelos de Machine Learning a producción.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">

</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/mlops-produccion/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
<item>
  <title>Machine Learning</title>
  <link>https://biitt.com/es/blog/machine-learning/</link>
  <description><![CDATA[ 




<p>Algoritmos de aprendizaje supervisado y no supervisado, ingeniería de características, validación y evaluación de modelos, y estadística aplicada a la inteligencia artificial.</p>




<div class="quarto-listing quarto-listing-container-default" id="listing-listing">
<div class="list quarto-listing-default">
<div class="quarto-post image-right" data-index="0" data-categories="ZWplbXBsbyUyQ21hY2hpbmUtbGVhcm5pbmc=" data-listing-date-sort="1787461200000" data-listing-file-modified-sort="1788216419609" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="3" data-listing-word-count-sort="427">
<div class="thumbnail"><a href="../machine-learning/ejemplo-post-completo/index.html" class="no-external">

<img loading="lazy" src="https://biitt.com/es/blog/machine-learning/ejemplo-post-completo/plotly_scatter_static.png" class="thumbnail-image">

</a></div>
<div class="body">
<h3 class="no-anchor listing-title">
<a href="../machine-learning/ejemplo-post-completo/index.html" class="no-external">Ejemplo: flujo completo de un notebook publicado en el blog</a>
</h3>
<div class="delink listing-description"><a href="../machine-learning/ejemplo-post-completo/index.html" class="no-external">
<!-- desc(5A0113B34292)[max=175]:machine-learning/ejemplo-post-completo/index.html -->
</a></div>
</div>
<div class="metadata">
<a href="../machine-learning/ejemplo-post-completo/index.html" class="no-external">
<div class="listing-date">
Aug 23, 2026
</div>
<div class="listing-author">
Wilder Ramírez Delgado
</div>
</a>
</div>
</div>
</div>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://biitt.com/es/blog/machine-learning/</guid>
  <pubDate>Mon, 31 Aug 2026 23:12:51 GMT</pubDate>
</item>
</channel>
</rss>
