Actividad Evaluativa — Nota 1 (Segundo 50%)

“Ingeniero Modelador”: Ajuste de Distribuciones y Modelos de Secado con scipy.stats y Phitter

Asignatura: Estadística Aplicada con Python y R

Programa: Ingeniería Agrícola — Universidad de Sucre

Semana de referencia: Semana 7 — Ajuste de Distribuciones, Bondad de Ajuste y Modelos Empíricos/Semiempíricos de Secado

Modalidad: Individual, trabajo autónomo en Google Colab

Entregable: Notebook .ipynb alojado en un repositorio de GitHub (se entrega la URL del notebook en GitHub, no un enlace de Colab)


1. Descripción de la actividad

En la Semana 7 aprendimos que ajustar un modelo a datos —ya sea una distribución de probabilidad o una curva de secado— sigue el mismo método: proponer candidatas con sentido físico, estimar parámetros, diagnosticar visualmente, contrastar con pruebas formales y criterios de información, y usar el resultado para decidir. También vimos un puente que conecta ambos mundos: la ecuación de Page, \(MR(t) = e^{-k\,t^{n}}\), es exactamente la función de supervivencia de una distribución Weibull con forma \(n\) y escala \(k^{-1/n}\). Esta actividad pone a prueba ese puente con datos que cada estudiante simula para su propio caso.

Cada estudiante recibirá, a partir de su código estudiantil, un producto agrícola, una temperatura de secado y unos parámetros de proceso ocultos (no se revelan como fórmula: se generan con una semilla aleatoria y no se consultan directamente). Con esos datos personalizados, el estudiante trabaja dos escalas del mismo fenómeno:

  • Parte A — Variabilidad lote a lote (distribución): el tiempo que cada lote de producto tarda en alcanzar la humedad objetivo no es siempre el mismo (varía por tamaño de pieza, humedad inicial, ubicación en el secador). Esa variabilidad se modela con una distribución de probabilidad, que el estudiante debe descubrir ajustando varias candidatas con scipy.stats y, principalmente, con un barrido automático en Phitter.
  • Parte B — La curva promedio de secado (modelo empírico/semiempírico): el seguimiento hora a hora de la humedad del producto se ajusta con los modelos clásicos de secado en capa delgada (Lewis, Henderson-Pabis, Page y al menos un modelo adicional) usando scipy.optimize.curve_fit.

El cierre de la actividad es verificar el puente entre las dos partes: la forma \(n\) y la escala del modelo de Page (Parte B) deben ser coherentes con la forma y la escala de la distribución Weibull que mejor ajustó los tiempos de secado (Parte A). Si no coinciden, el estudiante debe investigar por qué.

Esta actividad extiende —no reemplaza— el notebook de clase de la Semana 7, y se enmarca en la pedagogía del “Lápiz y el Algoritmo”: antes de aceptar cualquier código generado por IA, el estudiante debe predecir el resultado esperado (¿el tiempo de diseño debería ser mayor o menor que el tiempo promedio?) y verificarlo.


2. Objetivos

Objetivo general

Aplicar el ajuste de distribuciones de probabilidad (scipy.stats y Phitter) y de modelos empíricos/semiempíricos de secado (scipy.optimize.curve_fit) sobre datos simulados y personalizados, para estimar un tiempo de diseño de secado con criterio ingenieril, mediante un notebook desarrollado con apoyo crítico de un agente de IA.

Objetivos específicos

  • Generar, a partir del código estudiantil, un conjunto de datos personalizado y reproducible que represente la variabilidad de tiempos de secado entre lotes y la curva promedio de secado de un producto agrícola.
  • Ajustar con scipy.stats al menos dos distribuciones candidatas (incluida la Weibull) a los tiempos de secado simulados, con diagnóstico Q-Q y prueba de bondad de ajuste.
  • Ejecutar en Phitter un barrido automático restringido a distribuciones con sentido físico para datos de tiempo, comparar su resultado con el de scipy.stats e interpretar el ranking con sentido crítico (no aceptarlo sin verificar).
  • Ajustar por mínimos cuadrados no lineales (curve_fit) al menos cuatro modelos de secado en capa delgada (Lewis, Henderson-Pabis, Page y uno adicional) a la curva promedio de humedad, comparando su desempeño con AICc.
  • Verificar numéricamente el puente Page–Weibull entre la Parte A y la Parte B, y calcular un tiempo de diseño del secador que cubra al menos el 90 % de los lotes, no solo el promedio.
  • Documentar de forma crítica el proceso de interacción con el agente de IA (Bitácora de IA), incluyendo errores, ajustes y verificación humana del código.
  • Alojar el notebook en un repositorio propio de GitHub y compartir su URL pública.

