Введение
Общественная студия готовит материалы за семь дней до каждого мастер-класса. Прогноз по сканированиям входа после мероприятия мог бы выглядеть впечатляюще, но к этому сроку был бы бесполезен. Сначала вы построите простой базовый прогноз, затем определите, какие строки и столбцы допустимы для настоящего заблаговременного прогноза.
Нужны функции Python, базовый ввод в терминале, выборка и объединения pandas, начальные понятия регрессии и разделения на обучение и тест. Python и научные библиотеки подготовлены. Все таблицы — оригинальные синтетические учебные данные; небольшая выборка показывает рабочий процесс, а не гарантирует производственное прогнозирование. 55 минут — оценка автора с учётом чтения и обычных исправлений.
Измерить простой базовый прогноз в людях
На этом шаге вы спрогнозируете два поздних мастер-класса по ранней медиане и интерпретируете среднюю абсолютную ошибку.
Начните в WebIDE, затем откройте Terminal → New Terminal. Редактор и терминал используют общие файлы. cd меняет рабочий каталог этого терминала; новому терминалу нужен отдельный cd.
cd /home/labex/project/workshop-attendance
Подготовленный запускатель ./python использует Python-окружение курса. ./ означает «исполняемый файл в этом каталоге». Используйте его вместо системного Python для файлов курса. cat показывает текстовый файл, не изменяя его.
cat warmup-early.csv
В этой небольшой разминке три ранние фактические посещаемости: 12, 18 и 24. Их медиана, центральное значение после сортировки, равна 18 людям. Базовый метод прогнозирует 18 для каждого позднего мероприятия без его признаков.
cat warmup-later.csv
Поздние фактические значения — 20 для L-7 и 27 для L-2. Абсолютные ошибки равны abs(20 - 18) = 2 и abs(27 - 18) = 9. Средняя абсолютная ошибка (MAE) — их среднее: (2 + 9) / 2 = 5.5 человека. «Средняя ошибка 5,5 человека» имеет понятный смысл; «точность» без единиц скрывала бы измеряемую величину. Эта разминка отделена от полного сезона, который используется дальше.
Создайте повторно используемую функцию базового прогноза. Перенаправление оболочки > заменяет baseline.py. Here-document в кавычках <<'PY' передаёт в файл всё до строки, содержащей только PY, без подстановок оболочки. Вставьте весь блок, включая завершающий PY. Можно вместо этого отредактировать тот же файл в WebIDE и сохранить через File → Save.
Программа запуска передаёт две таблицы pandas в summarize. itertuples() перебирает строки с именованными полями; словарь связывает ID каждого позднего мастер-класса с его собственной ошибкой. float преобразует числовые значения pandas в обычные числа Python для вывода 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
Запустите подготовленную вспомогательную программу записи файлов. Аргумент baseline выбирает этот этап; результат функции сохраняется в output/baseline.json. JSON хранит именованные значения и объекты, а не строки CSV.
./python run.py baseline
На экране должны быть медиана 18.0, ошибки 2.0 и 9.0, MAE 5.5. Прочитайте сохранённый результат подготовленной программой чтения: она никогда не восстанавливает недостающие результаты.
./python show_results.py baseline
Теперь у вас есть ориентир, ошибка которого выражена в тех же единицах, что и задача планирования. Последующую модель необходимо сравнивать на тех же оценочных мероприятиях; превзойти число из разминки на другой выборке не означало бы честного сравнения.
Разделить время обучения и время прогнозирования
На этом шаге вы свяжете результаты по ID мастер-класса и оставите поздние даты для оценки.
Продолжайте в том же терминале WebIDE, в /home/labex/project/workshop-attendance. Прочитайте границу сезона и три основные таблицы.
cat season.json
cat history.csv
cat labels.csv
cat future.csv
Словарь данных:
| Поле | Значение и момент доступности | Использование |
|---|---|---|
session_id |
Постоянный идентификатор мастер-класса; порядок файла произволен | Связывать строки, никогда не признак модели |
event_date |
Запланированный день, ISO YYYY-MM-DD |
Определять временное разделение |
booked_7d |
Снимок бронирований ровно за семь дней до мероприятия | Разрешённый числовой признак |
duration_minutes |
Продолжительность, объявленная к семидневному сроку | Разрешённый числовой признак |
final_bookings |
Окончательное число бронирований к мероприятию | Недоступно к сроку прогноза |
scanned_entries |
Сканирования входа во время мероприятия | Недоступно к сроку прогноза |
actual_attendance |
Результат, известный к концу дня мероприятия | Цель обучения или отложенная оценочная метка |
Пустая числовая ячейка CSV означает отсутствие сведений, а не ноль бронирований. У каждого разрешённого признака есть хотя бы одно наблюдаемое обучающее значение. В каждой таблице ID уникальны; labels.csv содержит ровно один результат на исторический ID, намеренно в ином порядке. future.csv не содержит результатов или столбцов после мероприятия. Некорректные ключи, полностью пустые обучающие признаки и скользящие обновления модели не входят в область входных данных курса.
Модель обучается один раз и фиксируется 1 апреля 2026 года в 00:00 UTC, as_of_date. Только мероприятия до этой даты могут дать обучающие метки. В этом сезоне последнее обучающее мероприятие — 8 марта, поэтому метки уже доступны. Отложенная выборка начинается 12 апреля, holdout_start; первый семидневный срок прогноза — 5 апреля, после фиксации обучения. В промежутке нет предоставленных исторических мероприятий.
Это разные часы: 1 апреля фиксирует обученную модель; каждое позднее мероприятие предоставляет собственный снимок booked_7d в свою дату прогноза. Снимок от 5 апреля для события 12 апреля используется 5 апреля, а не объявляется известным 1 апреля. Это файловое упражнение воспроизводит сохранённые снимки. Поздние фактические метки раскрываются только для ретроспективной оценки. Майские мастер-классы в future.csv остаются прогнозами без меток.
Замените незавершённое разделение по позициям. Взаимно однозначный merge связывает метки по session_id, не предполагая, что первая строка соответствует первой строке. pd.to_datetime разбирает календарные даты, pd.Timestamp — настроенные границы, а булевы маски выбирают нужные строки. Сортировка по дате, затем по ID делает порядок читаемым; написание ID никогда не определяет период. .copy() создаёт независимые выбранные таблицы.
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
Обучающий порядок должен быть W-91, W-04, W-77, W-12, W-63, W-02; отложенные ID — W-88, W-09. Нерегулярные ID показывают, почему ни алфавитный порядок, ни две последние строки файла не определяют разделение.
./python show_results.py split
Проверьте W-88: он должен сохранить фактическую посещаемость 46 из соответствующей метки, а не метку в той же позиции строки. Сохранённые training.csv и holdout.csv пока содержат столбцы после мероприятия для осмотра. Следующий шаг выберет только два разрешённых признака; числовое хранение не делает столбец допустимым для прогноза.
Если случайно закрыли терминал, откройте Terminal → New Terminal и повторите cd выше. Ошибка «No such file or directory» обычно означает неверный каталог или опечатку в имени. Используйте pwd для текущего пути и ls для списка файлов, затем вернитесь в рабочую область и повторите правильную команду. Не перезапускайте лабораторную из-за обычной ошибки пути.
Изучить средние для пропусков только на обучении
На этом шаге вы обучите один преобразователь заполнения на ранних мастер-классах и повторно примените его к поздним снимкам, не обучаясь на них.
Продолжайте в WebIDE, в /home/labex/project/workshop-attendance. Можно редактировать baseline.py, split.py, prepare.py и свои файлы output/. Сохраните все предоставленные входы CSV/JSON, python, run.py, coursekit.py, show_results.py и каждый starter-*.py. Начальные копии позволяют восстановить модуль; можно также снова вставить его полную изученную версию. Основные функции должны оставаться пригодными при изменении дат, порядка строк и числовых значений.
Заполнение пропусков заменяет отсутствующий признак изученным значением. SimpleImputer(strategy="mean") изучает среднее арифметическое каждого столбца. Здесь обучающие наблюдения booked_7d — 10, 20, 40, 25 и 35: среднее равно 26. Среднее шести известных продолжительностей — 80 минут. Если взять все периоды, поздние мастер-классы повлияют на эти обучающие решения даже без меток результатов. Обучайте после разделения, не до него.
FEATURES, предоставленный coursekit, — ровно ['booked_7d', 'duration_minutes']. Двойные скобки выбирают два столбца в этом порядке. fit_transform изучает средние и заполняет обучающую матрицу; transform повторно использует их для отложенной и будущей матриц. statistics_ показывает изученные средние в порядке признаков. Возвращаемые массивы сохраняют порядок строк входных таблиц, чтобы вспомогательная программа сохраняла их 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
Изученные средние должны быть booked_7d: 26.0 и duration_minutes: 80.0.
./python show_results.py prepare
В holdout-features.csv для W-88 используются 26 бронирований и наблюдаемые 150 минут; W-09 сохраняет 90 бронирований и получает 80 минут. В future-features.csv для F-101 используется то же обучающее среднее бронирований. Окончательные бронирования, сканирования, даты, ID и результаты не входят в эти числовые матрицы. Исходные пустые ячейки остаются неизменными.
Вы подготовили настоящую границу оценки от раннего к позднему. Это не доказывает, что будущее повторяет прошлое. Следующая независимая лабораторная обучит небольшую модель и сравнит непрерывные ошибки с обучающей медианной базой на той же размеченной отложенной выборке. Эквивалентные вычисления и иной порядок выходных строк принимаются при неизменных связях по ID и числовом смысле; разрешены абсолютный и относительный допуски 1e-8.
Резюме
Вы создали повторно используемый медианный базовый прогноз, измерили MAE в людях, связали результаты по ID и отделили ранние даты обучения от поздних дат оценки. Вы выбрали только сведения, доступные за семь дней, и обучили средние для заполнения пропусков исключительно на обучающих строках. Сохранённые таблицы сохраняют исходные идентификаторы, а входные данные остаются неизменными для следующего этапа анализа.



