Introducción
Un estudio comunitario prepara los materiales siete días antes de cada taller. Predecir la asistencia con los escaneos posteriores al evento podría parecer impresionante, pero no serviría en ese plazo. Primero establecerás una referencia sencilla y después decidirás qué filas y columnas puede utilizar una predicción realmente anticipada.
Necesitas funciones de Python, entrada básica en terminal, selección y uniones con pandas y conceptos introductorios de regresión y separación entre entrenamiento y prueba. Python y las bibliotecas científicas están preparados. Todas las tablas son datos sintéticos originales para enseñar: la pequeña muestra demuestra un flujo de trabajo, sin garantizar predicciones en producción. Los 55 minutos son una estimación del autor que incluye lectura y correcciones habituales.
Medir una referencia sencilla en personas
En este paso predecirás dos talleres posteriores con una mediana temprana e interpretarás el error absoluto medio.
Empieza en WebIDE y abre Terminal → New Terminal. El editor y el terminal comparten archivos. cd cambia el directorio de trabajo de este terminal; cada terminal nuevo necesita su propio cd.
cd /home/labex/project/workshop-attendance
El lanzador preparado ./python utiliza el entorno Python del curso. ./ significa «el ejecutable de este directorio». Úsalo en lugar del Python del sistema al ejecutar los archivos del curso. cat muestra un archivo de texto sin editarlo.
cat warmup-early.csv
Este pequeño ejercicio contiene tres asistencias reales anteriores: 12, 18 y 24. Su mediana, el valor central tras ordenar, es 18 personas. La referencia predice 18 para cada evento posterior sin utilizar características del evento.
cat warmup-later.csv
Las asistencias posteriores son 20 para L-7 y 27 para L-2. Los errores absolutos son abs(20 - 18) = 2 y abs(27 - 18) = 9. El error absoluto medio (MAE) es su promedio: (2 + 9) / 2 = 5.5 personas. «Un error medio de 5,5 personas» tiene sentido; una «precisión» sin unidades ocultaría qué se está midiendo. Este ejercicio es independiente de la temporada completa que usarás a continuación.
Crea una función de referencia reutilizable. La redirección del shell > reemplaza baseline.py. El documento integrado entre comillas <<'PY' envía al archivo todo lo que sigue, hasta una línea que contenga solo PY, sin expansión del shell. Pega el bloque completo, incluida la última línea PY. También puedes editar el mismo archivo en WebIDE y guardar con File → Save.
El ejecutor pasa dos tablas de pandas a summarize. itertuples() recorre filas con campos nombrados; el diccionario asocia cada ID de taller posterior con su propio error. float convierte valores numéricos de pandas en números normales de Python para la salida JSON.
cat > baseline.py <<'PY'
def summarize(early, later):
baseline = float(early.actual_attendance.median())
errors = {
row.session_id: float(abs(row.actual_attendance - baseline))
for row in later.itertuples()
}
return {
"median_attendance": baseline,
"absolute_errors": errors,
"mae": sum(errors.values()) / len(errors),
}
PY
Ejecuta el programa auxiliar preparado que escribe los archivos. Su argumento baseline selecciona esta fase; guarda el resultado de tu función en output/baseline.json. JSON almacena valores y objetos con nombre, en vez de filas CSV.
./python run.py baseline
Los valores mostrados deben incluir la mediana 18.0, los errores 2.0 y 9.0, y el MAE 5.5. Lee el artefacto guardado con el lector preparado, que nunca reconstruye resultados ausentes.
./python show_results.py baseline
Ahora tienes una referencia cuyo error utiliza las mismas unidades que el problema de planificación. Un modelo posterior debe compararse sobre los mismos eventos de evaluación; superar el valor de este ejercicio en otra muestra no sería una comparación justa.
Separar el momento de entrenamiento del de predicción
En este paso asociarás los resultados por ID de taller y reservarás fechas posteriores para evaluar.
Continúa en el mismo terminal de WebIDE, en /home/labex/project/workshop-attendance. Lee el límite de temporada y las tres tablas principales.
cat season.json
cat history.csv
cat labels.csv
cat future.csv
El diccionario de datos es:
| Campo | Significado y disponibilidad | Uso |
|---|---|---|
session_id |
Identidad estable del taller; el orden del archivo es arbitrario | Asociar filas; nunca una característica del modelo |
event_date |
Día programado del evento, formato ISO YYYY-MM-DD |
Decidir la separación temporal |
booked_7d |
Instantánea de reservas guardada exactamente siete días antes del evento | Característica numérica permitida |
duration_minutes |
Duración anunciada antes del plazo de siete días | Característica numérica permitida |
final_bookings |
Total final de reservas al celebrarse el evento | No disponible al predecir |
scanned_entries |
Escaneos de entrada recogidos durante el evento | No disponible al predecir |
actual_attendance |
Resultado conocido al terminar el día del evento | Objetivo de entrenamiento o etiqueta de evaluación reservada |
Una celda numérica vacía en CSV representa información ausente, no cero reservas. Cada característica permitida tiene al menos un valor observado de entrenamiento. Los ID son únicos dentro de cada tabla; labels.csv contiene exactamente un resultado por ID histórico, deliberadamente en otro orden. future.csv no contiene resultados ni columnas posteriores al evento. Las claves inválidas, las características de entrenamiento totalmente vacías y las actualizaciones continuas del modelo quedan fuera del alcance de las entradas del curso.
El modelo se entrena una sola vez y queda congelado el 1 de abril de 2026 a las 00:00 UTC, as_of_date. Solo los eventos anteriores pueden aportar etiquetas de entrenamiento. En esta temporada, el último evento de entrenamiento es el 8 de marzo, por lo que sus etiquetas ya están disponibles. El conjunto reservado comienza el 12 de abril, holdout_start; su primer plazo de predicción de siete días es el 5 de abril, después de congelar el entrenamiento. No hay eventos históricos proporcionados en el intervalo.
Son relojes diferentes: el 1 de abril se congela el modelo ajustado; cada evento posterior proporciona su propia instantánea booked_7d en su propia fecha de predicción. La instantánea del 5 de abril del evento del 12 de abril se usa el 5 de abril: no se afirma que se conociera el día 1. Este ejercicio con archivos reproduce instantáneas guardadas. Las etiquetas reales posteriores se revelan únicamente para medir el rendimiento retrospectivamente. Los talleres de mayo de future.csv siguen siendo pronósticos sin etiquetas.
Reemplaza la separación incompleta basada en posiciones. Un merge uno a uno asocia etiquetas por session_id; no supone que la fila 1 corresponda a la fila 1. pd.to_datetime interpreta fechas del calendario, pd.Timestamp interpreta los límites configurados y las máscaras booleanas seleccionan las filas correspondientes. Ordenar por fecha y después por ID facilita la lectura; la escritura del ID nunca determina el período. .copy() crea tablas seleccionadas independientes.
cat > split.py <<'PY'
import pandas as pd
def split_events(history, labels, season):
events = history.merge(labels, on="session_id", validate="one_to_one")
dates = pd.to_datetime(events["event_date"])
train = events.loc[dates < pd.Timestamp(season["as_of_date"])].copy()
holdout = events.loc[dates >= pd.Timestamp(season["holdout_start"])].copy()
return (
train.sort_values(["event_date", "session_id"]),
holdout.sort_values(["event_date", "session_id"]),
)
PY
./python run.py split
El orden de entrenamiento debe ser W-91, W-04, W-77, W-12, W-63, W-02; los ID reservados son W-88, W-09. Estos ID irregulares muestran por qué ni el orden alfabético ni las dos últimas filas del archivo definen la separación.
./python show_results.py split
Comprueba W-88: debe conservar la asistencia real 46 de su etiqueta correspondiente, no la etiqueta situada en la misma posición. Los archivos guardados training.csv y holdout.csv aún incluyen columnas posteriores al evento para inspeccionarlas. El siguiente paso seleccionará solo las dos características permitidas; almacenar una columna como número no la convierte en una entrada legítima para predecir.
Si cierras accidentalmente el terminal, abre Terminal → New Terminal y repite el cd anterior. «No such file or directory» suele indicar un directorio incorrecto o un nombre mal escrito. Usa pwd para mostrar la ruta actual y ls para listar sus archivos; vuelve al espacio de trabajo y repite el comando correcto. No reinicies el laboratorio por un error habitual de ruta.
Aprender las medias de valores ausentes solo del entrenamiento
En este paso ajustarás un imputador con los talleres anteriores y lo reutilizarás en instantáneas posteriores sin aprender de ellas.
Continúa en WebIDE, en /home/labex/project/workshop-attendance. Puedes editar baseline.py, split.py, prepare.py y tus archivos output/. Conserva todos los CSV/JSON proporcionados, python, run.py, coursekit.py, show_results.py y cada starter-*.py. Las copias iniciales permiten recuperar un módulo; también puedes pegar de nuevo su versión completa enseñada. Las funciones principales deben seguir siendo reutilizables cuando cambien las fechas, el orden de filas y los valores numéricos.
La imputación reemplaza una característica ausente por un valor aprendido. SimpleImputer(strategy="mean") aprende la media aritmética de cada columna. Aquí, las observaciones de entrenamiento de booked_7d son 10, 20, 40, 25 y 35: su media es 26. Las seis duraciones conocidas promedian 80 minutos. Utilizar todos los períodos permitiría que talleres posteriores influyeran en estas decisiones de entrenamiento, incluso sin sus etiquetas de resultado. Ajusta después de separar, no antes.
FEATURES, proporcionado por coursekit, es exactamente ['booked_7d', 'duration_minutes']. Los corchetes dobles seleccionan esas dos columnas en ese orden. fit_transform aprende las medias y rellena la matriz de entrenamiento; transform reutiliza las mismas medias en las matrices reservada y futura. statistics_ expone las medias aprendidas en el orden de las características. Los arrays devueltos conservan el orden de filas de cada tabla de entrada para que el programa auxiliar pueda conservar sus ID.
cat > prepare.py <<'PY'
from sklearn.impute import SimpleImputer
from coursekit import FEATURES
def prepare_features(train, holdout, future):
imputer = SimpleImputer(strategy="mean")
training_values = imputer.fit_transform(train[FEATURES])
holdout_values = imputer.transform(holdout[FEATURES])
future_values = imputer.transform(future[FEATURES])
return training_values, holdout_values, future_values, imputer.statistics_
PY
./python run.py prepare
Las medias aprendidas deben ser booked_7d: 26.0 y duration_minutes: 80.0.
./python show_results.py prepare
En holdout-features.csv, W-88 utiliza 26 reservas y sus 150 minutos observados; W-09 conserva 90 reservas y utiliza 80 minutos. En future-features.csv, F-101 utiliza la misma media de reservas del entrenamiento. No entran en estas matrices numéricas ni reservas finales, ni escaneos, fechas, ID o resultados. Las celdas vacías originales permanecen intactas en los archivos fuente.
Has preparado un límite real de evaluación de lo anterior a lo posterior. Esto no demuestra que el futuro se comporte como el pasado. El siguiente laboratorio independiente ajustará un modelo pequeño y comparará sus errores continuos con una referencia de mediana de entrenamiento en el mismo conjunto reservado etiquetado. Se aceptan cálculos equivalentes y otros órdenes de salida si mantienen las asociaciones por ID y el significado numérico; las comparaciones permiten una tolerancia absoluta y relativa de 1e-8.
Resumen
Has creado una referencia reutilizable basada en la mediana, medido el MAE en personas, unido resultados por ID y separado las fechas tempranas de entrenamiento de las posteriores de evaluación. Seleccionaste únicamente información disponible siete días antes y ajustaste las medias para valores ausentes solo con las filas de entrenamiento. Las tablas guardadas conservan las identidades originales y los datos fuente permanecen intactos para la siguiente fase del análisis.