3. Competencias, resultados de aprendizaje y estrategias

Competencia Resultado de aprendizaje Estrategia pedagógica
Ajuste de distribuciones de probabilidad Ajusta y compara distribuciones candidatas con scipy.stats y Phitter, diagnosticando con Q-Q y pruebas de bondad de ajuste Barrido guiado en Phitter, restringido por sentido físico, contrastado con scipy.stats
Modelación empírica y semiempírica en ingeniería agrícola Ajusta modelos de secado en capa delgada por mínimos cuadrados no lineales y los compara con criterios de información (AICc) Réplica personalizada del flujo de trabajo de la Semana 7 sobre datos propios
Pensamiento computacional y programación asistida por IA Traduce una especificación estadística en código Python correcto (scipy.stats, Phitter, curve_fit), verificándolo línea por línea Prompting guiado, verificación humana obligatoria, Bitácora de IA
Integración conceptual (puente Page–Weibull) Verifica numéricamente que un modelo semiempírico de secado y una distribución de probabilidad describen el mismo fenómeno desde dos escalas distintas Comparación explícita de parámetros entre la Parte A y la Parte B
Juicio técnico e ingenieril Traduce el resultado del ajuste en un tiempo de diseño del secador que considera la variabilidad entre lotes, no solo el promedio Cálculo de un cuantil de diseño (p. ej. 90 %) y justificación técnica
Reserva cognitiva y uso ético de la IA Documenta el prompt usado, si el código funcionó al primer intento y qué ajustes humanos fueron necesarios Bitácora de IA obligatoria (conforme a la Hoja de Ruta de IA ética 2024)
Reproducibilidad y buenas prácticas Publica un notebook reproducible, versionado y accesible en un repositorio de GitHub propio Alojamiento del entregable en GitHub en lugar de un enlace de Colab

4. Tus datos personalizados (obligatorio, primera celda de código)

Para que cada notebook sea distinto —y verificable— no se usa un dataset compartido: cada estudiante genera el suyo a partir de su propio código estudiantil. Copia y ejecuta esta celda sin modificarla, salvo la línea del código estudiantil:

import numpy as np
import scipy.stats as stats

codigo = "XXXXXXXXX"        # <-- REEMPLAZA por tu código estudiantil completo, como texto
semilla = int(codigo[-4:])  # los últimos 4 dígitos del código, como semilla reproducible
rng = np.random.default_rng(semilla)

# --- Escenario asignado (no lo cambies: identifica tu notebook) ---
productos = ["Ñame", "Yuca", "Plátano", "Mango", "Cacao", "Ajonjolí"]
producto = productos[semilla % len(productos)]
temperatura = [50, 60, 70, 80][semilla % 4]
humedad_objetivo = 15 + (semilla % 6)          # % base húmeda (entre 15 y 20 %)

print(f"Código: {codigo}  ->  semilla = {semilla}")
print(f"Producto asignado: {producto}   |   Temperatura: {temperatura} °C   |   Humedad objetivo: {humedad_objetivo} % b.h.")

# --- Parámetros "verdaderos" OCULTOS del proceso (no los mires, no los copies en tus resultados) ---
n_verdadero = rng.uniform(0.65, 1.35)
k_verdadero = rng.uniform(0.15, 0.55) * (1 + 0.15 * (temperatura - 60) / 10)

# --- Parte A: tiempos de secado hasta la humedad objetivo, lote a lote (40 lotes) ---
# Bridge Page <-> Weibull: si MR(t) = exp(-k t^n), el tiempo hasta MR = objetivo
# se distribuye Weibull(forma = n, escala = k^(-1/n)).
n_lotes = 40
tiempos_lote = stats.weibull_min(c=n_verdadero, scale=k_verdadero ** (-1 / n_verdadero)) \
                     .rvs(size=n_lotes, random_state=rng)

# --- Parte B: curva promedio de secado, 2 repeticiones, cada hora durante 10 horas ---
t_h = np.tile(np.arange(0, 11), 2)
MR_teorico = np.exp(-k_verdadero * t_h ** n_verdadero)          # ecuación de Page
MR_obs = np.clip(MR_teorico + rng.normal(0, 0.02, size=t_h.size), 0.002, 1.05)

No borres ni recalcules semilla, producto, temperatura ni humedad_objetivo: son la huella digital de tu notebook y permiten verificar que los resultados corresponden a tu código. tiempos_lote es el insumo de la Parte A; t_h y MR_obs son el insumo de la Parte B.


