Разработка AI-системы персонализации программы лояльности

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-системы персонализации программы лояльности
Сложная
~2-4 недели
Часто задаваемые вопросы
Направления 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-системы персонализации программы лояльности

Стандартная программа лояльности: купил на 1000 рублей — получил 10 баллов. AI-персонализация превращает это в: "Маше, которая любит кофе и покупает по утрам, предлагаем двойные баллы в кофейном разделе по будням до 10:00". Персонализированные программы лояльности показывают на 2-3x больший engagement и удержание.

Персонализация начисления баллов

from anthropic import Anthropic
import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from dataclasses import dataclass
from typing import Optional
import json

@dataclass
class LoyaltyOffer:
    user_id: str
    offer_type: str      # double_points, bonus_category, threshold_bonus, streak_reward
    category: Optional[str]
    multiplier: float
    min_purchase: Optional[float]
    valid_hours: Optional[tuple]
    valid_days: Optional[list]
    description: str
    expected_lift: float

class LoyaltyPersonalizationEngine:
    def __init__(self):
        self.llm = Anthropic()
        self.engagement_model = None
        self.user_preferences = {}

    def train_engagement_model(self, offers_history: pd.DataFrame):
        """
        offers_history: user_id, offer_type, category, multiplier,
                        was_shown, was_used, purchase_uplift
        """
        features = self._extract_offer_features(offers_history)
        X = features.drop(columns=['was_used'])
        y = features['was_used']

        from sklearn.model_selection import cross_val_score
        self.engagement_model = GradientBoostingClassifier(
            n_estimators=200, learning_rate=0.05, random_state=42
        )
        cv_scores = cross_val_score(self.engagement_model, X, y, cv=5, scoring='roc_auc')
        self.engagement_model.fit(X, y)
        print(f"Engagement model AUC: {cv_scores.mean():.3f} ± {cv_scores.std():.3f}")

    def _extract_offer_features(self, df: pd.DataFrame) -> pd.DataFrame:
        features = pd.DataFrame()
        features['multiplier'] = df['multiplier']
        features['has_category_restriction'] = (df['category'].notna()).astype(int)
        features['has_time_restriction'] = df.get('valid_hours', pd.Series([None] * len(df))).notna().astype(int)
        features['user_avg_purchase'] = df.get('user_avg_purchase', 500)
        features['user_purchase_frequency'] = df.get('user_purchase_frequency', 2)
        features['user_category_match'] = df.get('user_category_match', 0.5)
        features['was_used'] = df.get('was_used', 0)
        return features

    def generate_personalized_offers(self, user: dict,
                                      n_offers: int = 3) -> list[LoyaltyOffer]:
        """Генерация персонализированных предложений"""
        # Анализ предпочтений пользователя
        top_categories = user.get('top_categories', [])[:3]
        preferred_hours = user.get('preferred_purchase_hours', [10, 11, 12, 18, 19, 20])
        avg_basket = user.get('avg_order_value', 500)
        tier = user.get('loyalty_tier', 'bronze')

        # Генерация кандидатов
        candidates = []

        # Категорийные бонусы
        for category in top_categories[:2]:
            multiplier = 2.0 if tier == 'bronze' else 1.5
            candidates.append(LoyaltyOffer(
                user_id=user['user_id'],
                offer_type='double_points',
                category=category,
                multiplier=multiplier,
                min_purchase=None,
                valid_hours=None,
                valid_days=None,
                description=f"×{multiplier} баллов в категории {category}",
                expected_lift=0.0
            ))

        # Пороговый бонус
        threshold = round(avg_basket * 1.3 / 100) * 100
        candidates.append(LoyaltyOffer(
            user_id=user['user_id'],
            offer_type='threshold_bonus',
            category=None,
            multiplier=1.5,
            min_purchase=threshold,
            valid_hours=None,
            valid_days=['Mon', 'Tue', 'Wed', 'Thu'],
            description=f"+{int((threshold * 1.5 - threshold) * 0.01)} баллов за покупку от {threshold}₽",
            expected_lift=0.0
        ))

        # Временной бонус
        if preferred_hours:
            peak_hour = max(set(preferred_hours), key=preferred_hours.count)
            candidates.append(LoyaltyOffer(
                user_id=user['user_id'],
                offer_type='time_bonus',
                category=None,
                multiplier=2.0,
                min_purchase=None,
                valid_hours=(peak_hour, peak_hour + 2),
                valid_days=None,
                description=f"×2 баллов с {peak_hour}:00 до {peak_hour+2}:00",
                expected_lift=0.0
            ))

        # Streak reward
        current_streak = user.get('consecutive_weeks_with_purchase', 0)
        if current_streak >= 2:
            candidates.append(LoyaltyOffer(
                user_id=user['user_id'],
                offer_type='streak_reward',
                category=None,
                multiplier=3.0,
                min_purchase=None,
                valid_hours=None,
                valid_days=None,
                description=f"Поддерживайте серию! ×3 баллов за {current_streak+1}-ю неделю подряд",
                expected_lift=0.0
            ))

        # Скоринг и выбор лучших
        if self.engagement_model:
            scored = self._score_candidates(candidates, user)
            return scored[:n_offers]

        return candidates[:n_offers]

    def _score_candidates(self, candidates: list[LoyaltyOffer],
                           user: dict) -> list[LoyaltyOffer]:
        """Скоринг кандидатов через ML-модель"""
        features_list = []
        for offer in candidates:
            user_cats = user.get('top_categories', [])
            category_match = 1.0 if offer.category in user_cats else 0.3

            features_list.append([
                offer.multiplier,
                int(offer.category is not None),
                int(offer.valid_hours is not None),
                user.get('avg_order_value', 500),
                user.get('purchase_frequency_monthly', 2),
                category_match
            ])

        probs = self.engagement_model.predict_proba(features_list)[:, 1]

        for offer, prob in zip(candidates, probs):
            offer.expected_lift = float(prob)

        return sorted(candidates, key=lambda x: x.expected_lift, reverse=True)

    def generate_offer_message(self, offer: LoyaltyOffer, user: dict) -> str:
        """AI-генерация описания предложения"""
        response = self.llm.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=80,
            messages=[{
                "role": "user",
                "content": f"""Write a brief, exciting loyalty offer message (1 sentence, emoji allowed).

Offer: {offer.description}
User name: {user.get('first_name', '')}
Loyalty tier: {user.get('loyalty_tier', 'bronze')}
User's favorite: {user.get('top_categories', [''])[0] if user.get('top_categories') else 'shopping'}"""
            }]
        )
        return response.content[0].text

