Разработка системы рекомендаций товаров для интернет-магазина

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка системы рекомендаций товаров для интернет-магазина
Сложная
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка системы рекомендаций товаров для интернет-магазина

Система рекомендаций — это алгоритмический движок, который увеличивает средний чек и глубину просмотра каталога. «Amazon рекомендует» — не маркетинговый слоган, а сложная инфраструктура с коллаборативной фильтрацией, поведенческими моделями и ML-пайплайнами. Разработка рекомендательной системы занимает от 10 до 20+ рабочих дней в зависимости от подхода.

Уровни сложности рекомендаций

Рекомендательные алгоритмы делятся по уровню сложности:

Уровень Подход Применимость
Базовый Rule-based (популярные, новинки, скидки) Старт любого магазина
Средний Item-based collaborative filtering 10k+ заказов в БД
Продвинутый Matrix factorization (ALS, SVD) 100k+ событий
Enterprise Deep learning (two-tower, BERT4Rec) ML-инфраструктура

Для большинства интернет-магазинов оптимален средний уровень: коллаборативная фильтрация по заказам, дополненная контентными сигналами.

Rule-based рекомендации (базовый уровень)

Запускается быстро, не требует накопленных данных:

class PopularityRecommender
{
    public function getPopular(int $categoryId, int $limit = 8): Collection
    {
        return Product::where('category_id', $categoryId)
            ->where('is_active', true)
            ->withCount(['orderItems as sales_count' => fn($q) =>
                $q->whereHas('order', fn($o) =>
                    $o->where('status', 'completed')
                      ->where('created_at', '>=', now()->subDays(30))
                )
            ])
            ->orderByDesc('sales_count')
            ->limit($limit)
            ->get();
    }
}

Для новых пользователей — популярные товары. Для пользователей с историей — персональные.

Коллаборативная фильтрация по заказам

«Пользователи, купившие этот товар, также покупали...» — классический item-to-item CF:

-- Матрица совместных покупок
CREATE MATERIALIZED VIEW product_cooccurrences AS
SELECT
    oi1.product_id AS product_a,
    oi2.product_id AS product_b,
    COUNT(DISTINCT oi1.order_id) AS cooccurrence_count
FROM order_items oi1
JOIN order_items oi2
    ON oi1.order_id = oi2.order_id
    AND oi1.product_id != oi2.product_id
JOIN orders o ON oi1.order_id = o.id
WHERE o.status = 'completed'
GROUP BY oi1.product_id, oi2.product_id
HAVING COUNT(DISTINCT oi1.order_id) >= 3;

CREATE INDEX idx_cooc_product_a ON product_cooccurrences(product_a, cooccurrence_count DESC);

Обновление materialized view — ночной cron:

$schedule->command('db:refresh-cooccurrences')->dailyAt('03:00');

Запрос рекомендаций по просматриваемому товару:

class CollaborativeRecommender
{
    public function getSimilar(int $productId, int $limit = 8): Collection
    {
        $recommendedIds = DB::table('product_cooccurrences')
            ->where('product_a', $productId)
            ->orderByDesc('cooccurrence_count')
            ->limit($limit)
            ->pluck('product_b');

        return Product::whereIn('id', $recommendedIds)
            ->where('is_active', true)
            ->orderByRaw("array_position(ARRAY[" . $recommendedIds->implode(',') . "]::bigint[], id)")
            ->get();
    }
}

Персонализация по истории пользователя

Для авторизованных пользователей — рекомендации на основе их заказов и просмотров:

class PersonalizedRecommender
{
    public function getForUser(User $user, int $limit = 12): Collection
    {
        // Категории из последних 5 заказов
        $recentCategories = OrderItem::whereHas('order', fn($q) =>
            $q->where('user_id', $user->id)->latest()->limit(5)
        )->with('product:id,category_id')
         ->get()
         ->pluck('product.category_id')
         ->unique();

        // Товары из этих категорий, которые пользователь ещё не покупал
        $purchasedIds = $user->orders()
            ->with('items:product_id')
            ->get()
            ->flatMap(fn($o) => $o->items->pluck('product_id'))
            ->unique();

        return Product::whereIn('category_id', $recentCategories)
            ->whereNotIn('id', $purchasedIds)
            ->where('is_active', true)
            ->inRandomOrder() // или по рейтингу
            ->limit($limit)
            ->get();
    }
}

ML-рекомендации через Python-сервис

Для продвинутого уровня: Python-микросервис на FastAPI с моделью ALS (Alternating Least Squares) из библиотеки implicit:

# recommendations_service/main.py
import implicit
import numpy as np
from scipy.sparse import csr_matrix
from fastapi import FastAPI

app = FastAPI()
model = implicit.als.AlternatingLeastSquares(factors=64, iterations=20)

@app.get("/recommendations/user/{user_id}")
async def user_recommendations(user_id: int, n: int = 12):
    user_idx = user_id_to_idx.get(user_id)
    if user_idx is None:
        return {"items": get_popular_fallback(n)}

    ids, scores = model.recommend(user_idx, user_item_matrix[user_idx], N=n)
    product_ids = [idx_to_product_id[i] for i in ids]
    return {"items": product_ids, "scores": scores.tolist()}

PHP-бэкенд запрашивает сервис и кеширует результат:

$recommendations = Cache::remember(
    "recs:user:{$userId}",
    1800,
    fn() => Http::timeout(2)->get("{$this->mlServiceUrl}/recommendations/user/{$userId}", ['n' => 12])
                ->throw()
                ->json('items')
);

Fallback при недоступности ML-сервиса — rule-based рекомендации.

Трекинг событий для обучения модели

Качество рекомендаций зависит от данных. Трекинг событий:

// Просмотр товара
api.post('/events', {
  type: 'product_view',
  product_id: product.id,
  session_id: getSessionId(),
  timestamp: new Date().toISOString(),
});

// Добавление в корзину
api.post('/events', { type: 'add_to_cart', product_id, quantity });

// Покупка (через backend после создания заказа)
CREATE TABLE recommendation_events (
    id BIGSERIAL PRIMARY KEY,
    event_type VARCHAR(30) NOT NULL,
    user_id BIGINT,
    session_id VARCHAR(64),
    product_id BIGINT,
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_rec_events_user ON recommendation_events(user_id, created_at DESC);

A/B тестирование алгоритмов

Разные алгоритмы показываются разным сегментам пользователей:

$algorithm = $user->id % 2 === 0 ? 'collaborative' : 'ml';
$recommendations = $this->recommenderFactory->make($algorithm)->get($user, $product);

// Логируем для анализа CTR и конверсии
event(new RecommendationShown($user, $recommendations, $algorithm, $context));

После 2–4 недель сравниваем CTR и конверсию по алгоритмам и выбираем победителя.

Размещение блоков рекомендаций

  • Страница товара: «С этим товаром покупают», «Похожие товары»
  • Корзина: «Вы забыли добавить», «Дополните комплект»
  • Главная страница: «Персональные рекомендации», «Популярное»
  • Email после покупки: «Вам может понравиться»
  • Пустая страница поиска: «Попробуйте эти товары»