5. Requisitos del notebook (Google Colab)

  1. Primera celda (texto/Markdown): nombres completos del estudiante, código estudiantil, asignatura, grupo y tema de la actividad.
  2. Celda de datos personalizados: exactamente la del numeral 4, con tu código reemplazado. Imprime el producto, la temperatura y la humedad objetivo asignados.
  3. Predicción manuscrita (antes de ejecutar el ajuste): una celda de texto donde fotografíes o transcribas tu predicción a mano: ¿esperas que el tiempo que cubre al 90 % de los lotes sea mayor o menor que el tiempo promedio de secado? Justifica en 2 a 3 líneas antes de calcularlo.
  4. Parte A — Distribución de los tiempos de secado (tiempos_lote):
    • Ajusta al menos dos distribuciones candidatas con scipy.stats (obligatoria la Weibull; la segunda a tu elección con sentido físico: Gamma, Lognormal o Exponencial), con gráfico Q-Q y al menos una prueba de bondad de ajuste (stats.kstest o stats.goodness_of_fit).
    • Ejecuta un barrido en Phitter restringido con distributions_to_fit a candidatas con sentido físico para datos de tiempo (no dejes el barrido libre de 80+ distribuciones sin filtrar). Reporta el ranking y la mejor distribución.
    • Compara los parámetros de la Weibull obtenidos por scipy.stats y por Phitter.
    • Calcula el cuantil 0.90 de la distribución ganadora: el tiempo que cubre al 90 % de los lotes.
  5. Parte B — Curva promedio de secado (t_h, MR_obs):
    • Ajusta con curve_fit al menos cuatro modelos: Lewis, Henderson-Pabis, Page (obligatorios, por el puente con la Parte A) y uno adicional a tu elección (Page modificado, dos términos, Wang y Singh, Thompson o logarítmico).
    • Compara los modelos con AICc, RMSE y un gráfico de residuos del mejor y del peor modelo.
    • Calcula el tiempo hasta la humedad objetivo (humedad_objetivo) con el mejor modelo.
  6. Verificación del puente Page–Weibull: compara la forma \(n\) y la escala \(k^{-1/n}\) estimadas por Page (Parte B) contra la forma y la escala de la Weibull ganadora (Parte A). ¿Son razonablemente parecidas? Si divergen mucho, propone una explicación (por ejemplo, pocos lotes, ruido de medición, un modelo mal elegido).
  7. Tiempo de diseño del secador (síntesis): compara el tiempo del cuantil 0.90 (Parte A) con el tiempo predicho por el mejor modelo de la curva promedio (Parte B) y recomienda, con una frase, cuál usarías para programar el tiempo de operación del secador y por qué.
  8. Bitácora de IA (obligatoria): herramienta usada, prompt(s) exacto(s) utilizado(s), si el código funcionó al primer intento, ajustes humanos realizados y errores o alucinaciones detectadas (por ejemplo, un identificador de distribución de Phitter que no existe, o una mala parametrización de Page).
  9. Conclusión técnica individual (5 a 8 líneas): interpreta el valor de \(n\) (resistencia interna vs. externa al secado, ver Semana 7), justifica la elección final de modelo para cada parte, y recomienda un tiempo de operación del secador para tu producto y temperatura asignados.

Entrega: subir el notebook a un repositorio de GitHub (público, o con acceso de lectura habilitado) y compartir la URL del archivo .ipynb en GitHub en el grupo de la asignatura. Ver la sección 8 con instrucciones si es tu primera vez usando GitHub.


6. Rúbrica de evaluación

Escala institucional 0.0 a 5.0. La nota de la actividad corresponde al promedio ponderado de los ocho criterios.

