Налаштування персоналізованих рекомендацій на основі поведінки 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування персоналізованих рекомендацій на основі поведінки 1С-Бітрікс
Проста
~1 робочий день
Часті питання

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

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування персоналізованих рекомендацій на основі поведінки 1С-Бітрікс

Персоналізовані рекомендації на основі поведінки — це середній рівень між "подібними по категорії" й повноцінним ML. Не потрібна окрема Python-інфраструктура: усе будується на даних з бази Бітрикса й кількох SQL-запитах. Працює гірше нейронних мереж, але в рази краще простих "подібних товарів" й потребує тільки PHP + PostgreSQL.

Поведінські сигнали й їхні ваги

Різні дії користувача мають різну цінність як сигнал інтересу. Типова шкала:

Событие Вага
Покупка товара 10
Додавання в кошик 5
Додавання в избранное 4
Перегляд карточки (>30 сек) 2
Перегляд карточки (<30 сек) 1
Пошуковий запит з переходом 3

Ваги зберігаються в конфігурації, события — в таблиці b_user_behavior (структура описана в статті про персоналізацію). Ключове поле: EVENT_TYPE з значеннями purchase, cart_add, wishlist, view.

Item-based коллаборативна фільтрація без ML

Суть: "користувачі, які дивилися товар A, також дивилися товари B, C, D". Це рахується напряму зі бази без ML-моделі:

SELECT
    b2.ENTITY_ID AS recommended_id,
    COUNT(DISTINCT b2.USER_ID) AS co_view_count
FROM b_user_behavior b1
JOIN b_user_behavior b2
    ON b1.USER_ID = b2.USER_ID
    AND b1.ENTITY_ID != b2.ENTITY_ID
    AND b2.EVENT_TYPE IN ('view', 'cart_add', 'purchase')
    AND b2.DATE_CREATE > NOW() - INTERVAL '60 days'
WHERE
    b1.ENTITY_ID = :current_item_id
    AND b1.EVENT_TYPE IN ('view', 'cart_add', 'purchase')
GROUP BY b2.ENTITY_ID
ORDER BY co_view_count DESC
LIMIT 20;

Цей запит виконується офлайн (раз на годину через агент) й результат кешується в окремій таблиці:

CREATE TABLE b_item_recommendations (
    ITEM_ID          INT NOT NULL,
    RECOMMENDED_ID   INT NOT NULL,
    SCORE            FLOAT NOT NULL,
    UPDATED_AT       TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (ITEM_ID, RECOMMENDED_ID)
);
CREATE INDEX idx_item_recs_item ON b_item_recommendations(ITEM_ID, SCORE DESC);

Персональний рейтинг для конкретного користувача

Із 20 кандидатів-рекомендацій вибрати 6–8 найбільш релевантних для поточного користувача. Використовуємо його поведінський профіль:

function getPersonalizedRecs(int $itemId, int $userId, int $limit = 8): array {
    // 1. Отримати кандидатів з item-based таблиці
    $candidates = getCandidates($itemId, 20);

    if (empty($candidates) || !$userId) {
        return array_slice($candidates, 0, $limit);
    }

    // 2. Отримати категорії з історії користувача
    $userCategoryIds = getUserTopCategories($userId, 10);

    // 3. Boosting: поднять товари з переважаних категорій
    foreach ($candidates as &$candidate) {
        $sectionId = getElementSectionId($candidate['id']);
        if (in_array($sectionId, $userCategoryIds)) {
            $candidate['score'] *= 1.5;
        }
    }

    // 4. Убрать уже куплені товари
    $purchased = getUserPurchasedIds($userId);
    $candidates = array_filter($candidates,
        fn($c) => !in_array($c['id'], $purchased)
    );

    usort($candidates, fn($a, $b) => $b['score'] <=> $a['score']);
    return array_column(array_slice($candidates, 0, $limit), 'id');
}

Кеширування й відображення

Користувацький компонент local:catalog.recommendations приймає ELEMENT_ID й виводить рекомендовані товари. Кеш будується на рівні item_id — не персональний, а item-based (одинакові кандидати для усіх). Персональний буст застосовується через окремий AJAX-виклик після загрузки основного блока.

Такий підхід дозволяє кешувати основний блок рекомендацій на рівні Бітрикса й при цьому показувати кожному користувачу персоналізований порядок без зайвих запитів до бази при рендерингу сторінки.

Перенос історії при авторизації

Бітрікс не переносить поведінську історію аноніма на авторизованого користувача автоматично. Обробник OnAfterUserLogin:

AddEventHandler('main', 'OnAfterUserLogin', function($fields) {
    $fuserId = \CSaleUser::GetAnonymousUserID();
    if (!$fuserId) return;

    $DB->Query("
        UPDATE b_user_behavior SET USER_ID = " . (int)$fields['USER_ID'] . "
        WHERE SESSION_ID = '" . $DB->ForSql(session_id()) . "'
          AND USER_ID IS NULL
    ");
});