<?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/estadistica-fundamentos/</link>
<atom:link href="https://biitt.com/es/blog/estadistica-fundamentos/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>Fri, 28 Aug 2026 05:00:00 GMT</lastBuildDate>
<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>
</channel>
</rss>