# Criterio Peso Excelente (4.6–5.0) Bueno (3.6–4.5) Aceptable (3.0–3.5) Insuficiente (0.0–2.9)
1 Identificación y datos personalizados 5% Encabezado completo (nombres, código, asignatura, grupo) y celda de datos ejecutada sin modificar su lógica, con escenario impreso correctamente Completo con algún detalle menor de formato Falta un dato del encabezado o se alteró parcialmente la celda de datos Falta el encabezado o la celda de datos fue modificada de forma que invalida la personalización
2 Parte A: ajuste con scipy.stats (Weibull + una candidata más) 15% Ambas distribuciones ajustadas correctamente, Q-Q y prueba de bondad de ajuste bien ejecutados e interpretados Ajuste correcto con interpretación parcial del Q-Q o de la prueba Ajuste con error menor de parametrización o sin diagnóstico completo Ajuste ausente o distribuciones mal parametrizadas
3 Parte A: barrido con Phitter y comparación con scipy.stats 20% Barrido restringido con criterio físico, ranking interpretado con sentido crítico, parámetros comparados correctamente entre Phitter y scipy.stats Barrido correcto con comparación de parámetros incompleta o poco crítica Barrido ejecutado pero sin restricción de candidatas o sin comparar con scipy.stats Phitter ausente o mal utilizado (p. ej. barrido de 80+ sin ningún filtro ni análisis)
4 Parte B: ajuste de modelos de secado con curve_fit (mínimo 4 modelos) 20% Los 4+ modelos correctamente definidos (ecuaciones exactas) y ajustados, con AICc, RMSE y residuos bien interpretados Modelos ajustados correctamente con comparación (AICc/RMSE) incompleta Menos de 4 modelos, o alguna ecuación mal escrita mecánicamente (p. ej. signo de Page modificado) Ajuste ausente o modelos insuficientes/incorrectos
5 Verificación del puente Page–Weibull 15% Compara explícitamente forma y escala entre Parte A y Parte B, con conclusión razonada sobre la coherencia (o falta de ella) Comparación presente con interpretación parcial Comparación mencionada pero sin cálculo explícito o sin interpretación Ausente: no se relacionan las dos partes
6 Tiempo de diseño del secador (cuantil 0.90 vs. modelo de curva) 10% Calcula y compara ambos tiempos, recomienda uno con justificación ingenieril clara Calcula ambos tiempos con justificación general Calcula solo uno de los dos tiempos, o sin comparación explícita Ausente o sin sentido físico
7 Bitácora de IA 10% Prompt(s) exacto(s) documentado(s), honestidad sobre ajustes/errores, reflexión crítica genuina Documentada pero con detalle limitado Bitácora superficial o genérica Ausente o copiada sin evidencia real de uso
8 Conclusión técnica, reproducibilidad y entrega en GitHub 5% Conclusión sólida con interpretación física de \(n\); notebook reproducible y correctamente alojado en GitHub con URL accesible Conclusión adecuada; notebook en GitHub con algún detalle menor de acceso o de formato Conclusión superficial, o el notebook está en GitHub pero incompleto/no reproducible Conclusión ausente, o el entregable no es un enlace de GitHub válido

Nota de la actividad = Σ (nota del criterio × peso del criterio), redondeada a un decimal según la escala institucional (0.0–5.0).


7. Recomendaciones para el estudiante

  • Ejecuta la celda de datos personalizados una sola vez y no la vuelvas a correr con una semilla distinta a mitad del trabajo: cambiarías tu escenario y tus resultados dejarían de ser coherentes entre las partes A, B y la verificación del puente.
  • Antes de pedirle el código a la IA, predice a mano (numeral 3) si el tiempo del cuantil 0.90 debería ser mayor o menor que el promedio. Un tiempo de diseño menor que el promedio sería una señal de error en el cálculo, no una posibilidad física real.
  • En Phitter, restringe siempre distributions_to_fit a candidatas con sentido para un tiempo (siempre positivo): evita dejar el barrido libre de 80+ distribuciones, tal como se discutió en el notebook de clase sobre el riesgo de “pesca de resultados”.
  • Revisa el código generado por la IA línea por línea, en especial las ecuaciones de Page y Page modificado (el signo dentro del exponente es la fuente de error más común) y la relación escala–forma del puente Weibull (\(k^{-1/n}\)).
  • Sé honesto en la Bitácora de IA: documentar un error o una alucinación de la IA y cómo la corregiste vale más que aparentar que todo funcionó a la primera.

8. Cómo alojar el notebook en GitHub (si es tu primera vez)

  1. Crea una cuenta gratuita en github.com si no tienes una.
  2. Crea un repositorio nuevo (botón New repository), público, con un nombre descriptivo, por ejemplo estadistica-secado-tuapellido.
  3. Desde Google Colab: Archivo → Guardar una copia en GitHub, autoriza el acceso la primera vez, selecciona tu repositorio y confirma. Colab sube el .ipynb directamente.
    • Alternativa manual: en Colab, Archivo → Descargar → Descargar .ipynb, y luego en tu repositorio de GitHub usa Add file → Upload files para subir el archivo descargado.
  4. Abre el archivo .ipynb dentro de tu repositorio en GitHub (se renderiza automáticamente con salidas y gráficos) y copia la URL de esa página —no la URL del repositorio completo, sino la del archivo— para entregarla.
  5. Verifica, en una ventana de incógnito o pidiéndole a un compañero, que el enlace abre sin pedir inicio de sesión.