Геймификация программы лояльности

class LoyaltyGamification:
    """Игровые механики для повышения вовлечённости"""

    def get_user_progress(self, user: dict) -> dict:
        """Текущий прогресс и следующие достижения"""
        current_points = user.get('points_balance', 0)
        current_tier = user.get('loyalty_tier', 'bronze')

        tier_thresholds = {
            'bronze': 0, 'silver': 1000, 'gold': 5000, 'platinum': 20000
        }

        # Следующий уровень
        tiers = list(tier_thresholds.items())
        current_idx = next(i for i, (t, _) in enumerate(tiers) if t == current_tier)
        next_tier = tiers[current_idx + 1] if current_idx + 1 < len(tiers) else None

        progress = {
            'current_tier': current_tier,
            'current_points': current_points,
            'streak_weeks': user.get('consecutive_weeks_with_purchase', 0),
            'achievements': user.get('achievements', [])
        }

        if next_tier:
            points_needed = next_tier[1] - current_points
            progress['next_tier'] = next_tier[0]
            progress['points_to_next_tier'] = max(0, points_needed)
            progress['progress_pct'] = min(100, (current_points - tier_thresholds[current_tier]) /
                                           (next_tier[1] - tier_thresholds[current_tier]) * 100)

        return progress

Персонализированные программы лояльности показывают: +40-60% к redemption rate баллов, +25-35% к частоте покупок у участников, NPS loyalty program members на 15-20 пунктов выше среднего. Ключевые метрики для оптимизации: redemption rate (целевой >40%), active member rate (>60% за 90 дней), points liability (следить за стоимостью начисленных баллов).