Asignatura: Estadística Aplicada con Python y R
Programa: Ingeniería Agrícola — Universidad de Sucre
Grupos: 1 y 2
Tema: Series de tiempo: componentes (tendencia, estacionalidad, irregularidad), promedios móviles, índices estacionales, descomposición clásica, métodos de referencia, validación de pronósticos (MAE, RMSE, SMAPE) y pronóstico automático con AutoTS
Modalidad: Individual. Mismo repositorio de las Actividades 2 y 3 + hoja manuscrita escaneada dentro del repositorio (Lápiz y Algoritmo)
Duración: 2 sesiones de 2 horas + trabajo autónomo
Entregable único: la URL de tu
repositorio en GitHub
(https://github.com/TU_USUARIO/app-estadistica-agricola),
con la versión final v1.0-final publicada como
Release
Importante: esta es la actividad que cierra tu app. Hoy la página Series de tiempo, que quedó “en construcción” desde la Actividad 2, se vuelve funcional. No vuelvas a ejecutar
generar_datos.pynigenerar_muestra_regresion.py: tus datos y tus huellas deben seguir siendo los mismos.
La cooperativa ya sabe describir sus parcelas (EDA) y cuánto responde el rendimiento al riego (regresión). Ahora el gerente técnico hace la pregunta que todo productor del Caribe se hace cada año:
“¿Cuánto lloverá en los próximos meses? Necesito saber cuándo sembrar y en qué meses tendré que regar.”
Para responder trabajarás con la serie mensual de
precipitación 2015–2025 de tu municipio (el archivo
clima_mensual.csv que generaste en la Actividad 2) y
construirás un pronóstico para 2026 con AutoTS, una
librería de Python que prueba automáticamente decenas de modelos de
pronóstico y se queda con el mejor.
Analogía agrícola:
Metodología del Lápiz y el Algoritmo:
| Mecanismo | Qué lo hace personal |
|---|---|
| Mismos datos desde la Actividad 2 | clima_mensual.csv se generó con tu código: cada
estudiante tiene otra lluvia. La huella de 8 caracteres no debe
cambiar. |
| Huella de series | generar_muestra_series.py produce una huella de 6
caracteres a partir de tus 24 meses (p. ej. 10A982). El
docente la regenera. |
| Semilla de AutoTS = tu código | El concurso de modelos usa tu código como semilla, así que tu resultado es reproducible y distinto al de tus compañeros. |
| Cálculo a mano con tus 24 meses | La hoja debe tener tu letra, nombre, código y las tres huellas (Actividad 2, regresión y series). |
Historial de commits, etiqueta v1.0-final y
Release |
GitHub registra fecha, hora y autor de todo el semestre. |
| Bitácora de IA | Tus prompts, lo que aceptaste, rechazaste y corregiste, y tu reflexión de cierre del semestre. |
Si dos repositorios tienen hallazgos o bitácoras idénticos, ambos estudiantes presentan una sustentación oral corta antes de asignar la nota.
Objetivo general
Completar la aplicación de Streamlit con una página de series de tiempo que analice y pronostique la precipitación mensual con AutoTS, construida con apoyo supervisado de GitHub Copilot en modo Agente, y verificar a mano y con Python y R los fundamentos del pronóstico y de su validación.
Objetivos específicos
src/series.py y la página Series de
tiempo, y revisar críticamente el código generado.v1.0-final,
Release en GitHub y README final.| Competencia | Resultado de aprendizaje | Estrategia pedagógica |
|---|---|---|
| Razonamiento cuantitativo manual (Lápiz y Algoritmo) | Calcula a mano promedios móviles, índices estacionales, pronósticos de referencia y sus métricas de error para 24 meses | Hoja manuscrita en dos partes (A y B) |
| Modelación de series de tiempo | Reconoce los componentes de una serie y explica cómo se valida un pronóstico separando entrenamiento y validación | Gráfico a mano + validación hacia atrás manual |
| Verificación computacional y reproducibilidad | Contrasta sus resultados manuales con Python y R, y documenta las diferencias | verificar_series.py, verificar_series.R y
RESULTADOS_SERIES.md |
| Pronóstico automático (AutoML) | Ejecuta AutoTS, interpreta el modelo ganador y su intervalo de predicción, y lo compara con los métodos de referencia | pronostico_autots.py + página Series de tiempo |
| Desarrollo de software asistido por IA | Dirige y supervisa a un agente para construir un módulo y una página de Streamlit con una librería nueva, y valida su salida | Prompts 7 y 9 (modo Agent) + Prompt 8 (modo Ask) |
| Gestión de versiones (Git/GitHub) | Mantiene el historial de un proyecto de semestre, etiqueta la versión final y publica un Release | Panel Control de código fuente, git tag,
Releases |
| Interpretación agronómica y pensamiento crítico | Traduce el pronóstico en recomendaciones de siembra y riego, reconociendo su incertidumbre | Sección “Hallazgos de series de tiempo” del README |
| Uso ético y crítico de la IA | Documenta qué aceptó, rechazó o corrigió del agente y reflexiona sobre el uso de AutoML | Bitácora de IA (Hoja de Ruta para la Adopción Ética y Sostenible de la IA en Colombia, 2024) |
La cuota del agente es limitada: usa cada prompt una sola vez, completo. El Prompt 8 se hace en modo Ask, que no modifica archivos.
Ctrl+Shift+G), o en la terminal:git pull # trae cualquier cambio hecho en GitHub
git tag # debe aparecer v0.3-regresion (Actividad 3)
cat datos/metadatos.json # tu huella debe ser la MISMA de tu README
Esta vez tú agregas la librería nueva, sin el agente, para entender cómo se gestionan las dependencias de un proyecto.
requirements.txt en el editor y agrega al
final estas dos líneas:scikit-learn
autots
Ctrl+S) e instala con el Python del entorno
virtual:.venv/bin/pip install -r requirements.txt # instala solo lo que falta (AutoTS y scikit-learn)
.venv/bin/python -c "import autots; print('AutoTS', autots.__version__)" # verifica la instalación
[manual] Agrega AutoTS y scikit-learn a requirements.txt →
Commit → Sync Changes.¿Por qué scikit-learn? AutoTS lo necesita para varios de sus modelos y transformaciones. Escribirlo en
requirements.txtdeja claro que tu proyecto depende de él, aunque pip lo instale de todas formas.
generar_muestra_series.py en la
raíz del proyecto..venv/bin/python generar_muestra_series.py # usa tu clima_mensual.csv de la Actividad 2
datos/muestra_series.csv y
datos/metadatos_series.json. En la terminal verás tu
huella de series y una tabla de 24 filas con el
periodo, la fecha, el mes, la precipitación y si el mes es de
entrenamiento (enero 2024 – junio 2025) o de
validación (julio – diciembre 2025).[manual] Agrega serie de 24 meses para series de tiempo →
Commit → Sync Changes.git status # debe decir: nothing to commit, working tree clean
Luego github.com/codespaces → … → Stop codespace. La Parte A es solo con lápiz.
Notación: \(y_t\) = precipitación del mes \(t\) (mm), con \(t = 1\) (enero 2024) hasta \(t = 24\) (diciembre 2025).
A1. Predicción previa (3–4 líneas, antes de calcular). Mirando la tabla: ¿cuáles crees que son los meses más lluviosos y los más secos? ¿Ves dos temporadas de lluvia o una sola? ¿2025 fue más lluvioso que 2024?
A2. Gráfico de línea a mano. En papel cuadriculado: eje horizontal = periodo \(t\) (1 a 24), eje vertical = precipitación (mm). Une los puntos con líneas. Traza una línea vertical punteada entre \(t = 18\) y \(t = 19\) para separar entrenamiento y validación.
A3. Componentes. Sobre tu gráfico, señala con flechas y explica en 3–4 líneas:
A4. Promedio móvil de orden 3 para los 12 meses de 2025 (\(t = 13\) a \(24\)):
\[PM_3(t) = \frac{y_{t-2} + y_{t-1} + y_t}{3}\]
| \(t\) | Fecha | \(y_t\) | \(PM_3(t)\) |
|---|---|---|---|
| 13 | 2025-01 | \((y_{11}+y_{12}+y_{13})/3 =\) | |
| … | … | ||
| 24 | 2025-12 |
Dibuja los valores de \(PM_3\) en rojo sobre tu gráfico. ¿Qué le pasó a la serie? ¿Por qué el promedio móvil “llega tarde” a los picos?
A5. Índices estacionales aditivos.
| Mes | \(y_{2024}\) | \(y_{2025}\) | \(\bar y_{mes}\) | \(IE_{mes}\) |
|---|---|---|---|---|
| Enero | ||||
| … | ||||
| Diciembre | ||||
| Σ | ≈ 0 |
Control: la suma de los 12 índices debe dar aproximadamente 0. Un \(IE\) positivo significa que ese mes llueve por encima del promedio; uno negativo, por debajo.
A6. Interpretación agronómica (4–5 líneas).
Analogía: el índice estacional es como la “costumbre” de cada mes. Enero tiene la costumbre de ser seco y octubre la de ser lluvioso. El índice mide qué tan fuerte es esa costumbre, en milímetros.
Vas a hacer lo mismo que AutoTS: esconder los últimos 6 meses (julio–diciembre 2025), pronosticarlos solo con los 18 meses de entrenamiento y medir qué método se equivoca menos.
B1. Tres pronósticos para julio–diciembre 2025 (estos tres métodos también compiten dentro de AutoTS):
| Método | Regla | Nombre en AutoTS |
|---|---|---|
| Ingenuo | \(\hat y_{t} = y_{18}\) (repite junio 2025 en los 6 meses) | LastValueNaive |
| Estacional ingenuo | \(\hat y_{t} = y_{t-12}\) (repite el mismo mes de 2024) | SeasonalNaive |
| Promedio | \(\hat y_{t} = \dfrac{\sum_{t=1}^{18} y_t}{18}\) (media del entrenamiento) | AverageValueNaive |
B2. Tabla de errores, una por método, con \(e_t = y_t - \hat y_t\):
| \(t\) | Fecha | \(y_t\) (real) | \(\hat y_t\) | \(e_t\) | \(\lvert e_t \rvert\) | \(e_t^2\) | \(\dfrac{\lvert e_t\rvert}{\lvert y_t\rvert + \lvert \hat y_t\rvert}\) |
|---|---|---|---|---|---|---|---|
| 19 | 2025-07 | ||||||
| … | |||||||
| 24 | 2025-12 | ||||||
| Σ |
B3. Métricas de error (las mismas que usa AutoTS), con \(h = 6\) meses:
\[MAE = \frac{\sum \lvert e_t \rvert}{h} \qquad RMSE = \sqrt{\frac{\sum e_t^2}{h}} \qquad SMAPE = \frac{200}{h}\sum \frac{\lvert e_t \rvert}{\lvert y_t \rvert + \lvert \hat y_t \rvert} \;(\%)\]
B4. Resultado del concurso.
| Método | MAE (mm) | RMSE (mm) | SMAPE (%) | Puesto |
|---|---|---|---|---|
| Ingenuo | ||||
| Estacional ingenuo | ||||
| Promedio |
B5. Pronóstico con el ganador. Con el método ganador, pronostica enero a junio de 2026 usando ahora los 24 meses. (Si ganó el estacional ingenuo, repite enero–junio de 2025; si ganó el promedio, usa la media de los 24 meses; si ganó el ingenuo, repite diciembre 2025.)
B6. Reflexión (5–6 líneas).
Escanea las Partes A y B en un solo PDF con el
nombre hoja_series.pdf.
evidencias/ → Add file
→ Upload files → hoja_series.pdf → mensaje
[web] Agrega hoja manuscrita de series de tiempo →
Commit changes.README.md → lápiz → agrega al final la
sección del Anexo D (los hallazgos los completas en el
Paso 12) → mensaje
[web] Agrega sección de series de tiempo al README →
Commit changes.verificacion/ crea los dos scripts del Anexo
B..venv/bin/python verificacion/verificar_series.py # verifica tu cálculo a mano
datos/muestra_series.csv y verificar_series.R
a un proyecto y ejecuta el script.verificacion/RESULTADOS_SERIES.md con la plantilla
del Anexo B. Si algún valor no coincide, busca
el error en tu hoja; no cambies la hoja para que coincida.Antes de pedirle al agente la página, ejecuta tú mismo AutoTS para ver cómo trabaja.
pronostico_autots.py en la raíz con el
código del Anexo C (cópialo textual; está comentado
línea por línea: léelo antes de ejecutarlo)..venv/bin/python pronostico_autots.py # el concurso de modelos de AutoTS
resultados/ con
autots_pronostico.csv,
autots_top10_modelos.csv y
autots_mejor_modelo.json.SeasonalNaive en el top 10? ¿En qué puesto?
¿Qué SMAPE tiene comparado con el ganador?Nota: el SMAPE de AutoTS no es directamente comparable con el de tu hoja, porque AutoTS valida con horizontes de 12 meses y con varias ventanas de 2015–2025, mientras tú validaste 6 meses. Lo comparable es el método: hiciste a mano lo mismo que AutoTS hace por dentro.
En el chat de Copilot, modo Agent:
Actúa como tutor de Python, Streamlit y series de tiempo para estudiantes de Ingeniería Agrícola.
Responde en español y explica en una o dos líneas cada paso antes de ejecutarlo.
Mi app de Streamlit tiene app.py, src/eda.py, src/regresion.py y pages/ (1_Datos, 2_EDA,
3_Regresion y 4_Series_de_tiempo, que está en construcción). En datos/ hay:
- clima_mensual.csv: fecha (mensual 2015-2025), precipitacion_mm, temperatura_c.
- muestra_series.csv: periodo, fecha, anio, mes, precipitacion_mm, conjunto
(entrenamiento = 18 meses, validacion = 6 meses) de mi cálculo a mano.
- metadatos.json y metadatos_series.json (huella_series).
En resultados/ están las salidas de pronostico_autots.py.
NO modifiques datos/, resultados/, los scripts generar_*.py ni pronostico_autots.py.
Usa .venv/bin/python y .venv/bin/pip y solo librerías de requirements.txt (incluye autots).
1. Crea src/series.py con funciones documentadas (docstrings) y comentadas paso a paso:
a) cargar_serie(variable) que devuelva un DataFrame con índice de fechas y frecuencia "MS".
b) promedio_movil(serie, orden) con rolling.
c) indices_estacionales(serie) aditivos: promedio de cada mes menos el promedio general.
d) descomponer(serie) con seasonal_decompose de statsmodels, modelo aditivo, period=12.
e) metodos_referencia(entrenamiento, h): pronósticos ingenuo (último valor), estacional
ingenuo (mismo mes del año anterior) y promedio, para h meses.
f) metricas(real, pronostico): MAE, RMSE y SMAPE = 200·media(|e| / (|real| + |pronóstico|)).
g) ejecutar_autots(serie, horizonte, model_list, generaciones, validaciones, intervalo,
semilla) usando AutoTS con frequency="MS", ensemble=None, transformer_list="superfast",
validation_method="backwards", no_negatives=True, n_jobs=1 y verbose=0; que devuelva
el pronóstico con límites inferior y superior, el nombre y los parámetros del mejor
modelo y la tabla model.results("validation") con Model, smape, mae, rmse y Score.
2. Reemplaza pages/4_Series_de_tiempo.py por una página funcional con estas secciones:
a) "Exploración": selector de variable (precipitacion_mm o temperatura_c); gráfico de línea
con promedios móviles de 3 y 12 meses; diagrama de caja por mes (estacionalidad).
b) "Descomposición clásica": gráficos de serie observada, tendencia, estacionalidad y
residuo; tabla de índices estacionales por mes con nombres de los meses en español.
c) "Pronóstico automático con AutoTS": en un st.form, horizonte (6 a 24 meses, por defecto
12), lista de modelos ("superfast" o "fast"), generaciones (1 a 10, por defecto 5),
validaciones (1 a 3, por defecto 2) e intervalo (0.8, 0.9 o 0.95). Al presionar
"Ejecutar AutoTS", usar st.spinner y guardar el resultado con st.cache_resource para no
repetir el cálculo; la semilla es mi código estudiantil de metadatos.json.
Mostrar: modelo ganador y sus parámetros en st.json; gráfico de la serie histórica con el
pronóstico y la banda del intervalo; tabla del pronóstico; top 10 de modelos en
validación; botón para descargar el pronóstico en CSV; y un st.info que explique que
AutoTS funciona como un ensayo de variedades con selección genética.
d) "Resultados guardados": si existen los archivos de resultados/, mostrar el modelo ganador
y el pronóstico de pronostico_autots.py (para que la página funcione sin volver a correr).
e) "Mi serie de 24 meses (verificación del cálculo a mano)": huella_series; tabla con PM3;
índices estacionales; los tres pronósticos de julio a diciembre 2025 junto a los valores
reales; tabla de MAE, RMSE y SMAPE ordenada por SMAPE; método ganador; y un gráfico con
la serie, la línea vertical que separa entrenamiento y validación, y los tres pronósticos.
3. En app.py, actualiza la descripción: todas las páginas están disponibles (versión final).
Requisitos: textos en español; ejes con unidades; código comentado paso a paso.
No hagas commits. Al final ejecuta:
.venv/bin/streamlit run app.py --server.headless true
y dime cómo abrir la app desde la pestaña Puertos (puerto 8501). Si hay errores, corrígelos.
Supervisa al agente:
prophet, tensorflow,
xgboost u otras librerías que no estén en
requirements.txt: AutoTS funciona sin ellas con
superfast.src/series.py que el SMAPE use
200 y \(\lvert real\rvert +
\lvert pronóstico\rvert\), y que el estacional ingenuo use el
valor de 12 meses atrás. Si el agente se equivoca,
corrígelo y anótalo.evidencias/:
captura_autots.png (sección c, con el gráfico del
pronóstico) y captura_serie24.png (sección e).Ctrl+C en la terminal.Cambia el selector del chat a Ask y pega:
Sin modificar ningún archivo, explícame en lenguaje sencillo, para un estudiante de
Ingeniería Agrícola: 1) cómo AutoTS elige el mejor modelo con validation_method="backwards"
y num_validations=2; 2) qué hace su algoritmo genético en cada generación; 3) qué significa
la columna Score de model.results("validation") y por qué combina varias métricas; y
4) en qué se parece y en qué se diferencia todo esto de comparar a mano los métodos ingenuo,
estacional ingenuo y promedio con 6 meses de validación.
En la bitácora responde: ¿la explicación es correcta y coherente con lo que hiciste a mano? Señala una idea que confirmaste y cualquier imprecisión que encuentres.
README.md, completa “Hallazgos de series
de tiempo” (8–12 líneas, escritas por ti, no
por la IA):
SeasonalNaive.BITACORA_IA.md, agrega al final la sección del
Anexo E, incluida la reflexión de cierre del
semestre.[manual] Agrega verificación, hallazgos de series y bitácora final
→ Commit → Sync Changes.Vuelve al modo Agent:
Actúa como mi asistente de control de versiones con Git. Explica cada comando antes de
ejecutarlo y espera mi aprobación.
1. Ejecuta git status y confirma que .venv/ NO aparece; si aparece, corrige .gitignore primero.
2. Ejecuta git pull.
3. Agrupa los archivos pendientes en commits separados y lógicos (por ejemplo: src/series.py;
pages/4_Series_de_tiempo.py y app.py; pronostico_autots.py y resultados/; evidencias/).
Cada mensaje en español debe empezar por "[agente]".
4. Crea la etiqueta anotada: git tag -a v1.0-final -m "Versión final: EDA, regresión y series de tiempo"
5. Ejecuta git push --follow-tags y muéstrame git log --oneline -20 y git tag.
6. Resume en 5 líneas la historia de mi repositorio durante el semestre a partir del git log.
Si ya no tienes archivos pendientes, pídele primero un cambio pequeño (por ejemplo, un pie de página en
pages/4_Series_de_tiempo.pycon la fecha de actualización) y después usa el Prompt 9.
v1.0-final → título
App de Estadística Aplicada — versión final 2026-2 → en la
descripción, 3–4 líneas con lo que hace tu app → Publish
release..venv y que
la etiqueta v0.3-regresion también existe.app-estadistica-agricola/
├── README.md ← ★ sección "Series de tiempo" y hallazgos
├── .gitignore .vscode/settings.json
├── requirements.txt ← ★ + scikit-learn y autots (agregados a mano)
├── generar_datos.py generar_muestra_regresion.py ← NO se vuelven a ejecutar
├── generar_muestra_series.py ← ★ Anexo A (sin modificar)
├── pronostico_autots.py ← ★ Anexo C
├── app.py ← ★ descripción de la versión final
├── src/
│ ├── __init__.py eda.py regresion.py
│ └── series.py ← ★ funciones de series de tiempo y AutoTS
├── pages/
│ ├── 1_Datos.py 2_EDA.py 3_Regresion.py
│ └── 4_Series_de_tiempo.py ← ★ página funcional (5 secciones)
├── datos/
│ ├── parcelas.csv clima_mensual.csv muestra10.csv metadatos.json
│ ├── muestra_regresion.csv metadatos_regresion.json
│ └── muestra_series.csv metadatos_series.json ← ★
├── resultados/ ← ★ salidas de AutoTS
│ └── autots_pronostico.csv autots_top10_modelos.csv autots_mejor_modelo.json
├── verificacion/
│ ├── (archivos de las Actividades 2 y 3)
│ └── verificar_series.py verificar_series.R RESULTADOS_SERIES.md ← ★
├── evidencias/
│ ├── (archivos de las Actividades 2 y 3)
│ └── hoja_series.pdf captura_autots.png captura_serie24.png ← ★
└── BITACORA_IA.md ← ★ sección de la Actividad 4 + reflexión del semestre
Historial mínimo de commits en esta actividad: 3
[manual] + 2 [web] + 2 [agente],
distribuidos en las dos sesiones; etiqueta v1.0-final y
Release publicado.
Escala de 0,0 a 5,0. Nota de la actividad = Σ (nota del criterio × peso), redondeada a un decimal.
| # | Criterio | Peso | Excelente (4,6–5,0) | Bueno (3,6–4,5) | Aceptable (3,0–3,5) | Insuficiente (0,0–2,9) |
|---|---|---|---|---|---|---|
| 1 | Continuidad del repositorio e identificación | 10 % | Mismo repositorio del semestre; huellas de las Actividades 2 y 3 sin
cambios; generar_muestra_series.py sin modificar; huella de
series correcta en README y hoja; AutoTS y scikit-learn agregados a mano
en requirements.txt |
Completo con un detalle menor (falta una huella en la hoja o en el README) | Repositorio nuevo o archivo del Anexo A modificado, pero con datos propios | Huellas que no corresponden al código, datos regenerados o repositorio inaccesible |
| 2 | Lápiz y Algoritmo — Parte A: componentes, promedio móvil e índices estacionales | 20 % | Predicción previa; gráfico de línea a mano con separación entrenamiento/validación; componentes señalados; \(PM_3\) de 2025 correcto y graficado; índices estacionales correctos con control Σ ≈ 0; interpretación de siembra y riego | Cálculos correctos con un error menor o sin predicción previa | Errores de procedimiento o tablas incompletas | Ausente, no manuscrito o con una serie distinta a la asignada |
| 3 | Lápiz y Algoritmo — Parte B: concurso de métodos, métricas y verificación con Python y R | 15 % | Tres pronósticos correctos; tablas de errores; MAE, RMSE y SMAPE
correctos; ganador justificado y discusión si las métricas difieren;
pronóstico enero–junio 2026; reflexión;
RESULTADOS_SERIES.md comparando manual, Python y R |
Correcto con un error menor o falta el pronóstico 2026 o la reflexión | Métricas incompletas o verificación en un solo lenguaje | Sin Parte B o sin verificación |
| 4 | AutoTS y página Series de tiempo en Streamlit | 20 % | pronostico_autots.py ejecutado con
resultados/ en el repositorio; src/series.py
documentado; las 5 secciones funcionando con sus datos;
AutoTS ejecutable desde la app con caché; sección de verificación
coincide con la hoja; capturas en evidencias/ |
Falta una sección o un detalle (p. ej. sin banda de intervalo o sin caché) | Varias secciones ausentes o AutoTS solo funciona desde la terminal | Sin AutoTS, página que no corresponde a sus datos o sin evidencia de funcionamiento |
| 5 | Interpretación agronómica y estadística | 15 % | Hallazgos propios (8–12 líneas) con cifras y unidades: meses
lluviosos y secos con índices, ganador a mano y de AutoTS, puesto de
SeasonalNaive, pronóstico 2026 con su incertidumbre,
recomendación de siembra y riego, y límites del modelo |
Hallazgos correctos pero faltan 1–2 aspectos | Hallazgos superficiales, sin cifras o genéricos | Sin hallazgos, o texto generado por IA sin relación con sus datos |
| 6 | Control de versiones y versión final | 10 % | ≥ 3 commits [manual], ≥ 2 [web], ≥ 2
[agente]; etiqueta v1.0-final y
Release publicado con descripción; trabajo distribuido en las
dos sesiones |
Cumple el mínimo pero sin Release o con mensajes poco descriptivos | Falta un tipo de commit o la etiqueta | Uno o dos commits con todo el trabajo, o subido con Upload files sin usar Git |
| 7 | Bitácora de IA y reflexión del semestre | 10 % | Los 3 prompts exactos; qué aprobó, rechazó o corrigió y por qué; respuestas sobre el ganador de AutoTS; evaluación argumentada del modo Ask; reflexión de cierre del semestre honesta y concreta; declara que detuvo el Codespace | Bitácora completa pero con poco detalle | Bitácora genérica o sin reflexión del semestre | Sin sección de la Actividad 4 en la bitácora |
| Lo que ves | Solución |
|---|---|
| Mi Codespace ya no aparece | Crea uno nuevo desde Code → Codespaces y recrea el
entorno:
python -m venv .venv && .venv/bin/pip install -r requirements.txt.
No vuelvas a ejecutar los scripts
generar_datos.py ni
generar_muestra_regresion.py |
ModuleNotFoundError: autots |
Instalaste fuera del entorno: usa
.venv/bin/pip install -r requirements.txt y ejecuta con
.venv/bin/python |
| AutoTS tarda más de 5 minutos | Baja max_generations a 2 y num_validations
a 1. El Codespace de 2 núcleos es modesto |
| AutoTS muestra muchas advertencias en la terminal | Es normal: algunos modelos fallan y AutoTS los descarta. Lo importante es el modelo ganador al final |
El agente quiere instalar prophet,
tensorflow o xgboost |
Rechaza: con model_list="superfast" no se
necesitan |
| La app se “congela” al ejecutar AutoTS | Espera el spinner. Si se repite el cálculo cada vez que mueves un
control, falta st.cache_resource o el
st.form |
| Mi SMAPE a mano no coincide con Python | Revisa que uses 200 (no 100) y la suma de valores absolutos en el denominador |
| El estacional ingenuo me da valores raros | Debe repetir julio–diciembre 2024, no los meses anteriores de 2025 |
| El SMAPE de AutoTS es distinto al de mi hoja | Es esperado: AutoTS valida 12 meses en varias ventanas; tú validaste 6 meses. Compara el método, no el número |
| No encuentro Releases | En la página principal del repositorio, columna derecha; o en
https://github.com/TU_USUARIO/app-estadistica-agricola/releases |
| “You’ve reached your monthly chat/agent limit” | Se agotó la cuota: crea los archivos con ayuda de otro asistente o a mano y anótalo en la bitácora |
generar_muestra_series.pyCopia el código textual. No modifiques
ninguna línea. Ejecútalo desde la raíz con
.venv/bin/python generar_muestra_series.py.
"""
generar_muestra_series.py
Extrae TUS 24 meses de precipitación (enero 2024 - diciembre 2025) para el cálculo A MANO
de series de tiempo: promedios móviles, índices estacionales y validación de pronósticos.
Asignatura: Estadística Aplicada con Python y R · Ingeniería Agrícola · Unisucre
Requisito: tener datos/clima_mensual.csv, creado en la Actividad 2 con TU código.
NO modifiques este archivo.
"""
import hashlib # para calcular la "huella" de tu serie
import json # para leer y guardar metadatos
from pathlib import Path
import pandas as pd
# ------------------------------------------------------------------
# 1. Leer tu serie mensual de clima y tus metadatos (Actividad 2)
# ------------------------------------------------------------------
clima = pd.read_csv("datos/clima_mensual.csv", parse_dates=["fecha"])
meta = json.loads(Path("datos/metadatos.json").read_text(encoding="utf-8"))
# ------------------------------------------------------------------
# 2. Tomar los últimos 24 meses: enero 2024 a diciembre 2025
# ------------------------------------------------------------------
serie = clima[(clima["fecha"] >= "2024-01-01") & (clima["fecha"] <= "2025-12-01")].copy()
serie["periodo"] = range(1, len(serie) + 1) # t = 1, 2, ..., 24
serie["anio"] = serie["fecha"].dt.year
serie["mes"] = serie["fecha"].dt.month
# Partición para validar pronósticos (igual que hace AutoTS con validation_method="backwards"):
# entrenamiento = enero 2024 a junio 2025 (18 meses)
# validación = julio a diciembre 2025 (6 meses)
serie["conjunto"] = ["entrenamiento"] * 18 + ["validacion"] * 6
serie = serie[["periodo", "fecha", "anio", "mes", "precipitacion_mm", "conjunto"]]
serie["fecha"] = serie["fecha"].dt.strftime("%Y-%m")
serie.to_csv("datos/muestra_series.csv", index=False)
# ------------------------------------------------------------------
# 3. Huella de la serie (el docente la regenera con tu código)
# ------------------------------------------------------------------
huella_series = hashlib.md5(
f"{meta['codigo']}|{serie['precipitacion_mm'].sum():.1f}".encode()).hexdigest()[:6].upper()
Path("datos/metadatos_series.json").write_text(
json.dumps({"codigo": meta["codigo"], "huella_series": huella_series},
ensure_ascii=False, indent=2), encoding="utf-8")
print(f"Estudiante: {meta['nombre']} | Código: {meta['codigo']} | Municipio: {meta['municipio']}")
print(f"Huella de la serie: {huella_series}")
print("\nPrecipitación mensual (mm) — copia esta tabla en tu hoja")
print(serie.to_string(index=False))
verificacion/verificar_series.py
# verificar_series.py — Fase 2 del Lápiz y Algoritmo (verificación con Python)
# Ejecuta desde la raíz del repositorio: .venv/bin/python verificacion/verificar_series.py
import numpy as np
import pandas as pd
s = pd.read_csv("datos/muestra_series.csv") # 1. Leer tus 24 meses
y = s["precipitacion_mm"] # 2. Precipitación mensual (mm)
# 3. Promedio móvil simple de orden 3 (de los 3 meses anteriores e incluido el actual)
s["pm3"] = y.rolling(window=3).mean().round(2)
# 4. Índices estacionales aditivos: promedio de cada mes (2024 y 2025) menos el promedio general
prom_general = y.mean()
prom_mes = s.groupby("mes")["precipitacion_mm"].mean()
indice = (prom_mes - prom_general).round(2)
print(f"Promedio general (24 meses) = {prom_general:.2f} mm")
print("\nPromedio móvil de orden 3 (año 2025):")
print(s.loc[s["anio"] == 2025, ["fecha", "precipitacion_mm", "pm3"]].to_string(index=False))
print("\nÍndice estacional aditivo por mes (mm):")
print(pd.DataFrame({"promedio_mes": prom_mes.round(2), "indice": indice}).to_string())
print(f"Suma de índices = {indice.sum():.2f} (debe ser ≈ 0)")
# 5. Validación hacia atrás: entrenar con 18 meses y pronosticar los 6 de validación
ent = s[s["conjunto"] == "entrenamiento"]
val = s[s["conjunto"] == "validacion"]
real = val["precipitacion_mm"].to_numpy()
pronosticos = {
# Ingenuo: repite el último valor observado (junio 2025)
"Ingenuo (LastValueNaive)": np.repeat(ent["precipitacion_mm"].iloc[-1], 6),
# Estacional ingenuo: repite el mismo mes del año anterior (julio-diciembre 2024)
"Estacional ingenuo (SeasonalNaive)": ent.loc[ent["anio"] == 2024, "precipitacion_mm"].iloc[6:12].to_numpy(),
# Promedio: la media de los 18 meses de entrenamiento
"Promedio (AverageValueNaive)": np.repeat(ent["precipitacion_mm"].mean(), 6),
}
# 6. Métricas de error (las mismas que usa AutoTS)
def metricas(real, pron):
e = real - pron
mae = np.mean(np.abs(e)) # error absoluto medio
rmse = np.sqrt(np.mean(e ** 2)) # raíz del error cuadrático medio
smape = 200 * np.mean(np.abs(e) / (np.abs(real) + np.abs(pron))) # SMAPE (%)
return mae, rmse, smape
filas = []
for nombre, pron in pronosticos.items():
mae, rmse, smape = metricas(real, pron)
filas.append({"método": nombre, "MAE (mm)": round(mae, 2),
"RMSE (mm)": round(rmse, 2), "SMAPE (%)": round(smape, 2)})
tabla = pd.DataFrame(filas).sort_values("SMAPE (%)")
print("\nPronósticos para julio-diciembre 2025:")
print(pd.DataFrame({"fecha": val["fecha"].to_numpy(), "real": real,
**{k.split(" (")[0]: np.round(v, 2) for k, v in pronosticos.items()}}).to_string(index=False))
print("\nComparación de métodos (ordenados por SMAPE):")
print(tabla.to_string(index=False))
print(f"\nMétodo ganador: {tabla.iloc[0]['método']}")
verificacion/verificar_series.R
(ejecutar en Posit Cloud)
# verificar_series.R — Fase 2 del Lápiz y Algoritmo (verificación con R)
# En Posit Cloud: sube datos/muestra_series.csv al proyecto y ejecuta este script.
s <- read.csv("muestra_series.csv") # 1. Leer tus 24 meses
y <- s$precipitacion_mm # 2. Precipitación mensual (mm)
# 3. Promedio móvil de orden 3 (mes actual y los dos anteriores)
s$pm3 <- round(as.numeric(stats::filter(y, rep(1/3, 3), sides = 1)), 2)
print(s[s$anio == 2025, c("fecha", "precipitacion_mm", "pm3")])
# 4. Índices estacionales aditivos
prom_general <- mean(y)
prom_mes <- tapply(y, s$mes, mean)
indice <- round(prom_mes - prom_general, 2)
cat("Promedio general =", round(prom_general, 2), "mm\n")
print(data.frame(mes = 1:12, promedio_mes = round(prom_mes, 2), indice = indice))
cat("Suma de índices =", round(sum(indice), 2), "\n")
# 5. Validación hacia atrás: 18 meses de entrenamiento, 6 de validación
ent <- s[s$conjunto == "entrenamiento", ]
real <- s$precipitacion_mm[s$conjunto == "validacion"]
pron <- list(
ingenuo = rep(tail(ent$precipitacion_mm, 1), 6), # último valor
estacional = ent$precipitacion_mm[ent$anio == 2024][7:12], # mismo mes de 2024
promedio = rep(mean(ent$precipitacion_mm), 6)) # media de entrenamiento
# 6. Métricas de error (las mismas que usa AutoTS)
metricas <- function(a, f) {
e <- a - f
c(MAE = mean(abs(e)), RMSE = sqrt(mean(e^2)),
SMAPE = 200 * mean(abs(e) / (abs(a) + abs(f))))
}
tabla <- t(sapply(pron, metricas, a = real))
print(round(tabla[order(tabla[, "SMAPE"]), ], 2))
# 7. Gráfico: serie con su promedio móvil
plot(y, type = "o", pch = 19, xlab = "Periodo (1 = ene 2024)", ylab = "Precipitación (mm)",
main = "Precipitación mensual y promedio móvil de orden 3")
lines(s$pm3, col = "red", lwd = 2)
abline(v = 18.5, lty = 2) # separa entrenamiento y validación
verificacion/RESULTADOS_SERIES.md
(plantilla)
# Verificación del Lápiz y Algoritmo — Series de tiempo (24 meses)
**Huella de series:** ______
## Promedio móvil e índices estacionales
| Medida | A mano | Python | R | App (sección e) | ¿Coincide? |
|------------------------------------------|--------|--------|----|-----------------|------------|
| Promedio general (mm) | | | | | |
| PM3 de diciembre 2025 (mm) | | | | | |
| Índice estacional del mes más lluvioso | | | | | |
| Índice estacional del mes más seco | | | | | |
| Suma de los 12 índices | | | | | |
## Concurso de métodos (julio-diciembre 2025)
| Método | MAE manual | MAE Python | RMSE manual | RMSE Python | SMAPE manual | SMAPE Python | SMAPE R |
|---------------------|------------|------------|-------------|-------------|--------------|--------------|---------|
| Ingenuo | | | | | | | |
| Estacional ingenuo | | | | | | | |
| Promedio | | | | | | | |
**Ganador a mano:** ______ · **Ganador de AutoTS:** ______ · **Puesto de SeasonalNaive en AutoTS:** ______
## ¿Se cumplió mi predicción previa (A1)?
(2–3 líneas)
## Diferencias encontradas y su causa
(si no hubo, escribe "Ninguna, solo redondeo")
pronostico_autots.pyCópialo textual en la raíz del proyecto y léelo antes de ejecutarlo: cada línea está comentada.
"""
pronostico_autots.py
Pronóstico automático de la precipitación mensual con AutoTS.
Asignatura: Estadística Aplicada con Python y R · Ingeniería Agrícola · Unisucre
Ejecuta desde la raíz del repositorio: .venv/bin/python pronostico_autots.py
(Tarda entre 1 y 4 minutos en el Codespace.)
"""
import json
from pathlib import Path
import pandas as pd
from autots import AutoTS # librería de pronóstico automático (AutoML para series de tiempo)
# ------------------------------------------------------------------
# 1. Leer tu serie mensual (2015-2025) en formato "ancho":
# índice = fechas, una columna por cada serie
# ------------------------------------------------------------------
meta = json.loads(Path("datos/metadatos.json").read_text(encoding="utf-8"))
clima = pd.read_csv("datos/clima_mensual.csv", parse_dates=["fecha"])
serie = clima.set_index("fecha")[["precipitacion_mm"]].asfreq("MS") # MS = inicio de mes
# ------------------------------------------------------------------
# 2. Configurar el "concurso de modelos"
# ------------------------------------------------------------------
modelo = AutoTS(
forecast_length=12, # pronosticar 12 meses (todo 2026)
frequency="MS", # datos mensuales
prediction_interval=0.9, # intervalo de predicción del 90 %
ensemble=None, # sin combinar modelos (más fácil de interpretar)
model_list="superfast", # modelos rápidos: ingenuos, estacionales, lineales...
transformer_list="superfast", # transformaciones previas rápidas
max_generations=5, # generaciones del algoritmo genético
num_validations=2, # validaciones hacia atrás adicionales
validation_method="backwards", # valida con los últimos meses, como en tu hoja
no_negatives=True, # la lluvia no puede ser negativa
random_seed=int(meta["codigo"]) % 10_000, # semilla: tu código (resultado reproducible)
n_jobs=1, # un solo núcleo (suficiente en el Codespace)
verbose=0, # menos mensajes en la terminal
)
# ------------------------------------------------------------------
# 3. Entrenar: AutoTS prueba muchos modelos y se queda con el de mejor puntaje
# ------------------------------------------------------------------
modelo = modelo.fit(serie)
# ------------------------------------------------------------------
# 4. Pronosticar con el modelo ganador
# ------------------------------------------------------------------
pred = modelo.predict()
pronostico = pd.DataFrame({
"fecha": pred.forecast.index.strftime("%Y-%m"),
"pronostico_mm": pred.forecast["precipitacion_mm"].round(1).to_numpy(),
"limite_inferior_mm": pred.lower_forecast["precipitacion_mm"].round(1).to_numpy(),
"limite_superior_mm": pred.upper_forecast["precipitacion_mm"].round(1).to_numpy(),
})
# ------------------------------------------------------------------
# 5. Tabla de los modelos evaluados en validación (menor Score = mejor)
# ------------------------------------------------------------------
validacion = modelo.results("validation")
top10 = validacion[["Model", "smape", "mae", "rmse", "Score"]].head(10).round(3)
# ------------------------------------------------------------------
# 6. Guardar resultados para la app y para el docente
# ------------------------------------------------------------------
Path("resultados").mkdir(exist_ok=True)
pronostico.to_csv("resultados/autots_pronostico.csv", index=False)
top10.to_csv("resultados/autots_top10_modelos.csv", index=False)
Path("resultados/autots_mejor_modelo.json").write_text(json.dumps({
"modelo": modelo.best_model_name,
"parametros": modelo.best_model_params,
"transformaciones": modelo.best_model_transformation_params,
}, ensure_ascii=False, indent=2, default=str), encoding="utf-8")
print(f"Modelo ganador: {modelo.best_model_name}")
print("\nPronóstico de precipitación para 2026 (mm):")
print(pronostico.to_string(index=False))
print("\nLos 10 mejores modelos en validación:")
print(top10.to_string(index=False))
Cómo leer la salida de AutoTS:
| Elemento | Qué significa | Analogía agrícola |
|---|---|---|
best_model_name |
El modelo ganador del concurso | La variedad que mejor rindió en el ensayo |
best_model_params |
La configuración del modelo ganador | El manejo agronómico de esa variedad (densidad, fertilización) |
best_model_transformation_params |
Transformaciones aplicadas antes de modelar (p. ej. suavizado, diferenciación) | La preparación del suelo antes de sembrar |
results("validation") |
Todos los modelos evaluados en las ventanas de validación, ordenados
por Score |
La tabla de resultados del ensayo, de mejor a peor |
Score |
Puntaje combinado de varias métricas (SMAPE, MAE, RMSE y otras); menor es mejor | Un índice de selección que combina rendimiento, sanidad y calidad |
lower_forecast / upper_forecast |
Límites del intervalo de predicción | El rango de cosecha esperado en un año malo y en uno bueno |
README.md## Series de tiempo (Actividad 4) — Versión final v1.0-final
**Huella de series:** ______
Página Series de tiempo: exploración con promedios móviles, descomposición clásica, índices
estacionales, pronóstico automático de la precipitación con AutoTS y verificación del
concurso de métodos de referencia (ingenuo, estacional ingenuo y promedio).
### Hallazgos de series de tiempo
(8–12 líneas escritas por ti, con cifras y unidades)
BITACORA_IA.md# Actividad 4 — Series de tiempo con AutoTS
## Ejecución de pronostico_autots.py (terminal)
- Modelo ganador de AutoTS:
- Puesto y SMAPE de SeasonalNaive en el top 10:
- Ancho del intervalo del 90 % en el mes más lluvioso de 2026:
## Prompt 7 (Agent) — Módulo src/series.py y página Series de tiempo
- Prompt usado (texto exacto):
- Comandos que aprobé:
- Comandos o cambios que rechacé o corregí, y por qué:
- ¿El SMAPE usa 200 y |real| + |pronóstico|? ¿Coincidió la sección "Mi serie de 24 meses" con mi hoja?
## Prompt 8 (Ask) — AutoTS por dentro
- Prompt usado (texto exacto):
- ¿La explicación fue correcta? Idea que confirmé con mi cálculo a mano:
- Imprecisiones que encontré (si hubo):
## Prompt 9 (Agent) — Commits finales y etiqueta v1.0-final
- Prompt usado (texto exacto):
- Commits que creó el agente:
## Reflexión de la actividad (4–5 líneas)
- ¿Qué entendí del pronóstico al hacer mi propio "concurso" a mano que no habría entendido
usando solo AutoTS?
- ¿Qué riesgo tiene confiar ciegamente en una herramienta de AutoML?
## Reflexión de cierre del semestre (6–8 líneas)
- ¿Cómo cambió mi forma de trabajar desde la Actividad 2 (EDA) hasta hoy?
- ¿Qué aprendí a hacer yo mismo y qué aprendí a supervisar en el agente de IA?
- ¿En qué situación de mi futuro trabajo como ingeniero agrícola usaría esta app o estas técnicas?
- ¿Detuve el Codespace al terminar cada sesión? (Sí / No)