Послепродажное обслуживание автомобилей сталкивается с парадоксом: сотни тысяч SKU, из которых 80% продаются реже раза в месяц, при этом дефицит одной критической детали останавливает автомобиль на неделю. Спрос на новые детали (cold start) вообще невозможно предсказать классическими методами. Мы решаем эту задачу, комбинируя ABC-классификацию с ML-моделями, адаптированными под разные типы спроса. Наш подход снижает уровень запасов на 15–25% при сохранении или улучшении сервисного уровня — это проверено на 50+ проектах в дистрибуции запчастей.
Почему Croston и TSB необходимы для intermittent demand?
Большинство деталей продаётся редко и неравномерно. ARIMA или Prophet на таком спросе дают ошибку MAPE >100%. Croston раздельно прогнозирует интервал между продажами и размер транзакции, а TSB (Teunter-Syntetos-Babai) добавляет адаптацию под устаревающие детали — это снижает bias на 30–50%. На реальных данных дистрибьютора Croston показал MAPE 78% против 142% у ARIMA — в 1.8 раза точнее.
from statsforecast.models import CrostonOptimized, IMAPA, TSB models = [ CrostonOptimized(), IMAPA(), TSB(alpha_d=0.1, alpha_p=0.1) ] Сравнение методов прогноза для intermittent demand:
| Модель | MAPE на C-классе | Применимость |
|---|---|---|
| CrostonOptimized | 78% | Редкий спрос без тренда |
| TSB | 72% | Редкий спрос с устареванием |
| ARIMA | 142% | Частый спрос |
| Prophet | 115% | Частый спрос с сезонностью |
Как park-based forecast повышает точность?
Спрос на запчасти определяется не только историей продаж, но и парком автомобилей. Мы строим модель: спрос = количество машин × вероятность отказа детали в зависимости от возраста. Источник данных — регистрационные базы (парк по моделям и годам).
def park_based_forecast(part_number, region): applicable_models = parts_catalog.get_applicable_models(part_number) park = vehicle_registration_db.count( models=applicable_models, region=region, age_range=(2, 20) ) failure_curve = get_failure_rate_curve(part_number) expected_demand = sum( park[age] * failure_curve[age] for age in range(2, 21) ) / 12 return expected_demand Этот метод особенно эффективен для новых деталей или при выводе продукта (cold start), когда истории продаж ещё нет.
Оптимизация safety stock с учётом асимметрии затрат
Классический newsvendor model: мы оптимизируем страховой запас не по симметричному нормальному распределению, а по реальным затратам на дефицит (простой клиента, потеря лояльности) и хранение. Себестоимость дефицита критической детали может в 50 раз превышать стоимость хранения — safety stock для таких SKU поднимается до z=3.0 против стандартного z=1.65. Типичная экономия от такого подхода — до $18k–26k в год для среднего склада.
| Класс деталей | Сервисный уровень | Коэффициент z | Cost ratio (дефицит/хранение) |
|---|---|---|---|
| Критические (immobilizing) | 98–99% | 2.0–2.3 | 30:1 – 50:1 |
| Стандартные расходники | 93–95% | 1.5–1.65 | 10:1 – 20:1 |
| C-класс (медленные) | 85–90% | 1.0–1.28 | 2:1 – 5:1 |
from scipy.stats import norm def optimal_safety_stock(mean_demand, std_demand, lead_time_days, service_level=0.95, holding_cost_rate=0.25, stockout_cost=50.0): cu = stockout_cost co = holding_cost_rate * unit_cost / 365 critical_ratio = cu / (cu + co) z = norm.ppf(critical_ratio) demand_during_lt = mean_demand * lead_time_days std_during_lt = std_demand * np.sqrt(lead_time_days) safety_stock = z * std_during_lt reorder_point = demand_during_lt + safety_stock return safety_stock, reorder_point Детали расчёта critical ratio
Формула critical_ratio = Cu / (Cu + Co) — где Cu (cost of understock) — потери от дефицита, Co (cost of overstock) — издержки хранения избытка. При Cu/Co = 50 critical_ratio ≈ 0.98, что соответствует сервисному уровню 98%.Как ML Ops поддерживает модели в продакшене?
Модели деградируют со временем: меняются парк автомобилей, сезонность, ассортимент. Мы настроили ML Ops-конвейер: автоматическое переобучение при снижении точности (alert при MAPE > 90%), логирование метрик в MLflow, A/B-тестирование новых версий. Это гарантирует стабильную работу прогнозов без ежемесячного ручного вмешательства.
Управление устаревающими деталями (phase-out)
Снятая с производства модель — спрос угасает, но не мгновенно. TSB-модель выявляет тренд на снижение, а наш скрипт детектирует признаки EOL:
def detect_obsolescence_risk(part_number, sales_history): trend = np.polyfit(range(len(sales_history)), sales_history, 1)[0] park_decline = get_park_trend(part_number) if trend < -0.1 and park_decline < -0.05: return 'phase_out', suggest_final_buy_quantity(part_number) return 'active', None Final buy — расчёт оптимального заказа на 5–7 лет гарантийного обслуживания. Мы учитываем, что после EOL детали дорожают или становятся недоступны.
Multi-echelon: снижение bullwhip effect
В цепочке OEM → дистрибьютор → дилер вариация спроса усиливается. Мы синхронизируем safety stock на всех уровнях: чем выше буфер у дилера, тем меньше страховой запас дистрибьютора. VMI (Vendor Managed Inventory) в реальном времени пополняет склад дилера — это снижает общий запас по цепочке на 15–20%.
Что входит в работу
- Аудит данных: история продаж, парк автомобилей, каталог деталей.
- Построение ML-моделей: Croston, TSB, park-based, сезонные факторы.
- Оптимизация safety stock и reorder points (дифференцированные сервисные уровни).
- Phase-out management и final buy рекомендации.
- Дашборд с прогнозами, alerting по дефициту/излишкам.
- Интеграция с WMS/ERP, настройка VMI.
- Обучение команды и эксплуатационная документация.
Окупаемость решения составляет менее 12 месяцев. Свяжитесь с нами — оценим ваш складской портфель и покажем потенциал снижения запасов. Наша команда: 10+ лет в ML-решениях для логистики, 50+ внедрённых проектов, сертифицированные специалисты по Croston method.







