О проекте
Команда: Axioma
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Доведённый продукт
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Streamlit-сервис для закупщика Электрокомплект: импортирует Excel/ZIP поставщиков, прогнозирует спрос, рассчитывает объяснимый проект заказа с учётом остатков и поступлений и сохраняет утверждение менеджера с экспортом в Excel.
Как устроено
Из накладных выделяются разовые крупные покупки, месячные данные сверяются с детализацией, а спрос корректируется на подтверждённые дни отсутствия товара. Модель выбирается автоматически из средних за 3 или 6 месяцев, экспоненциального сглаживания, прошлого сезона и сезонности; есть общая ML-модель по пулу SKU. Заказ считается от свободного остатка, страхового запаса, поступлений по датам и промежуточного дефицита, затем округляется по MOQ и кратности. Неизвестный остаток не приравнивается к нулю. Менеджер проверяет и утверждает заказ, причины изменений фиксируются вместе со снимком расчёта.
Ключевые решения
- exponential smoothing
- seasonal naive
- moving average auto-selection
- pooled ML demand model
- anomaly/one-off purchase detection
- stockout demand correction
- safety stock и reorder point
- MOQ rounding
- WAPE backtest
- inventory policy simulation
- scenario grid ±20%
Метрики
154 теста; 3 045 SKU × 6 мес.: средняя WAPE ниже 6-мес. среднего на 3,22% (IEK) и 6,08% (Systeme Electric); доля спроса, обслуженного сразу: ML 78,52% против простого среднего 78,66% (SE), 67,50% против 70,19% (IEK)
Особенности
Команда честно признаёт, что в симуляции запасов ML не превосходит простое среднее, и публикует все проигрыши. Неизвестный остаток отделён от нулевого. Промежуточный дефицит проверяется по дневному балансу. На вкладке «Проверка кейса» лежат 11 воспроизводимых примеров, есть протокол пилота.
Стек
Python · Streamlit · pandas · Docker · GitHub Actions
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-8b028a15-axioma.
README
README.mdAxioma — объяснимое пополнение склада
Excel/ZIP → прогноз спроса → проект заказа → проверка менеджером → сохранённый Excel. Сервис для закупщика Электрокомплект отделяет разовые покупки, учитывает остатки и даты поступлений, показывает причину количества и фиксирует утверждение.
Основной вход — app.py. Демо из шести синтетических товаров работает без ключей, аккаунтов и файлов компании. Объединены доработки команды: общая ML-модель, статистические модели, сценарии неизвестных остатков, календарь дефицита и журнал заказов. Независимый режим app_extended.py сохранён отдельно.
Что уже проверено
- 154 автоматических теста после объединения на macOS / Python 3.14 (базовая версия команды: 133 на Windows / Python 3.12), включая основной интерфейс, импорт, арифметику и сохранение утверждения после новой сессии.
- 12 исходных XLSX прочитаны целиком: 3 184 товара IEK и 724 Systeme Electric.
- 3 045 товаров × 6 месяцев в исторической проверке. Средняя WAPE по SKU основного режима ниже среднего за 6 месяцев на 3,22% для IEK и 6,08% для Systeme Electric. Некоторые товары и показатели лучше у других методов; сравнение всех семи опубликовано.
- 11 воспроизводимых примеров для пяти обязательных требований доступны на вкладке «Проверка кейса».
Исторические месяцы использовались при разработке: это диагностика, а не независимое доказательство качества на будущем периоде. Процент изменения ошибки не является денежной экономией. Полный протокол и ограничения.
Что показала проверка решений по запасам
В app.py появилась «Проверка эффекта»: одинаковые условия → три политики → дневной баланс → проигранные случаи → ZIP протокола. Можно ввести собственные ставки затрат, увидеть чувствительность и скачать пустые задания для контрольного пилота. Цены компании не выдумываются.
Новый результат не подтверждает превосходство ML. В ретроспективной симуляции на первых 100 подходящих SKU каждого поставщика, при потерянной продаже:
| Поставщик | Простое среднее: обслужено сразу | Общая ML: обслужено сразу | SKU с положительным спросом / проверено |
|---|---|---|---|
| Systeme Electric | 78,66% | 78,52% | 44 / 100 |
| IEK | 70,19% | 67,50% | 73 / 100 |
Это средние доли по SKU, не фактически предотвращённые потери. Условия: июнь–август 2026, начальный запас 21 день прошлого спроса, срок/пересмотр/страховка 21/14/7; месячные продажи равномерно распределены по дням. Общая модель обучается на выбранной сотне товаров. Этот период уже просматривался; независимого финального теста нет. При отложенном спросе ML улучшает немедленное обслуживание Systeme Electric (71,83% против 69,41%), но уступает среднему у IEK (54,96% против 56,73%). Простой метод доступен в настройках; алгоритмы не подгонялись под результат. Оба режима дефицита, автовыбор, запас, смещение, все проигрыши и команды.
Скриншот «Проверки эффекта» на шести синтетических товарах

