Воспроизводимость анализа: скрипты, версии, окружение
Воспроизводимость — это возможность получить тот же результат из тех же данных и кода. Она не требует идеальной чистоты проекта, но требует, чтобы ключевые шаги были записаны, а не восстанавливались по памяти.
Проверка простая: может ли коллега, не участвовавший в работе, запустить анализ и получить ваши числа?
Структура проекта
Разложите файлы по назначению: исходные данные, скрипты, промежуточные результаты, финальные таблицы и рисунки. Исходные данные не редактируйте вручную — любые правки оформляйте скриптом.
Распространённая схема: папки data-raw, data, scripts, output. Главный скрипт запускает всё по порядку, чтобы не приходилось вспоминать, какой файл за каким идёт.
Пути и имена
Абсолютные пути вида /Users/имя/Desktop/... ломаются на другом компьютере. Используйте относительные пути от корня проекта.
Имена файлов без пробелов и кириллицы избавляют от проблем с кодировкой в разных системах. Даты в формате ГГГГ-ММ-ДД сортируются правильно.
Версии пакетов
Разные версии библиотек дают разные результаты — от изменения алгоритмов до формата вывода. Зафиксируйте версии.
В R для этого служит renv: он создаёт проектную библиотеку и файл блокировки с версиями. В Python — виртуальное окружение (venv, conda) и файл зависимостей, полученный через pip freeze.
Записывайте также версию языка и операционной системы: они влияют на численные библиотеки.
Случайность
Если в анализе есть случайные шаги — начальная инициализация, бутстреп, разбиение на фолды, — фиксируйте seed. Без этого повторный запуск даст другие числа.
Записывайте seed в скрипт и в журнал. Если методов несколько, у каждого должен быть свой воспроизводимый генератор.
Журнал запусков
Ведите короткий журнал: дата, версия скрипта, входные данные, ключевые результаты. Он помогает понять, какая версия породила таблицу в статье.
Если проект в Git, коммит заменяет часть журнала: хеш фиксирует состояние кода. Но данные и параметры запуска всё равно нужно описывать.
Проверка «с чистого листа»
Самый надёжный тест — запустить анализ на другом компьютере или в чистом контейнере. Обычно сразу обнаруживаются забытые зависимости и ручные правки.
Проверьте не только финальные числа, но и промежуточные таблицы: расхождение может возникнуть на этапе очистки данных.
Что делать с большими данными
Если данные не помещаются в репозиторий, опишите, где они лежат, как получены и по какому запросу. Приложите скрипт, который их скачивает или собирает.
Для больших наборов укажите контрольные суммы: они подтверждают, что файл не изменился.
Что писать в статье
В разделе о доступности данных перечислите: где лежит код, где данные, какая версия использована, как запустить анализ.
Если данные нельзя открыть, объясните причину и опишите условия доступа. Формулировка «данные доступны по запросу» без процедуры мало помогает.
Частые ошибки
- ручная правка данных без записи;
- абсолютные пути в скриптах;
- отсутствие фиксации версий;
- незафиксированный seed;
- скрипт, который не запускается вне вашей машины;
- данные без описания и контрольных сумм;
- отсутствие порядка запуска.
Документация для себя
Через полгода вы не вспомните, почему фильтр стоит именно такой. Короткий комментарий к неочевидному шагу экономит часы.
Пишите комментарии о причинах, а не о механике: «исключены записи с длительностью менее 3 с — артефакт запуска» полезнее, чем «фильтр по длительности».
Когда воспроизводимость недостижима
Для полевых данных, уникального оборудования или закрытых наборов полная воспроизводимость невозможна. В этом случае описывают процесс и ограничения честно.
Цель — прозрачность: читатель должен понимать, что можно проверить, а что нет.
Версии данных, а не только кода
Код без данных воспроизводит процесс, но не результат. Зафиксируйте, какая выгрузка использована: дата, источник, фильтры, хеш файла.
Если данные обновляются регулярно, храните снимок на дату анализа. Иначе повторный запуск через месяц даст другие числа при том же коде, и объяснить расхождение будет нечем.
Порядок запуска и зависимости между шагами
Явно опишите, какие скрипты должны выполняться до каких. Скрытые зависимости всплывают при первом запуске на новой машине.
Автоматизируйте цепочку через Makefile или скрипт-обёртку. Одна команда вместо пяти ручных шагов снижает вероятность пропустить этап.
Чек-лист
- Проект разделён на данные, код и результаты.
- Пути относительные.
- Версии пакетов зафиксированы.
- Seed записан для всех случайных шагов.
- Есть скрипт, запускающий анализ целиком.
- Проверка выполнена на чистой машине.
- Описание доступности данных есть в статье.
Частые вопросы
Обязательно ли использовать Git?
Нет, но он самый простой способ фиксировать версии. Для небольших проектов достаточно архива с датами, если описан порядок запуска.
Что делать, если анализ делался в Excel?
Опишите шаги вручную и сохраните промежуточные файлы. Полной воспроизводимости не будет, но прозрачность повысится.
Нужно ли выкладывать код, если он некрасивый?
Да, если это позволяет проверить результат. Оформление можно улучшить позже; отсутствие кода хуже, чем несовершенный код.
Как быть с проприетарным ПО?
Укажите версию, параметры и последовательность действий. Если возможно, приложите экспорт результатов.