100 Días de Código en Python — Día 78: Regresión lineal con seaborn y scikit-learn — ¿más presupuesto, más taquilla?
Nivel: Grado décimo
Área: Tecnología e Informática
Modalidad: Tutorial práctico
Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 78 (nivel avanzado).
29 min de lectura
18 secciones
Este tutorial adapta pedagógicamente el Día 78. Las secciones 📝 Contenido original del curso provienen de las lecciones 574 a 582; el cuaderno de inicio y el archivo cost_revenue_dirty.csv están en los recursos del curso (Seaborn Linear Regression (start).zip). En varias lecciones parte del código aparece solo en imágenes; aquí se reconstruye y se verifica. Los retos 🟢🟡🟠🔴, la sección qué dice y qué no dice una regresión, el proyecto extra y la etapa 3 del Laboratorio de Datos Abiertos son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.
Nota sobre las verificaciones: el 27 de septiembre de 2026, con Python 3.14, pandas 3.0.6, seaborn 0.13.2, Matplotlib 3.11.2 y scikit-learn 1.9.1, y con una copia pública de cost_revenue_dirty.csv (publicada en GitHub por otro estudiante del mismo curso), se ejecutó todo el código. Los resultados coinciden con el curso: 5 391 películas sin faltantes ni duplicados; 512 sin ingresos en Estados Unidos y 357 sin ingresos mundiales; 7 sin estrenar; 37,2 % que no recupera su presupuesto; 153 películas anteriores a 1970; intercepto de −8,65 millones, pendiente de 3,12 y r² de 0,558 para las películas recientes. Hay dos diferencias importantes: la predicción de "unos 600 millones para una película de 350 millones" usa el modelo de las películas antiguas (el de peor ajuste, r² = 0,03), mientras que el modelo de las películas recientes predice unos 1 084 millones; y la afirmación de que "todas las películas del cuartil inferior pierden dinero" no se sostiene: del 25 % con menor presupuesto, pierde dinero el 51,6 %.
Hoy analizamos datos de presupuestos e ingresos de películas, ideales para probar dos herramientas nuevas: scikit-learn, para calcular una regresión lineal, y seaborn, una biblioteca de visualización construida sobre Matplotlib.
La pregunta: ¿los presupuestos más altos generan más ingresos en taquilla? Es decir, ¿un estudio debería gastar más en una película para ganar más?
Aprenderás a usar seaborn; a calcular e interpretar una regresión lineal con scikit-learn; a dibujar una regresión sobre un gráfico de dispersión; a agregar una tercera dimensión para crear un gráfico de burbujas; y a usar la división entera// para transformar datos.
Preparación: descarga el ZIP, sube el cuaderno a Google Drive, ábrelo con Colab y agrega cost_revenue_dirty.csv.
Prerequisitos: limpieza y conversión de tipos (Días 72 y 76), fechas (Día 73), gráficos de dispersión (Día 74) y la ecuación de la recta y = mx + b de matemáticas. En tu computador: pip install seaborn scikit-learn.
Reto 1: ¿cuántas filas y columnas?, ¿hay NaN?, ¿hay duplicados?, ¿de qué tipo son las columnas? Reto 2: convierte USD_Production_Budget, USD_Worldwide_Gross y USD_Domestic_Gross a número quitando $ y , (domestic = Estados Unidos). Reto 3: convierte Release_Date a fecha.
"Con cualquier conjunto de datos nuevo, primero miro .shape, .head(), .tail(), .info() y .sample()". Hay miles de películas y caracteres no numéricos en las columnas de dinero.
Para limpiar, un bucle anidado: una lista de caracteres por quitar y otra de columnas.
Python
12345678910111213
chars_to_remove =[',','$']
columns_to_clean =['USD_Production_Budget','USD_Worldwide_Gross','USD_Domestic_Gross']for col in columns_to_clean:for char in chars_to_remove:# Reemplaza cada carácter por una cadena vacía
data[col]= data[col].astype(str).str.replace(char,"")# Convierte la columna a número
data[col]= pd.to_numeric(data[col])
data.Release_Date = pd.to_datetime(data.Release_Date)
Resultado verificado: 5 391 filas y 6 columnas (Rank, Release_Date, Movie_Title y las tres de dinero). Tras la limpieza, las columnas de dinero son int64 y la fecha es datetime64.
¿Por qué un bucle anidado? El bucle exterior recorre columnas y el interior, caracteres: 3 × 2 = 6 reemplazos con 4 líneas. Si mañana aparece un tercer carácter (por ejemplo, un espacio), solo agregas ' ' a la lista. Es el principio DRY (Don't Repeat Yourself).
Otra forma(adaptación): una sola expresión regular que quita todo lo que no sea dígito:
Python
12
for col in columns_to_clean:
data[col]= pd.to_numeric(data[col].str.replace(r'[^\d]','', regex=True))
[^\d] significa "cualquier carácter que no sea un dígito". Es más corta, pero más difícil de leer si no conoces las expresiones regulares: elige la que tu equipo entienda.
💡 Formato de fecha: las fechas del CSV están en formato estadounidense (8/2/1915 = 2 de agosto). pd.to_datetime las interpreta como mes/día por defecto. Si tus datos son colombianos (día/mes), usa dayfirst=True o, mejor, format='%d/%m/%Y'.
La conversión dentro del bucle interior: si pd.to_numeric va dentro del segundo for, se intenta convertir cuando aún quedan $ → ValueError. Fíjate en la sangría: va en el bucle exterior.
Olvidar asignar:data[col].str.replace(...) sin data[col] = no cambia nada.
Aplicar .str a una columna ya numérica: si ejecutas la celda dos veces, la segunda vez astype(str) evita el error, pero es mejor ejecutar la limpieza una sola vez desde la carga (Reiniciar y ejecutar todo).
🟢 Reto 1: convierte el bucle en una función limpiar_columnas(df, columnas, caracteres) y úsala.
🟡 Reto 2: agrega una columna Profit = ingreso mundial − presupuesto. ¿Cuál es la película con mayor ganancia? ¿Y con mayor pérdida?
🟠 Reto 3: agrega una columna ROI (retorno) = ingreso mundial / presupuesto. ¿Qué película tiene el mayor retorno? ¿Por qué el ROI puede engañar con presupuestos muy pequeños?
Reto 1: ¿presupuesto promedio?, ¿ingreso mundial promedio?, ¿mínimos?, ¿el 25 % inferior gana o pierde?, ¿máximos?, ¿cuánto ganaron las películas de menor y mayor presupuesto? Casi todo se responde con .describe().
La película promedio cuesta unos 31 millones y gana unas 3 veces eso (≈ 89 millones).
"Todas las películas del cuartil inferior pierden dinero, porque su costo promedio es de 5 millones y solo ganan 3,8 millones".
El mínimo es 0 (películas nunca exhibidas o canceladas). El mayor presupuesto es de 425 millones y el mayor ingreso, 2 783 918 982 dólares.
La de menor presupuesto (My Date With Drew) costó 1 100 dólares y ganó 181 041. La de mayor presupuesto es Avatar.
Reto 2: ¿cuántas películas no ganaron nada en Estados Unidos? Reto 3: ¿y en el mundo?
Python
123456
zero_domestic = data[data.USD_Domestic_Gross ==0]print(f'Number of films that grossed $0 domestically {len(zero_domestic)}')# 512
zero_domestic.sort_values('USD_Production_Budget', ascending=False)
zero_worldwide = data[data.USD_Worldwide_Gross ==0]print(f'Number of films that grossed $0 worldwide {len(zero_worldwide)}')# 357
Las de mayor presupuesto sin ingresos se estrenan después de la recopilación de los datos (1 de mayo de 2018). ¿Por qué 512 contra 357? Porque algunas películas internacionales nunca se exhibieron en Estados Unidos, como Don Gato, el inicio de la pandilla (unos 4,5 millones de ingresos, 80 millones de presupuesto).
📖 Resultados verificados y una corrección importante#
Presupuesto promedio 31,1 millones; ingreso mundial promedio 88,9 millones; los valores extremos coinciden con el curso.
🛠️ Nota técnica (verificado):.describe() calcula los cuartiles de cada columna por separado. El 25 % del presupuesto (5 millones) y el 25 % del ingreso (3,87 millones) no corresponden a las mismas películas, así que compararlos no dice si "el cuartil inferior" pierde dinero. Hay que seleccionar las películas y compararlas fila por fila:
🟢 Reto 1: calcula el porcentaje de películas que pierden dinero en cada cuartil de presupuesto (pista: pd.qcut(data.USD_Production_Budget, 4) y groupby).
🟡 Reto 2: ¿qué porcentaje del ingreso mundial viene de Estados Unidos, en promedio? ¿Ha cambiado con los años?
pandas está construido sobre NumPy, que usa los operadores bitwise de Python para comparar elemento a elemento. Como estos operadores tienen mayor precedencia que las comparaciones, hay que poner paréntesis.
international_releases = data.query('USD_Domestic_Gross == 0 and USD_Worldwide_Gross != 0')print(f'Number of international releases: {len(international_releases)}')
Reto: identifica las películas sin estrenar a la fecha de recopilación (1 de mayo de 2018), cuéntalas y crea data_clean sin ellas. Hay 7:
Python
1
data_clean = data.drop(future_releases.index)
Reto adicional: ¿qué porcentaje de películas no recupera su presupuesto en taquilla?
Python
12345
money_losing = data_clean.loc[data_clean.USD_Production_Budget > data_clean.USD_Worldwide_Gross]len(money_losing)/len(data_clean)# o bien
money_losing = data_clean.query('USD_Production_Budget > USD_Worldwide_Gross')
money_losing.shape[0]/ data_clean.shape[0]
¡Un 37,2 %! "¿Quién diría que las finanzas del cine son tan riesgosas?".
scrape_date = pd.Timestamp('2018-5-1')
future_releases = data[data.Release_Date >= scrape_date]len(future_releases)# 7: A Wrinkle in Time, Amusement Park, Meg, Aquaman, Singularity...
Resultados verificados: 155 estrenos solo internacionales (con ambas formas); 5 384 películas en data_clean; 37,28 % no recupera su presupuesto.
Operadores de pandas contra palabras de Python:
Significado
En [...] y .loc
En .query('...')
En un if normal
Y
&
and
and
O
|
or
or
No
~
not
not
¿Por qué no and dentro de los corchetes? Porque and pregunta "¿toda esta columna es verdadera?", y una columna de miles de valores no es ni verdadera ni falsa. Verificado sin paréntesis:
Texto
1
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Ese mensaje aparece también si usas and en vez de &: cuando lo veas, revisa operadores y paréntesis.
🟢 Reto 1: ¿cuántas películas costaron más de 100 millones y perdieron dinero? Resuélvelo con & y con query.
🟡 Reto 2: usa | para encontrar las películas que costaron menos de 1 millón o ganaron más de 1 000 millones.
🟠 Reto 3: con query puedes usar variables con @: data.query('USD_Production_Budget > @limite'). Crea una función que reciba el límite y devuelva cuántas películas lo superan.
Seaborn (se abre en otra pestaña) está construido sobre Matplotlib y hace muy cómodas ciertas visualizaciones. Por convención se importa como sns.
Python
12345
import seaborn as sns
sns.scatterplot(data=data_clean,
x='USD_Production_Budget',
y='USD_Worldwide_Gross')
Como seaborn usa Matplotlib por debajo, podemos entrar a esa capa en cualquier momento: cambiar el tamaño de la figura o configurar el objeto Axes que devuelve sns.scatterplot():
Python
1234567891011121314
plt.figure(figsize=(8,4), dpi=200)
ax = sns.scatterplot(data=data_clean,
x='USD_Production_Budget',
y='USD_Worldwide_Gross',
hue='USD_Worldwide_Gross',# color
size='USD_Worldwide_Gross')# tamaño del punto
ax.set(ylim=(0,3000000000),
xlim=(0,450000000),
ylabel='Revenue in $ billions',
xlabel='Budget in $100 millions')
plt.show()
hue y size crean un gráfico de burbujas: las películas más taquilleras se ven más grandes y oscuras. Para aplicar un estilo a un solo gráfico se usa with (como al abrir archivos):
Python
12
with sns.axes_style('darkgrid'):
ax = sns.scatterplot(...)
Otros temas: 'whitegrid', 'dark', 'ticks'.
Reto: un gráfico de burbujas con fecha de estreno en x, presupuesto en y y el ingreso mundial como color y tamaño:
Análisis: los presupuestos "explotaron" en los últimos 40 años. Hasta los años 70 la industria parecía estar en otra era; los presupuestos crecieron rápido desde los 80 y siguieron creciendo en los 2000. La industria también produce muchísimas más películas: desde el 2000 los puntos se amontonan.
Leer el eje: el eje y va hasta 3 000 000 000; Matplotlib muestra 1e9 arriba del eje, que significa "multiplica por mil millones". De ahí la etiqueta "Revenue in $ billions". Una forma más legible es dividir los datos antes de graficar (por ejemplo, en millones).
Cuidado con las burbujas: usar la misma variable en hue y size es redundante (refuerza la idea, pero no agrega información). En el reto, en cambio, el gráfico muestra tres variables distintas: tiempo, presupuesto e ingreso.
Reto: crea una columna Decade (1992 y 1999 → 1990): 1) crea un DatetimeIndex a partir de Release_Date; 2) toma los años con .year; 3) usa la división entera //; 4) agrega la columna.
Python
12345678
dt_index = pd.DatetimeIndex(data_clean.Release_Date)
years = dt_index.year
5.0/2# 2.55.0//2# 2.0 (redondea hacia abajo)
decades = years //10*10
data_clean['Decade']= decades
Reto: crea old_films (antes de 1970, hasta 1969 incluido) y new_films (desde 1970). ¿Cuántas películas antiguas hay? ¿Cuál fue la más cara?
La división entera "corta" el último dígito y la multiplicación lo vuelve cero. Resultados verificados: 153 películas antiguas y 5 231 recientes; la década con más películas es la de 2000 (2 181).
Una forma más directa(adaptación): data_clean['Decade'] = data_clean.Release_Date.dt.year // 10 * 10 (verificado: mismo resultado). El accesor .dt evita crear el DatetimeIndex.
Se ve Cleopatra a la derecha, y muchas películas de bajo presupuesto que ganaron mucho más. La relación no es fuerte: muchos puntos están muy lejos de la línea.
Reto:regplot para new_films con fondo 'darkgrid', sin valores negativos en los ejes, etiquetas "Revenue in $ billions" y "Budget in $ millions", puntos azul oscuro (#2f4b7c) y línea naranja (#ff7c43). ¿Se ajusta mejor? ¿Cuánto ganaría una película de 150 millones?
El ajuste es mucho mejor: los puntos se alinean con la recta y el intervalo de confianza es más estrecho. Una película de 150 millones ganaría, según la recta, un poco menos de 500 millones. "Podemos estar bastante seguros de que hay una relación entre presupuesto e ingreso". Pero ¿qué parte de la variación explica el presupuesto? ¿Cuánto ingreso extra da cada dólar? Para eso hay que ver los números del modelo.
¿Qué es una regresión lineal? Es la recta que mejor pasa entre los puntos: la que hace más pequeña la suma de los errores al cuadrado (distancias verticales de cada punto a la recta). Se llama "de mínimos cuadrados".
¿Qué es la banda sombreada? El intervalo de confianza del 95 % de la recta: dónde podría estar la recta "verdadera" si repitiéramos el estudio con otras películas parecidas. Es angosta donde hay muchos datos y se ensancha donde hay pocos. No indica dónde caerá una película individual (eso sería mucho más ancho).
Verificado: según el modelo de las películas recientes, una de 150 millones ganaría ≈ 460 millones, coherente con "un poco menos de 500 millones".
Usamos una regresión univariada: una sola variable explicativa (el presupuesto), que en aprendizaje automático se llama feature (característica). La recta tiene la forma:
Texto
1
REVENUE = θ0 + θ1 · BUDGET
θ₀ (intercepto): el ingreso si el presupuesto fuera 0.
θ₁ (pendiente): cuánto ingreso extra da 1 dólar más de presupuesto.
Python
12345678910111213
from sklearn.linear_model import LinearRegression
regression = LinearRegression()# Variable(s) explicativa(s) o característica(s)
X = pd.DataFrame(new_films, columns=['USD_Production_Budget'])# Variable de respuesta u objetivo
y = pd.DataFrame(new_films, columns=['USD_Worldwide_Gross'])
regression.fit(X, y)# encuentra la mejor recta
regression.intercept_ # array([-8650768.00661042])
regression.coef_ # array([[3.12259592]])
regression.score(X, y)# r cuadrado: ≈ 0.558
LinearRegression "no quiere" series de pandas, por eso se crean DataFrames. intercept_ y coef_ son atributos del objeto; el guion bajo final es parte del nombre.
Interpretación:
Intercepto: si el presupuesto es 0, el ingreso estimado es de −8,65 millones. Absurdo: hemos obligado al modelo a ser una recta, y el modelo es más preciso donde hay más datos, no en los extremos.
Pendiente: por cada dólar extra de presupuesto, el ingreso aumenta 3,1 dólares. Quizás por eso los presupuestos crecieron tanto en 30 años.
r² = 0,558: el modelo explica cerca del 56 % de la variación del ingreso. Para un modelo tan simple, con una sola variable, es bastante bueno.
Reto: la regresión para old_films. La pendiente es 1,6 (positiva), pero el r² es muy bajo: el modelo lineal es inadecuado para las películas antiguas.
Reto: ¿cuánto ingreso estima el modelo para una película de 350 millones? "Unos 600 millones":
Python
123456
22821538+1.64771314*350000000
budget =350000000
revenue_estimate = regression.intercept_[0]+ regression.coef_[0,0]* budget
revenue_estimate =round(revenue_estimate,-6)print(f'The estimated revenue for a $350 film is around ${revenue_estimate:.10}.')
Resumen del día: bucles anidados para limpiar varias columnas; filtros con .loc[] y .query(); gráficos de burbujas con seaborn; estilos de seaborn y ajustes con Matplotlib; división entera; regresiones con seaborn; juzgar un modelo por su ajuste y su r²; regresiones y coeficientes con scikit-learn.
📖 Resultados verificados y una corrección importante#
Modelo
Intercepto
Pendiente
r²
Predicción para 350 millones
Películas recientes (1970 en adelante)
−8,65 millones
3,12
0,558
≈ 1 084 millones
Películas antiguas (antes de 1970)
22,82 millones
1,65
0,029
≈ 600 millones
🛠️ Nota técnica (verificado): los números de la predicción del curso (22821538 + 1.64771314 * 350000000) son el intercepto y la pendiente del modelo de las películas antiguas: en el cuaderno, la variable regression se reutilizó para el reto anterior. Ese modelo es el peor de los dos (r² = 0,03) y se construyó con películas de máximo 42 millones: estimar una de 350 millones es una extrapolación enorme. Con el modelo de las películas recientes la predicción es de unos 1 084 millones. Lección: dale a cada modelo su propio nombre (reg_nuevas, reg_antiguas).
🛠️ Nota técnica (verificado): el formato :.10 depende del número. Con 600 000 000 imprime 600000000.0, pero con 1 084 000 000 imprime 1.084e+09 (notación científica). Para dinero, usa un formato explícito: f'{revenue_estimate:,.0f}' → 1,084,000,000. Además, el texto dice "$350 film": falta "million".
Una forma más clara de predecir(adaptación, verificada):
new_films[['USD_Production_Budget']] (doble corchete) ya es un DataFrame: no hace falta pd.DataFrame(..., columns=...).
Xdebe tener 2 dimensiones (filas × características); con una serie, scikit-learn lanza ValueError: Expected a 2-dimensional container but got <class 'pandas.Series'>. En cambio, y sí puede ser una serie.
.predict() calcula θ₀ + θ₁·x por ti y funciona igual con 1 o con 13 características (Día 81).
¿Qué es X y qué es y en tu problema? ¿Qué unidades tiene la pendiente (dólares de ingreso por dólar de presupuesto)? ¿En qué rango de x tienes datos? ¿Tiene sentido x = 0?
"Las películas con más presupuesto tienden a ganar más"
Sí (pendiente positiva, r² = 0,56 en las recientes)
"Si un estudio gasta 1 dólar más, ganará 3,1 dólares más"
No necesariamente. Es una asociación. Las películas caras suelen tener actores famosos, secuelas y más publicidad: quizá eso, y no el gasto en sí, explica el ingreso
"Una película de 1 000 millones ganará unos 3 100 millones"
No. No hay ninguna película de ese presupuesto: es extrapolación
"El 44 % restante de la variación es azar"
No. Son factores que el modelo no incluye (género, estrellas, fecha, calidad…)
"El estudio gana el ingreso mundial"
No. El ingreso de taquilla se reparte con los cines y distribuidores, y no incluye publicidad ni otros costos
Tres preguntas antes de creer en un modelo:
¿Qué tan bien se ajusta? (el r² y el gráfico).
¿Estoy prediciendo dentro del rango de los datos?
¿Hay otras variables que podrían explicar la relación?
11
9. 🚀 Proyecto del día: asesoría para un estudio de cine#
Encuentra cinco problemas: falta quitar el $ antes de to_numeric (ValueError); and en lugar de & y sin paréntesis (ValueError: The truth value of a Series is ambiguous); // sobre una fecha en vez de sobre el año (.dt.year); X como serie (ValueError: Expected a 2-dimensional container); y la predicción para 1 000 millones es una extrapolación fuera del rango de los datos (máximo: 425 millones).
Durante al menos 20 días de clase, registren (con autorización de la tienda y del docente) la temperatura máxima del día (de un servicio meteorológico o de un termómetro del colegio) y el número de bebidas frías vendidas. Si no es posible, usen datos abiertos equivalentes (por ejemplo, temperatura del IDEAM y un registro de consumo de otra fuente) y documenten la fuente.
Limpien los datos: días sin clase, datos faltantes, registros mal escritos.
Hagan un gráfico de dispersión con regplot y ajusten un modelo con scikit-learn.
Interpreten la pendiente en palabras ("por cada grado más, se venden unas _ bebidas más").
Predigan las ventas para una temperatura dentro del rango observado y expliquen por qué no conviene predecir para 40 °C.
La predicción para la temperatura promedio es cercana al promedio de ventas (propiedad de la regresión lineal: la recta pasa por el punto de los promedios).
Ciclo de trabajo: formula el problema → inténtalo tú → consulta a la IA → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.
Actividad 1 — Verificar una conclusión. Muestra a una IA la tabla de .describe() y pregúntale si el 25 % inferior de las películas pierde dinero. Si dice que sí, pídele que lo compruebe fila por fila y compara con tu cálculo (51,6 %).
Actividad 2 — Causalidad. Pregunta a una IA: "Si la pendiente es 3,1, ¿cuánto ganará un estudio si aumenta su presupuesto en 10 millones?". ¿Distingue asociación de causalidad? ¿Menciona la extrapolación?
Actividad 3 — Documentación. Pide a una IA el código para predecir con LinearRegression. Compara su uso de predict, coef_ e intercept_ con la documentación de scikit-learn (sklearn.linear_model.LinearRegression), en especial la forma que deben tener X y y.
16
14. 🛠️ Correcciones técnicas al material original#
Archivo
Afirmación o comportamiento del curso
Observación
Tratamiento
576
"Todas las películas del cuartil inferior pierden dinero"
Los cuartiles de describe() son por columna; del 25 % de menor presupuesto pierde el 51,6 % (verificado)
Nota técnica de la sección 2
581
Predicción de ≈ 600 millones para 350 millones
Usa el modelo de películas antiguas (r² = 0,03, máximo 42 millones): extrapolación; el modelo reciente da ≈ 1 084 millones (verificado)
Nota técnica de la sección 7
581
f'{revenue_estimate:.10}'
Con otros valores imprime notación científica (1.084e+09, verificado); falta "million" en el texto
Nota técnica de la sección 7
581
"Por cada dólar extra, el ingreso aumenta 3,1 dólares"
Es una asociación, no un efecto causal garantizado
Sección 8
577
Código de future_releases (solo en imagen)
Reconstruido y verificado: 7 películas
Sección 3
579
pd.DatetimeIndex(...).year
Funciona; alternativa directa: .dt.year (verificado, mismo resultado)
Sección 5
580
El reto pide la etiqueta "Budget in $ millions"; la solución usa "$100 millions"
Diferencia menor entre enunciado y solución
—
577
Enlace a la documentación de Python 3.4 (operator)
El cuaderno del análisis de películas con los dos modelos y la tabla de pruebas superada.
El informe para el estudio de cine, con predicciones dentro del rango de los datos.
El análisis de la tienda escolar (proyecto extra).
La etapa 3 del Laboratorio de Datos Abiertos.
Cuaderno de errores: conversión dentro del bucle equivocado, and en vez de &, paréntesis olvidados, conclusiones por columna aplicadas a filas, // sobre fechas, X como serie, un modelo reutilizado con el mismo nombre, extrapolación, formato :.10, confundir asociación con causalidad.