Это отдельный синтетический пример. Результаты компании и проигранные случаи приведены в таблице выше и полном протоколе.
Запуск
Рекомендуется Python 3.12. Интернет нужен один раз для установки зависимостей. Из папки проекта в Windows PowerShell:
py -3.12 -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt
.venv\Scripts\python.exe -m streamlit run app.py --server.headless true
macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python -m streamlit run app.py --server.headless true
Открыть http://localhost:8501. start.ps1 и start.command упрощают локальный запуск. Менять политику безопасности PowerShell не нужно: при запрете скриптов используйте команды выше. Объединённая версия проверена на Windows и macOS; Docker и CI-конфигурации сохранены, успешный запуск в этих средах не заявляется.
Демонстрация за 3 минуты
- Оставить «Показать пример». Открыть «Почему столько» → DEMO-001. Одна покупка на 1 500 единиц выделена отдельно; выключение фильтра меняет расчёт.
- Выбрать DEMO-004: 20 подтверждённых дней отсутствия. Переключить восстановление спроса и сравнить результат.
- Показать дату риска дефицита и дневной баланс: поздняя поставка не скрывает промежуточный недостаток. Ускорение до прихода нового заказа показано отдельно.
- В «Рекомендации» открыть «Проверить и утвердить заказ»: отметить строку, указать ответственного; при изменении количества — причину. Нажать «Утвердить и сохранить заказ».
- В «История» открыть сохранённое утверждение и скачать Excel. Заказы разных поставщиков объединяются в общую корзину. Изменение параметров текущего расчёта не переписывает историю.
- «Проверка кейса» → «Запустить проверку требований»: 11 примеров до/после. Для реальной точности показать протокол; полный backtest во время короткой защиты запускать необязательно.
Дополнительно: «Проверка эффекта» → сравнить политики → показать проигранные случаи → скачать ZIP и задания пилота.
Сценарий защиты и ответы жюри · Карта требований
Данные и допущения
В режиме «Файлы поставщика» выбрать поставщика и загрузить ZIP либо все шесть XLSX. ZIP читается в памяти. Ожидаются месячные продажи, детализация накладных, остатки/сводка, товары в пути, категории и сезонность; распознанные источники видны в «Качество данных». Пример имён и подробности — требования.
Неизвестный остаток не равен нулю. В IEK нет актуального свободного остатка для всех 3 184 позиций. В Systeme Electric он известен для 497, неизвестен для 227. Для неизвестного остатка показывается порог пополнения; безусловное количество блокируется. Можно загрузить заполненный CSV-шаблон либо явно выбрать сценарий из прошлого снимка. Сценарий хранит источник, дату и использованные продажи; при утверждении требуется подтвердить допущение.
В «Данные и допущения» доступны редактор, CSV-шаблон и сохранение для того же набора исходных файлов. CSV использует код sku; поля stock, lead_days, category, pack, moq, source_growth необязательны. Пустое значение сохраняет прежние данные, явный ноль задаёт нулевой остаток. lead_days — целое число 1–365. Неизвестные коды показываются отдельно.
В исходных архивах нет ID клиента и точных ежедневных периодов отсутствия. При наличии client_id алгоритм объединяет накладные клиента за день; этот случай проверен синтетически. Подтверждённые периоды отсутствия вводятся CSV sku,start,end включительно. Месячный нулевой снимок — отдельное приближение, по умолчанию выключено.
Срок новой поставки по умолчанию 21 день, до следующего заказа 14 дней, страховой запас 7 дней — видимые стартовые допущения. Коэффициенты категорий и срок поставки следует согласовать с владельцем кейса. Прирост из сводки хранится долей (0.2 = +20%) и включается отдельно; он заменяет исторический компонент роста. Дополнительный процент в интерфейсе — отдельный ручной сценарий.
Заказ и MOQ/кратность основного режима выражены в исходной единице товара. Минимальная партия IEK не объявляется кратностью. Для кабеля в демо кратность 50 м показана явно. Перевод метров в бухты по заданному коэффициенту доступен в независимом дополнительном режиме; автоматический коэффициент из названия не угадывается.
Сценарии и приоритет пересчёта склада
Вкладка «Сценарии» сохраняет новую разработку команды: диапазон заказа по сетке остаток ±20%, спрос ±20%, известные поступления вовремя или +7 дней. Границы можно менять; это не вероятность и не доверительный интервал. На синтетическом демо расчёт выполняется сразу, большой каталог проверяется по кнопке, чтобы обычное открытие заказа не ожидало перебора вариантов.
Действия: подготовить заказ, ускорить поставку, проверить остаток. Очередь ставит выше товары, у которых уточнение остатка меняет заказ да/нет или срочность. DEMO-002 имеет неизвестный остаток и прошлый снимок; DEMO-005 не имеет даже пригодного снимка. В карточке можно внести подтверждённый свободный остаток: он сохраняется между сессиями для этих исходных файлов и даты расчёта, получает отметку происхождения и пересчитывает заказ.
После проверки сценарные диапазоны и допущения входят в снимок расчёта и утверждённый Excel. Срок поставки каждого товара учитывается отдельно. «Показать задержку на 7 дней» сравнивает решения при одинаковом спросе и остатке; срочность может измениться даже при неизменном размере обычного заказа.
Как получается количество
- По накладным или клиенту за день выявляются крупные события. Повторяемость клиента требует как минимум трёх месяцев и 90 дней; устойчивый поток крупных накладных сохраняется. Менеджер может признать событие регулярным или разовым.
- Перед вычитанием сверяются месячная ведомость и детализация. Расхождение больше
max(1 единица, 2% месячного итога)блокирует вычитание за этот месяц. Причина расхождения требует проверки владельцем данных. - Подтверждённое отсутствие корректирует наблюдённый спрос. Выбранная модель прогнозирует срок поставки и интервал пересмотра.
- Учитываются свободный остаток, страховой запас с множителем категории и поступления по датам. Дополнительно проверяется промежуточный дефицит после новой поставки, который скрывает простая сумма за весь период.
- Положительная потребность округляется вверх по минимуму и кратности. Риск до новой поставки требует ускорения или перемещения; этот объём не добавляется автоматически повторно.
- Менеджер проверяет количество, основание и исходные данные. Утверждение хранит снимок расчёта, ответственного, причину изменения и подтверждение сценария. Поставщику ничего автоматически не отправляется.
По умолчанию: компактный автовыбор среди средних 3/6 месяцев, экспоненциального сглаживания, прошлого сезона и сезонности с поправкой уровня. Выбор использует шесть прошлых месяцев; при двух полных активных годах с выраженным повторяющимся сезонным профилем — 12. Расширенный выбор с TSB/Croston–SBA, общая HistGradientBoosting-модель команды и исходная эвристика доступны в переключателе. Методология.
Проверка и воспроизведение
python -m pytest -q
python benchmark.py "IEK.zip" --output data/benchmark-iek
python benchmark.py "Systeme electric.zip" --output data/benchmark-systeme
python verify_real.py "IEK.zip" "Systeme electric.zip"
Без аргумента benchmark.py использует синтетическое демо. По умолчанию проверяются март–август 2026; --periods, --end, --max-skus меняют охват. Каждая внешняя точка заново обучает модели и строит фильтр только по предыдущим месяцам. Отсутствующий факт пропускается; нулевой факт учитывается. Текущие остатки, прирост, готовая сезонность поставщика и ретроспективные stockout-интервалы исключены. Метры и штуки в объёмной метрике оцениваются отдельно.
scripts/validate_history.py и старые отчёты сохранены как история разработки. Актуальные результаты объединённого режима: release-validation.md и агрегаты JSON.
Дополнительный режим команды
python -m streamlit run app_extended.py --server.port 8502
app_extended.py / axioma/ — самостоятельная методика дневного спроса, CSV-шаблоны и явный перевод метров в бухты. Её результаты не складываются с основным расчётом. data/demo/*.csv — синтетические данные. Описание. Обе реализации покрыты тестами; имена отчётов приведены к совместимым с Windows.
Материалы команды
Сценарии на полных архивах: 70 782 сочетания. Сохранены предыдущие замеры команды и протокол пилота; они относятся к указанной там версии и другому ноутбуку, а не к скорости текущего запуска.
Карта доказательств и измеримый пилот · Проверки нового раздела. Денежная экономия и сокращение активного времени менеджера пока не измерены.
Хранение и следующий этап
SQLite-база по умолчанию находится в data/axioma.sqlite3; путь задаётся через AXIOMA_DB. Настройки привязаны к отпечатку исходных файлов, история сохраняется между сессиями. Это локальный журнал, без входа пользователей и электронной подписи. Для рабочего внедрения нужны резервные копии, авторизация, политика хранения и интеграция с учётной системой.
Пилот: две недели параллельного расчёта с менеджером на новых данных. Измерять время подготовки заказа, долю ручных исправлений и дни дефицита. Получить ежедневный свободный остаток, обезличенный ID клиента и согласованные сроки. Денежный эффект считать после получения цен и затрат.
Команда, AI и сдача
main — объединённая версия; вклад участников сохранён в истории Git. Обновление кода в официальном репозитории и отправка карточки решения на платформе — разные действия. Текст карточки. localhost:8501 доступен только на компьютере запуска; публичное размещение не заявляется.
OpenAI Codex использован для разработки, объединения и тестирования. Внешние AI API при расчёте не вызываются. Коммерческие Excel, SQLite, секреты и виртуальное окружение исключены из репозитория и пакета. Сторонние компоненты: Python, Streamlit, pandas, NumPy, openpyxl, pytest, scikit-learn и SciPy; лицензии сохраняются в установленных пакетах. Исходные данные предоставлены владельцем кейса для хакатона.
Авторы коммитов
История коммитов
- 2026-09-23 17:45Clarify verification baseline for integrated releaseAmina-07-web
- 2026-09-23 17:43Merge team release and revalidate inventory experiments on current forecastsAmina-07-web
- 2026-09-23 17:34Add auditable inventory-policy experiments and pilot protocolAmina-07-web
- 2026-09-23 17:12Finalize integrated Axioma with reproducible forecast and decision evidencekama782
- 2026-09-23 17:04Контрольная точка 17:00lauraken
- 2026-09-23 17:03Integrate scenario workspace with persistent stock counts and audited orderskama782
- 2026-09-23 17:02Document measured workflow impact and add real demo screenshotsAmina-07-web
- 2026-09-23 16:50Улучшено оформление AXIOMAlauraken
Все коммиты (28)
- 2026-09-23 16:48Merge audited replenishment workflow, persistent approvals and six-month supplier validationkama782
- 2026-09-23 16:46Add scenario robustness, stock-count priorities and buyer decision workspaceAmina-07-web
- 2026-09-23 16:08Prevent transit timing gaps and add executable case evidence with review auditAmina-07-web
- 2026-09-23 16:01Integrate source reconciliation, auditable forecasts and persistent order approvalskama782
- 2026-09-23 15:49Merge pull request #1 from BAITC-Hacks/feature/axioma-locallauraken
- 2026-09-23 15:48Merge branch 'main' into feature/axioma-locallauraken
- 2026-09-23 15:40Integrate team changes and validate full supplier portfoliosAmina-07-web
- 2026-09-23 15:38Сохранены оба режима AXIOMAlauraken
- 2026-09-23 15:37Merge branch 'main' into feature/axioma-locallauraken
- 2026-09-23 15:27Add pooled demand learning and reviewed supplier order basketAmina-07-web
- 2026-09-23 15:20Add auditable forecasting candidates and causal demand safeguardsAmina-07-web
- 2026-09-23 15:12AXIOMA: прототип закупок, импорт данных и тестыlauraken
- 2026-09-23 15:08style: keep dashboard header visible below Streamlit toolbarkama782
- 2026-09-23 15:06fix: validate Windows workflow, ZIP import and demand source handlingkama782
- 2026-09-23 14:52Validate forecasts on held-out months and expose stock-independent reorder thresholdsAmina-07-web
- 2026-09-23 14:37Add transparent stock scenarios and per-product method comparisonAmina-07-web
- 2026-09-23 14:25Merge remote-tracking branch 'origin/main'Amina-07-web
- 2026-09-23 14:24Prioritize urgent orders and record confirmed submissionAmina-07-web
- 2026-09-23 14:24docs: record case requirements and source data findingskama782
- 2026-09-23 14:21Build explainable replenishment prototype with Excel imports and testsAmina-07-web
Структура репозитория (101 файлов)
.dockerignore .github/workflows/tests.yml .gitignore .streamlit/config.toml Dockerfile README.md SUBMISSION.md app.py app_extended.py axioma/__init__.py axioma/demo.py axioma/engine.py axioma/export.py axioma/importers.py axioma/model.py benchmark.py data/demo/incoming.csv data/demo/products.csv data/demo/sales.csv data/demo/stockouts.csv docs/DEMO.md docs/EXTENDED.md docs/JURY.md docs/benchmark-iek.json docs/benchmark-systeme.json docs/calculation-and-import.md docs/decision-checks.json docs/decision-verification.md docs/effect-verification.md docs/extended-progress.md docs/extended-validation.md docs/final-verification.md docs/images/decision-explanation.jpg docs/images/effect-synthetic.jpg docs/images/stock-count-queue.jpg docs/inventory-simulation-iek.json docs/inventory-simulation-systeme.json docs/inventory-simulation.md docs/measured-effect.md docs/methodology.md docs/pilot.md docs/progress.md docs/release-benchmark.json docs/release-decisions.json docs/release-validation.md docs/requirements.md docs/robustness.md docs/validation.md docs/verification.md docs/workflow-benchmark.json requirements-dev.txt requirements.txt scripts/check_decisions.py scripts/check_real_data.py scripts/compare_inventory.py scripts/generate_demo.py scripts/measure_workflow.py scripts/validate_history.py src/__init__.py src/anomalies.py src/backtest.py src/data.py src/effect.py src/engine.py src/evidence.py src/forecasting.py src/inputs.py src/orders.py src/planning.py src/pooled.py src/reconciliation.py src/robustness.py src/scenario_ui.py src/scenarios.py src/storage.py src/validation.py start.command start.ps1 tests/test_anomalies.py tests/test_app.py tests/test_case_acceptance.py tests/test_compact_forecasting.py tests/test_effect.py tests/test_engine.py tests/test_export.py tests/test_extended_app.py tests/test_extended_engine.py tests/test_forecasting.py tests/test_importers.py tests/test_inputs.py tests/test_integrated_workspace.py tests/test_orders.py tests/test_pooled.py tests/test_reconciliation.py tests/test_regressions.py tests/test_robustness.py tests/test_scenarios.py tests/test_storage.py tests/test_timing.py tests/test_validation.py verify_real.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.