Разработка AI-системы управления ассортиментом

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-системы управления ассортиментом
Средняя
~1-2 недели
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Реализация AI-системы управления ассортиментом

AI-управление ассортиментом определяет какие товары держать в каждой точке продаж (или категории сайта), в каком количестве и по какой цене. Цель: максимизировать выручку при ограниченном SKU-пространстве полок. Система анализирует продажи, сезонность, каннибализацию и рекомендует ввод/вывод позиций.

Оптимизация ассортимента

import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from anthropic import Anthropic

class AssortmentOptimizer:
    def __init__(self):
        self.llm = Anthropic()
        self.demand_model = None
        self.cannibalization_matrix = None

    def train_demand_model(self, sales_df: pd.DataFrame):
        """Модель прогноза спроса для новых позиций"""
        features = ['price', 'category_encoded', 'brand_encoded',
                    'seasonality_index', 'days_available', 'marketing_spend']
        available = [f for f in features if f in sales_df.columns]

        X = sales_df[available].fillna(0)
        y = sales_df['weekly_units_sold']

        self.demand_model = GradientBoostingRegressor(
            n_estimators=200, learning_rate=0.05, random_state=42
        )
        self.demand_model.fit(X, y)

    def estimate_cannibalization(self, category_sales: pd.DataFrame) -> pd.DataFrame:
        """Матрица каннибализации между товарами одной категории"""
        # Коэффициент каннибализации через correlation продаж
        pivot = category_sales.pivot_table(
            index='week', columns='sku', values='units_sold', fill_value=0
        )

        # Отрицательная корреляция = каннибализация
        corr = pivot.corr()
        cannibalization = pd.DataFrame(
            np.where(corr < -0.3, abs(corr), 0),
            index=corr.index, columns=corr.columns
        )
        self.cannibalization_matrix = cannibalization
        return cannibalization

    def recommend_assortment_changes(self, current_assortment: pd.DataFrame,
                                      candidates: pd.DataFrame,
                                      shelf_space: int) -> dict:
        """Рекомендации по изменению ассортимента"""
        # Метрики текущего ассортимента
        performance = current_assortment.copy()
        performance['margin_per_sqft'] = (
            performance['weekly_margin'] /
            performance['shelf_space_sqft'].clip(0.1)
        )
        performance['sales_velocity'] = performance['weekly_units_sold']

        # Слабые позиции
        weak_threshold = performance['margin_per_sqft'].quantile(0.25)
        to_remove = performance[
            (performance['margin_per_sqft'] < weak_threshold) &
            (performance['weeks_in_assortment'] > 8)
        ]['sku'].tolist()

        # Сильные кандидаты для ввода
        if self.demand_model is not None and not candidates.empty:
            available_features = [f for f in self.demand_model.feature_names_in_
                                   if f in candidates.columns]
            X_cand = candidates[available_features].fillna(0)
            candidates['predicted_demand'] = self.demand_model.predict(X_cand)
            candidates['predicted_margin'] = (
                candidates['predicted_demand'] * candidates['gross_margin']
            )
            to_add = candidates.nlargest(len(to_remove), 'predicted_margin')['sku'].tolist()
        else:
            to_add = []

        # AI-объяснение рекомендаций
        explanation = self._explain_recommendations(to_remove, to_add, performance)

        return {
            'remove': to_remove,
            'add': to_add,
            'expected_margin_lift': len(to_remove) * performance['margin_per_sqft'].quantile(0.75) * 0.1,
            'explanation': explanation
        }

    def _explain_recommendations(self, to_remove: list, to_add: list,
                                   performance: pd.DataFrame) -> str:
        if to_remove:
            removed_stats = performance[performance['sku'].isin(to_remove)][
                ['sku', 'margin_per_sqft', 'weeks_in_assortment']
            ].to_dict('records')
        else:
            removed_stats = []

        response = self.llm.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=200,
            messages=[{
                "role": "user",
                "content": f"""Explain these assortment change recommendations to a category manager.

Remove {len(to_remove)} SKUs: {removed_stats[:3]}
Add {len(to_add)} SKUs: {to_add[:3]}

2-3 sentences: business rationale for the changes."""
            }]
        )
        return response.content[0].text

Автоматическое управление ассортиментом типично увеличивает выручку на 4-8% и снижает markdown (уценки) на 15-25%. Частота пересмотра: еженедельно для быстрооборачиваемых категорий (FMCG), ежемесячно для fashion/electronics. Минимальный период наблюдения перед выводом SKU: 6-8 недель для стабилизации продаж.