Asignatura: Estadística Aplicada con Python y R
Programa: Ingeniería Agrícola — Universidad de Sucre
Grupos: 1 y 2
Tema: Correlación (Pearson y Spearman), regresión lineal simple por Mínimos Cuadrados Ordinarios (MCO), bondad de ajuste, inferencia sobre la pendiente y diagnóstico de residuos
Modalidad: Individual. Mismo repositorio de la Actividad 2 + 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)
Importante: no crees un repositorio nuevo. Esta actividad continúa tu app
app-estadistica-agricola: hoy la página Regresión, que quedó “en construcción”, se vuelve funcional. No vuelvas a ejecutargenerar_datos.py: tus datos y tu huella de la Actividad 2 deben seguir siendo los mismos.
La cooperativa de productores quedó satisfecha con el EDA de tu app. Ahora el gerente técnico hace una pregunta concreta:
“Si aumentamos la lámina de riego, ¿cuánto sube el rendimiento? ¿Y qué tan confiable es esa cifra para decidir si invertimos en riego?”
Para responder, pasarás de describir los datos (EDA) a modelar la relación entre dos variables: la lámina de riego (X, en mm) y el rendimiento (Y, en t/ha) de tus parcelas.
Analogía agrícola:
Metodología del Lápiz y el Algoritmo:
| Mecanismo | Qué lo hace personal |
|---|---|
| Mismos datos de la Actividad 2 | parcelas.csv y la huella de 8 caracteres se generaron
con tu código. Si cambian, se nota. |
| Huella de regresión | El script generar_muestra_regresion.py elige tus 8
parcelas con tu código y produce una huella de 6 caracteres (p. ej.
6CCD9B). El docente la regenera. |
| Cálculo a mano con tus 8 parcelas | Cada estudiante obtiene otra recta, otro \(r\) y otro \(t\). La hoja debe tener tu letra, nombre, código y las dos huellas. |
Historial de commits y etiqueta
v0.3-regresion |
GitHub registra fecha, hora y autor. Se revisa que el trabajo se haya hecho en las dos sesiones. |
| Bitácora de IA | Tus prompts, lo que aceptaste, rechazaste y corregiste. |
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
Ampliar la aplicación de Streamlit con una página de correlación y regresión lineal simple, construida con apoyo supervisado de GitHub Copilot en modo Agente, y verificar a mano y con Python y R los resultados del modelo sobre los datos agrícolas personalizados de cada estudiante.
Objetivos específicos
src/regresion.py y la página Regresión de
la app, y revisar críticamente el código generado.| Competencia | Resultado de aprendizaje | Estrategia pedagógica |
|---|---|---|
| Razonamiento cuantitativo manual (Lápiz y Algoritmo) | Calcula a mano \(r\), \(r_s\), \(\hat\beta_0\), \(\hat\beta_1\), residuos, \(R^2\), RSE y el estadístico \(t\) de la pendiente para 8 observaciones | Hoja manuscrita en dos partes (A y B) |
| Modelación estadística | Formula el modelo \(Y = \beta_0 + \beta_1 X + \varepsilon\), enuncia sus supuestos y evalúa la significancia de la pendiente | Pizarras 3 a 5 + prueba de hipótesis manual |
| Verificación computacional y reproducibilidad | Contrasta sus resultados manuales con Python y R, y documenta las diferencias | verificar_regresion.py,
verificar_regresion.R y
RESULTADOS_REGRESION.md |
| Desarrollo de software asistido por IA | Dirige y supervisa a un agente para construir un módulo y una página de Streamlit, y valida su salida contra su cálculo a mano | Prompts 4 y 6 (modo Agent) + Prompt 5 (modo Ask) |
| Gestión de versiones (Git/GitHub) | Registra su trabajo en commits con mensajes claros, sincroniza y etiqueta una versión | Panel Control de código fuente, edición web,
git tag |
| Interpretación agronómica y pensamiento crítico | Interpreta la pendiente en unidades agronómicas y discute tamaño de muestra, extrapolación y correlación ≠ causalidad | Sección “Hallazgos de la regresión” del README |
| Uso ético y crítico de la IA | Documenta qué aceptó, rechazó o corrigió del agente | 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 5 se hace en modo Ask, que no modifica archivos.
Ctrl+Shift+G) haz clic en Sync Changes, o
en la terminal:git pull # trae a tu Codespace cualquier cambio hecho en GitHub
git log --oneline -5 # deben aparecer tus últimos commits de la Actividad 2
ls datos/ # deben estar parcelas.csv, clima_mensual.csv, muestra10.csv y metadatos.json
cat datos/metadatos.json # tu huella debe ser la MISMA que está en tu README
.venv/bin/python -c "import pandas, statsmodels, scipy; print('Entorno OK')"
Si aparece
No such file or directory, el entorno no existe en este Codespace: recréalo conpython -m venv .venv && .venv/bin/pip install -r requirements.txt(ver sección 10).
generar_muestra_regresion.py en la raíz
del proyecto (al lado de generar_datos.py)..venv/bin/python generar_muestra_regresion.py # usa tus datos de la Actividad 2
datos/muestra_regresion.csv y
datos/metadatos_regresion.json. En la terminal verás tu
huella de regresión y una tabla así (los números serán
los tuyos):X = lámina de riego (mm) Y = rendimiento (t/ha)
parcela lamina_riego rendimiento
P017 126 5.34
P086 180 6.13
... ... ...
[manual] Agrega muestra de 8 parcelas para regresión →
Commit → Sync Changes.La Parte A es solo con lápiz y calculadora: no necesitas el Codespace encendido.
git status # debe decir: nothing to commit, working tree clean
Luego github.com/codespaces → … → Stop codespace.
Usa la notación de la guía de clase: \(X\) = lámina de riego (mm), \(Y\) = rendimiento (t/ha), \(n = 8\).
A1. Predicción previa (antes de calcular, 3–4 líneas). Mirando la tabla: ¿la relación será positiva o negativa? ¿Fuerte o débil? ¿Qué valor aproximado de \(r\) esperas? ¿Por qué?
A2. Diagrama de dispersión a mano. En papel cuadriculado, con ejes rotulados y unidades, ubica los 8 puntos. Usa azul para X y rojo para Y (código de colores de la clase).
A3. Tabla de cálculo. Construye esta tabla con sus totales en la última fila:
| \(i\) | \(x_i\) | \(y_i\) | \(x_i-\bar x\) | \(y_i-\bar y\) | \((x_i-\bar x)^2\) | \((y_i-\bar y)^2\) | \((x_i-\bar x)(y_i-\bar y)\) | \(R(x_i)\) | \(R(y_i)\) | \(d_i\) | \(d_i^2\) |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | |||||||||||
| … | |||||||||||
| 8 | |||||||||||
| Σ | ≈ 0 | ≈ 0 | \(S_{xx}\) | \(S_{yy}\) | \(S_{xy}\) | \(\sum d_i^2\) |
A4. Correlación de Pearson.
\[r = \frac{S_{xy}}{\sqrt{S_{xx}\,S_{yy}}}\]
Interprétala con la escala de la clase: 0 (nula), ±0,3 (débil), ±0,7 (alta), ±1 (perfecta).
A5. Correlación de Spearman (por rangos).
\[r_s = 1 - \frac{6\sum d_i^2}{n\,(n^2-1)} = 1 - \frac{6\sum d_i^2}{504}\]
Compárala con \(r\): ¿cuál es mayor? ¿Qué te dice eso sobre si la relación es lineal o solo monótona?
A6. Recta de mínimos cuadrados.
\[\hat\beta_1 = \frac{S_{xy}}{S_{xx}} \qquad\qquad \hat\beta_0 = \bar y - \hat\beta_1\,\bar x\]
Escribe la ecuación con unidades: \(\hat Y = \hat\beta_0 + \hat\beta_1 X\).
A7. Trazar la recta. Calcula \(\hat Y\) para la lámina menor y la mayor de tu muestra, y traza la recta en verde sobre tu diagrama. Comprueba que pasa por el punto \((\bar x, \bar y)\).
A8. Interpretación (4–5 líneas).
Analogía: \(\hat\beta_1\) es como la “tasa de respuesta” de una curva de fertilización: dice cuánto rinde cada unidad extra de insumo. Pero solo es válida en el rango que se ensayó.
B1. Tabla de ajustados y residuos.
| \(i\) | \(x_i\) | \(y_i\) | \(\hat y_i = \hat\beta_0 + \hat\beta_1 x_i\) | \(e_i = y_i - \hat y_i\) | \(e_i^2\) |
|---|---|---|---|---|---|
| 1 | |||||
| … | |||||
| Σ | ≈ 0 | \(SCE\) |
B2. Descomposición de la variabilidad y \(R^2\).
B3. Error estándar de estimación.
\[RSE = \sqrt{\frac{SCE}{n-2}} = \sqrt{\frac{SCE}{6}} \quad \text{(en t/ha)}\]
B4. Prueba de hipótesis para la pendiente (\(\alpha = 0{,}05\)).
B5. Predicción y extrapolación.
B6. Supuestos y reflexión (5–6 líneas).
Escanea las Partes A y B en un solo PDF con el
nombre hoja_regresion.pdf.
evidencias/ →
Add file → Upload files → arrastra
hoja_regresion.pdf → mensaje
[web] Agrega hoja manuscrita de regresión → Commit
changes.README.md → lápiz → agrega al
final la sección del Anexo C (con tu huella de
regresión; los hallazgos los completas en el Paso 10) → mensaje
[web] Agrega sección de regresión al README →
Commit changes.git pull). Debe aparecer el PDF en evidencias/
y el README actualizado.En el chat de Copilot, modo Agent:
Actúa como tutor de Python, Streamlit y estadística 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 ya tiene app.py, src/eda.py y pages/ (1_Datos, 2_EDA, 3_Regresion en
construcción y 4_Series_de_tiempo). En datos/ hay:
- parcelas.csv: parcela, suelo, riego, dosis_N [kg/ha], lamina_riego [mm],
materia_organica [%] (con faltantes), ph, rendimiento [t/ha].
- muestra_regresion.csv: parcela, lamina_riego, rendimiento (8 parcelas de mi cálculo a mano).
- metadatos.json y metadatos_regresion.json (huella_regresion).
NO modifiques la carpeta datos/, generar_datos.py ni generar_muestra_regresion.py.
Usa .venv/bin/python y .venv/bin/pip en todos los comandos y solo librerías de requirements.txt.
1. Crea src/regresion.py con funciones documentadas (docstrings) y comentadas paso a paso:
a) matriz_correlacion(df, metodo) para "pearson" o "spearman" de las variables numéricas.
b) calculo_manual(x, y): devuelve n, media de x, media de y, Sxx, Syy, Sxy, r de Pearson,
rho de Spearman, b1, b0, SCE, SCR, SCT, R2, RSE = raíz(SCE/(n-2)), SE(b1) = RSE/raíz(Sxx),
t = b1/SE(b1), t crítico bilateral (alfa 0.05, gl = n-2) y p-valor, usando numpy y scipy
con las mismas fórmulas de mínimos cuadrados de la clase.
c) ajustar_rls(df, x, y) con statsmodels (ols) que devuelva el modelo ajustado.
d) predecir(modelo, x0) con la predicción, el intervalo de confianza y el intervalo de
predicción del 95 %.
e) ajustar_multiple(df, y, lista_x) con statsmodels, eliminando filas con faltantes.
2. Reemplaza pages/3_Regresion.py por una página funcional con estas secciones:
a) "Correlación": selector Pearson/Spearman, mapa de calor de la matriz con seaborn y tabla
de la correlación de cada variable numérica con rendimiento, ordenada de mayor a menor |r|.
b) "Regresión lineal simple": selector de X (por defecto lamina_riego) con Y = rendimiento;
dispersión con la recta ajustada; ecuación con unidades; r, R2 y RSE en st.metric; tabla de
coeficientes (coeficiente, error estándar, t, p-valor, IC 95 %) y un st.info con la decisión
sobre H0: beta1 = 0 al 5 %.
c) "Diagnóstico de residuos": residuos vs ajustados con línea en 0, histograma de residuos,
gráfico Q-Q y prueba de Shapiro-Wilk con su interpretación.
d) "Predicción": st.slider para X dentro del rango de los datos que muestre la predicción con
sus intervalos del 95 %, y un st.number_input libre que muestre st.warning de
EXTRAPOLACIÓN cuando el valor esté fuera del rango observado.
e) "Regresión múltiple (vista previa)": rendimiento ~ dosis_N + lamina_riego +
materia_organica + ph; tabla de coeficientes, R2 y R2 ajustado.
f) "Muestra de 8 parcelas (verificación del cálculo a mano)": muestra la huella_regresion, la
tabla de la muestra con y ajustado y residuo, todos los resultados de calculo_manual con 4
decimales (b1 con 6), la dispersión con la recta, y una tabla comparativa de b1, r, R2,
t y p-valor entre la muestra de 8 parcelas y todas las parcelas.
3. En app.py, actualiza la descripción para indicar que la página Regresión ya está disponible.
Requisitos: textos de la interfaz 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:
requirements.txt (por ejemplo
scikit-learn o plotly),
rechaza y pídele que use solo las de la lista.src/regresion.py que el RSE divida entre
n − 2 y la varianza de la pendiente use \(S_{xx}\). Si el agente se equivoca,
corrígelo y anótalo en la bitácora.evidencias/
arrastrándolas al explorador: captura_regresion.png
(sección b) y captura_muestra8.png (sección f).Ctrl+C en la terminal donde
corre.Cambia el selector del chat a Ask (este modo no modifica archivos) y pega:
Sin modificar ningún archivo, explícame línea por línea cómo la función calculo_manual de
src/regresion.py obtiene b1, b0, R2, RSE, SE(b1) y t. Relaciona cada línea con estas fórmulas:
b1 = Sxy/Sxx, b0 = ȳ - b1·x̄, R2 = 1 - SCE/SCT, RSE = raíz(SCE/(n-2)), SE(b1) = RSE/raíz(Sxx),
t = b1/SE(b1). Termina diciéndome por qué se usan n-2 grados de libertad.
En la bitácora responde: ¿la explicación del agente es correcta? Señala al menos una frase que confirmaste con tu hoja o con la guía de clase, y cualquier imprecisión que encuentres.
verificacion/ crea los dos scripts del
Anexo B..venv/bin/python verificacion/verificar_regresion.py # verifica tu cálculo a mano
datos/muestra_regresion.csv y
verificar_regresion.R a un proyecto y ejecuta el script.
Busca en summary(modelo) el Residual standard
error (RSE), el Multiple R-squared (\(R^2\)) y la fila de
lamina_riego (\(\hat\beta_1\), su error estándar, \(t\) y p-valor).verificacion/RESULTADOS_REGRESION.md con la
plantilla del Anexo B. Si algún valor no coincide (más
allá del redondeo), busca el error en tu hoja; no cambies la
hoja para que coincida: anótalo y explica qué pasó.README.md, completa “Hallazgos de la
regresión” (8–12 líneas, escritas por ti, no
por la IA), con base en tu hoja y tu app:
BITACORA_IA.md, agrega al final la sección del
Anexo D (no borres lo de la Actividad 2).[manual] Agrega verificación, hallazgos de regresión y bitácora
→ 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 para traer los cambios que haya en GitHub.
3. Agrupa los archivos pendientes en commits separados y lógicos (por ejemplo: src/regresion.py;
pages/3_Regresion.py y app.py; evidencias/). Cada mensaje en español debe empezar por
"[agente]" y describir el cambio.
4. Crea la etiqueta anotada: git tag -a v0.3-regresion -m "Actividad 3: correlación y regresión"
5. Ejecuta git push --follow-tags y muéstrame git log --oneline -15 y git tag.
6. Explícame en 3 líneas para qué sirve una etiqueta (tag) en un proyecto que crece durante
el semestre.
Si al llegar aquí ya no tienes archivos pendientes, primero pídele al agente un cambio pequeño (por ejemplo, un pie de página en
pages/3_Regresion.pycon la fecha de actualización) y después usa el Prompt 6.
.venv, y en Releases/Tags aparece
v0.3-regresion.app-estadistica-agricola/
├── README.md ← ★ sección "Regresión" con huella y hallazgos
├── .gitignore requirements.txt .vscode/settings.json
├── generar_datos.py ← Actividad 2 (NO se vuelve a ejecutar)
├── generar_muestra_regresion.py ← ★ Anexo A (sin modificar)
├── app.py ← ★ descripción actualizada
├── src/
│ ├── __init__.py eda.py
│ └── regresion.py ← ★ funciones de correlación y regresión
├── pages/
│ ├── 1_Datos.py 2_EDA.py
│ ├── 3_Regresion.py ← ★ página funcional (6 secciones)
│ └── 4_Series_de_tiempo.py ← en construcción (final del semestre)
├── datos/
│ ├── parcelas.csv clima_mensual.csv muestra10.csv metadatos.json
│ └── muestra_regresion.csv metadatos_regresion.json ← ★
├── verificacion/
│ ├── verificar_muestra.py verificar_muestra.R RESULTADOS.md
│ └── verificar_regresion.py verificar_regresion.R RESULTADOS_REGRESION.md ← ★
├── evidencias/
│ ├── hoja_manuscrita.pdf captura_inicio.png captura_eda.png
│ └── hoja_regresion.pdf captura_regresion.png captura_muestra8.png ← ★
└── BITACORA_IA.md ← ★ sección de la Actividad 3 agregada
Historial mínimo de commits en esta actividad: 2
[manual] + 2 [web] + 2 [agente],
distribuidos en las dos sesiones, y la etiqueta
v0.3-regresion.
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 de la Actividad 2; huella original sin cambios;
generar_muestra_regresion.py sin modificar; huella de
regresión correcta en README y hoja; nombre, código y grupo |
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: correlación y MCO | 20 % | Predicción previa; dispersión a mano con ejes y unidades; tabla completa con controles (Σ ≈ 0); \(r\), \(r_s\), \(\hat\beta_1\), \(\hat\beta_0\) correctos; recta trazada por \((\bar x,\bar y)\); interpretación por cada 100 mm y del intercepto | Cálculos correctos con un error menor de redondeo o sin predicción previa | Errores de procedimiento en una medida o tabla incompleta | Ausente, no manuscrito o con una muestra distinta a la asignada |
| 3 | Lápiz y Algoritmo — Parte B: bondad de ajuste, inferencia y verificación con Python y R | 15 % | Residuos con Σ ≈ 0; SCE, SCR, \(R^2\) (y control \(R^2 \approx r^2\)), RSE, \(SE(\hat\beta_1)\), \(t\), decisión e IC 95 % correctos;
predicción y discusión de extrapolación; gráfico de residuos a mano;
RESULTADOS_REGRESION.md comparando manual, Python y R |
Correcto con un error menor o falta el IC o el gráfico de residuos | Inferencia incompleta o verificación en un solo lenguaje | Sin Parte B o sin verificación |
| 4 | Página de Regresión en Streamlit | 20 % | src/regresion.py documentado; las 6 secciones
funcionando con sus datos; RSE con \(n-2\); advertencia de extrapolación; la
sección “Muestra de 8 parcelas” coincide con la hoja; capturas en
evidencias/ |
Falta una sección o un detalle (p. ej. sin intervalo de predicción) | Varias secciones ausentes o la app funciona parcialmente | Sin página de Regresión, 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: ecuación, pendiente por 100 mm, \(r\), \(R^2\), decisión con 8 parcelas vs todas (y por qué difieren), residuos, predicción vs extrapolación, otra variable relevante y correlación ≠ causalidad | 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: panel, web y agente | 10 % | ≥ 2 commits [manual], ≥ 2 [web]
sincronizados, ≥ 2 [agente]; etiqueta
v0.3-regresion publicada; trabajo distribuido en las dos
sesiones |
Cumple el mínimo con algún mensaje poco descriptivo o sin la etiqueta | Falta un tipo de commit | Uno o dos commits con todo el trabajo, o subido con Upload files sin usar Git |
| 7 | Bitácora de IA y pensamiento crítico | 10 % | Los 3 prompts exactos; qué aprobó, rechazó o corrigió y por qué; evaluación argumentada de la explicación del modo Ask; al menos un error o riesgo detectado; reflexión honesta; declara que detuvo el Codespace | Bitácora completa pero con poco detalle en las correcciones | Bitácora genérica o incompleta | Sin sección de la Actividad 3 en la bitácora |
| Lo que ves | Solución |
|---|---|
| Mi Codespace ya no aparece | Si fue eliminado, crea uno nuevo desde Code →
Codespaces. Tus archivos están en GitHub; solo debes recrear el
entorno:
python -m venv .venv && .venv/bin/pip install -r requirements.txt.
No ejecutes generar_datos.py de nuevo |
FileNotFoundError: datos/parcelas.csv |
Estás ejecutando el script fuera de la raíz del proyecto, o no
hiciste git pull. Ejecuta pwd y
ls datos/ |
ModuleNotFoundError: statsmodels |
Usa .venv/bin/python o
.venv/bin/streamlit; si persiste,
.venv/bin/pip install -r requirements.txt |
| Mi \(r\) a mano no coincide con Python | Revisa las medias y que no redondeaste en pasos intermedios. Un error típico: usar \(\sum x_i^2\) en lugar de \(\sum (x_i-\bar x)^2\) |
| \(\hat\beta_1\) me da un número muy pequeño (p. ej. 0,0028) | Es normal: es t/ha por cada mm. Multiplícalo por 100 para interpretarlo por cada 100 mm |
| La decisión sobre \(H_0\) con 8 parcelas no coincide con la de todas las parcelas | No es un error: con \(n = 8\) la estimación es muy sensible a qué parcelas cayeron en la muestra, y con \(n \approx 100\) la prueba detecta efectos más pequeños. Compara también los valores de \(\hat\beta_1\) y explícalo en tus hallazgos |
El agente quiere instalar scikit-learn o
plotly |
Rechaza y pídele que use solo requirements.txt
(statsmodels, scipy, seaborn) |
| No veo el modo Ask | En el selector de modo del chat de Copilot (junto a Agent) |
git push no sube la etiqueta |
Usa git push --follow-tags o
git push origin v0.3-regresion |
| “You’ve reached your monthly chat/agent limit” | Se agotó la cuota: pega el prompt en otro asistente, crea los archivos a mano y anótalo en la bitácora |
generar_muestra_regresion.pyCopia el código textual. No modifiques
ninguna línea. Ejecútalo desde la raíz del proyecto con
.venv/bin/python generar_muestra_regresion.py.
"""
generar_muestra_regresion.py
Selecciona TUS 8 parcelas para el cálculo A MANO de correlación y regresión lineal simple.
Asignatura: Estadística Aplicada con Python y R · Ingeniería Agrícola · Unisucre
Requisito: haber ejecutado antes generar_datos.py (Actividad 2) con TU código.
NO modifiques este archivo.
"""
import hashlib # para calcular la "huella" de tu muestra
import json # para leer y guardar metadatos
from pathlib import Path
import pandas as pd
# ------------------------------------------------------------------
# 1. Leer tus datos personalizados (creados en la Actividad 2)
# ------------------------------------------------------------------
parcelas = pd.read_csv("datos/parcelas.csv")
meta = json.loads(Path("datos/metadatos.json").read_text(encoding="utf-8"))
semilla = int(meta["codigo"]) % 2**32 # misma semilla: tu código estudiantil
# ------------------------------------------------------------------
# 2. Quitar parcelas atípicas en rendimiento (vallas de Tukey, 1.5·RIC)
# Para el cálculo a mano queremos una nube de puntos "limpia".
# ------------------------------------------------------------------
y = parcelas["rendimiento"]
q1, q3 = y.quantile([0.25, 0.75])
ric = q3 - q1
limpias = parcelas[(y >= q1 - 1.5 * ric) & (y <= q3 + 1.5 * ric)].copy()
# ------------------------------------------------------------------
# 3. Elegir 8 parcelas repartidas a lo largo de la lámina de riego:
# se ordenan por lámina, se forman 8 grupos y se toma 1 parcela de cada grupo.
# ------------------------------------------------------------------
limpias = limpias.sort_values(["lamina_riego", "parcela"]).reset_index(drop=True)
limpias["grupo"] = pd.qcut(limpias.index, 8, labels=False)
muestra = pd.concat([g.sample(1, random_state=(semilla + 7) % 10_000) # 1 parcela por grupo
for _, g in limpias.groupby("grupo")])
muestra = muestra[["parcela", "lamina_riego", "rendimiento"]].sort_values("lamina_riego")
muestra["lamina_riego"] = muestra["lamina_riego"].astype(int) # lámina en mm enteros
muestra.to_csv("datos/muestra_regresion.csv", index=False)
# ------------------------------------------------------------------
# 4. Huella de la muestra (el docente la regenera con tu código)
# ------------------------------------------------------------------
huella_reg = hashlib.md5(
f"{meta['codigo']}|{'-'.join(muestra['parcela'])}".encode()).hexdigest()[:6].upper()
Path("datos/metadatos_regresion.json").write_text(
json.dumps({"codigo": meta["codigo"], "huella_regresion": huella_reg,
"parcelas": muestra["parcela"].tolist()}, ensure_ascii=False, indent=2),
encoding="utf-8")
print(f"Estudiante: {meta['nombre']} | Código: {meta['codigo']} | Cultivo: {meta['cultivo']}")
print(f"Huella de la muestra de regresión: {huella_reg}")
print("\nX = lámina de riego (mm) Y = rendimiento (t/ha)")
print(muestra.to_string(index=False))
¿Por qué 8 parcelas repartidas a lo largo de la lámina? Porque así la nube de puntos cubre desde las parcelas más secas hasta las mejor regadas, y la recta se apoya en todo el rango de X. Se excluyen las parcelas atípicas en rendimiento para que el cálculo a mano no quede dominado por una sola parcela. (En la app, con todas las parcelas, sí verás el efecto de los atípicos.)
verificacion/verificar_regresion.py
# verificar_regresion.py — Fase 2 del Lápiz y Algoritmo (verificación con Python)
# Ejecuta desde la raíz del repositorio: .venv/bin/python verificacion/verificar_regresion.py
import numpy as np
import pandas as pd
from scipy import stats
m = pd.read_csv("datos/muestra_regresion.csv") # 1. Leer tus 8 parcelas
x = m["lamina_riego"] # 2. X: lámina de riego (mm)
y = m["rendimiento"] # 3. Y: rendimiento (t/ha)
n = len(m)
# 4. Medias y sumas de cuadrados (las mismas columnas de tu tabla manuscrita)
xm, ym = x.mean(), y.mean()
Sxx = ((x - xm) ** 2).sum()
Syy = ((y - ym) ** 2).sum()
Sxy = ((x - xm) * (y - ym)).sum()
# 5. Correlación de Pearson y de Spearman
r = Sxy / np.sqrt(Sxx * Syy)
rho, p_rho = stats.spearmanr(x, y)
# 6. Recta de mínimos cuadrados
b1 = Sxy / Sxx # pendiente (t/ha por cada mm)
b0 = ym - b1 * xm # intercepto (t/ha)
y_hat = b0 + b1 * x # valores ajustados
e = y - y_hat # residuos
# 7. Bondad de ajuste e inferencia sobre la pendiente
SCE = (e ** 2).sum() # suma de cuadrados del error (residual)
R2 = 1 - SCE / Syy # coeficiente de determinación
RSE = np.sqrt(SCE / (n - 2)) # error estándar de estimación
SE_b1 = RSE / np.sqrt(Sxx) # error estándar de la pendiente
t = b1 / SE_b1 # estadístico t
t_crit = stats.t.ppf(0.975, n - 2) # valor crítico bilateral, alfa = 0.05
p_valor = 2 * stats.t.sf(abs(t), n - 2) # p-valor bilateral
print(f"n = {n} x̄ = {xm:.2f} mm ȳ = {ym:.4f} t/ha")
print(f"Sxx = {Sxx:.2f} Syy = {Syy:.4f} Sxy = {Sxy:.4f}")
print(f"Pearson r = {r:.4f} Spearman rho = {rho:.4f}")
print(f"b1 = {b1:.6f} t/ha por mm (= {100*b1:.4f} t/ha por cada 100 mm)")
print(f"b0 = {b0:.4f} t/ha")
print(f"SCE = {SCE:.4f} R² = {R2:.4f} RSE = {RSE:.4f} t/ha")
print(f"SE(b1) = {SE_b1:.6f} t = {t:.3f} t crítico (gl={n-2}) = {t_crit:.3f} p = {p_valor:.4f}")
print("Decisión:", "Se rechaza H0 (la lámina es significativa)" if p_valor < 0.05
else "No se rechaza H0 (sin evidencia suficiente con n = 8)")
# 8. Tabla de ajustados y residuos para comparar con tu hoja
tabla = m.assign(y_ajustado=y_hat.round(4), residuo=e.round(4))
print("\n", tabla.to_string(index=False))
print(f"\nSuma de residuos = {e.sum():.6f} (debe ser ≈ 0)")
verificacion/verificar_regresion.R
(ejecutar en Posit Cloud)
# verificar_regresion.R — Fase 2 del Lápiz y Algoritmo (verificación con R)
# En Posit Cloud: sube datos/muestra_regresion.csv al proyecto y ejecuta este script.
m <- read.csv("muestra_regresion.csv") # 1. Leer tus 8 parcelas
x <- m$lamina_riego # 2. X: lámina de riego (mm)
y <- m$rendimiento # 3. Y: rendimiento (t/ha)
n <- length(y)
# 4. Sumas de cuadrados (las mismas columnas de tu tabla manuscrita)
Sxx <- sum((x - mean(x))^2)
Syy <- sum((y - mean(y))^2)
Sxy <- sum((x - mean(x)) * (y - mean(y)))
cat("x_media =", round(mean(x), 2), " y_media =", round(mean(y), 4), "\n")
cat("Sxx =", round(Sxx, 2), " Syy =", round(Syy, 4), " Sxy =", round(Sxy, 4), "\n")
# 5. Correlación de Pearson y de Spearman (con su prueba)
print(cor.test(x, y, method = "pearson"))
print(cor.test(x, y, method = "spearman"))
# 6. Modelo de regresión lineal simple por MCO
modelo <- lm(rendimiento ~ lamina_riego, data = m)
print(summary(modelo)) # b0, b1, SE(b1), t, p-valor, RSE (Residual standard error) y R²
# 7. Ajustados y residuos para comparar con tu hoja
print(data.frame(m, y_ajustado = round(fitted(modelo), 4),
residuo = round(resid(modelo), 4)))
cat("Suma de residuos =", round(sum(resid(modelo)), 6), "\n")
# 8. Gráficos: nube de puntos con la recta y residuos vs ajustados
par(mfrow = c(1, 2))
plot(x, y, pch = 19, xlab = "Lámina de riego (mm)", ylab = "Rendimiento (t/ha)",
main = "Recta de MCO")
abline(modelo, col = "red", lwd = 2)
plot(fitted(modelo), resid(modelo), pch = 19, xlab = "Ajustados (t/ha)",
ylab = "Residuos (t/ha)", main = "Residuos vs ajustados")
abline(h = 0, lty = 2)
verificacion/RESULTADOS_REGRESION.md
(plantilla)
# Verificación del Lápiz y Algoritmo — Regresión (8 parcelas)
**Huella de regresión:** ______
| Medida | A mano | Python | R | App (sección f) | ¿Coincide? |
|--------------------------------|--------|--------|------|-----------------|------------|
| x̄ (mm) | | | | | |
| ȳ (t/ha) | | | | | |
| Sxx | | | | | |
| Syy | | | | | |
| Sxy | | | | | |
| r de Pearson | | | | | |
| rs de Spearman | | | | | |
| β̂1 (t/ha por mm) | | | | | |
| β̂0 (t/ha) | | | | | |
| SCE | | | | | |
| R² | | | | | |
| RSE (t/ha) | | | | | |
| SE(β̂1) | | | | | |
| t | | | | | |
| Decisión sobre H0 | | | | | |
| Predicción para 400 mm (t/ha) | | | | | |
## ¿Se cumplió mi predicción previa (A1)?
(2–3 líneas)
## Diferencias encontradas y su causa
(si no hubo, escribe "Ninguna, solo redondeo")
README.md## Regresión (Actividad 3)
**Huella de regresión:** ______ · **Versión:** v0.3-regresion
Página Regresión: correlación (Pearson y Spearman), regresión lineal simple de rendimiento
(t/ha) sobre lámina de riego (mm), diagnóstico de residuos, predicción y vista previa de
regresión múltiple.
### Hallazgos de la regresión
(8–12 líneas escritas por ti, con cifras y unidades)
BITACORA_IA.md# Actividad 3 — Correlación y regresión
## Prompt 4 (Agent) — Módulo src/regresion.py y página Regresión
- Prompt usado (texto exacto):
- Comandos que aprobé:
- Comandos o cambios que rechacé o corregí, y por qué:
- ¿El RSE usa n-2? ¿Coincidió la sección "Muestra de 8 parcelas" con mi hoja?
## Prompt 5 (Ask) — Explicación de calculo_manual
- Prompt usado (texto exacto):
- ¿La explicación fue correcta? Frase que confirmé con mi hoja o la guía:
- Imprecisiones que encontré (si hubo):
## Prompt 6 (Agent) — Commits y etiqueta v0.3-regresion
- Prompt usado (texto exacto):
- Commits que creó el agente:
## Reflexión (5–6 líneas)
- ¿Qué entendí de la regresión al calcularla a mano que no habría entendido viendo solo la app?
- ¿En qué se equivocó o podría equivocarse la IA al construir un modelo estadístico?
- ¿Detuve el Codespace al terminar cada sesión? (Sí / No)