AI Audience Targeting System Based on ML

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
AI Audience Targeting System Based on ML
Medium
~2-4 weeks
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1317
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1226
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    925
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1156
  • image_logo-advance_0.webp
    B2B Advance company logo design
    620
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    894

AI Audience Targeting with Machine Learning

We build machine learning systems for ad audience targeting. Our models replace broad demographic segments with precise conversion probability scores. Instead of targeting all women aged 25–34, you reach users with a 73%+ likelihood of converting within 7 days. The efficiency gain is 3–5x with the same budget. We work exclusively with first-party behavioral data. Third-party cookies are disappearing. First-party signals remain available and are more accurate. In a typical e-commerce project we deliver, CTR grows from 0.08% to 0.4%. Cost per lead drops by 40%. Our stack combines LightGBM for propensity scoring, MiniBatchKMeans for behavioral segmentation, and BERT-based classifiers for contextual targeting. The approach is GDPR-compliant. Data stays on your infrastructure. We provide full-cycle delivery: data audit, feature engineering, model training, DSP integration, and A/B test validation. Contact us to estimate your targeting project — we will scope it within 2 business days.

Problems We Solve

Blind demographic targeting misses intent. A 35-year-old user may be shopping for a child's gift, not for themselves. Our ML model evaluates behavioral signals: product view frequency, cart additions, time between sessions. Prediction accuracy for conversion exceeds 85%.

Oversized audiences dilute budget. Lookalike models built from 50+ seed users expand the audience while maintaining concentration of high-intent leads. We use a calibrated LightGBM classifier instead of simple kNN. This yields a 0.08–0.12 improvement in ROC-AUC.

Loss of context after retargeting wastes spend. When a user just read a technology article and sees a credit card ad, there is a context gap. Our contextual engine analyzes URL and page text. It identifies the IAB category (e.g., IAB19 — technology) and matches creative to context. This works without user-level data and is GDPR-compliant.

How the ML Propensity Model Works

Feature quality is the foundation. We use raw events: product_view, add_to_cart, checkout_start, search. We compute recency (hours since last event), session frequency, funnel depth (weighted action count), and activity trend (last 7 days vs. previous 7 days). These features feed into a calibrated LightGBM classifier. Each user receives a purchase_probability score. Users are sorted into tiers: cold (under 10%), warm (10–30%), hot (30–60%), ready_to_buy (above 60%).

import pandas as pd
import numpy as np
import lightgbm as lgb
from sklearn.cluster import MiniBatchKMeans
from sklearn.preprocessing import LabelEncoder

class PredictiveAudienceBuilder:
    """Создание аудиторий на основе вероятностей конверсии"""

    def build_intent_features(self, user_events: pd.DataFrame) -> pd.DataFrame:
        """
        Признаки намерения из событий пользователя.
        user_events: user_id, event_type, page_url, timestamp, session_id
        """
        df = user_events.copy()
        df['ts'] = pd.to_datetime(df['timestamp'])

        # Рекентность последней активности
        now = df['ts'].max()
        recency = df.groupby('user_id')['ts'].max().apply(
            lambda t: (now - t).total_seconds() / 3600
        ).rename('hours_since_last_event')

        # Поведенческие признаки
        behavior = df.groupby('user_id').agg(
            total_sessions=('session_id', 'nunique'),
            total_events=('event_type', 'count'),
            product_views=('event_type', lambda x: (x == 'product_view').sum()),
            cart_adds=('event_type', lambda x: (x == 'add_to_cart').sum()),
            checkout_starts=('event_type', lambda x: (x == 'checkout_start').sum()),
            search_queries=('event_type', lambda x: (x == 'search').sum()),
        )

        # Конверсионная воронка (нормализованная)
        behavior['funnel_depth'] = (
            behavior['product_views'] * 1 +
            behavior['cart_adds'] * 3 +
            behavior['checkout_starts'] * 7
        ) / behavior['total_sessions'].clip(1)

        # Сессионная активность: тренд последних 7 дней vs предыдущие 7
        last_7d = df[df['ts'] >= now - pd.Timedelta(days=7)]
        prev_7d = df[df['ts'].between(now - pd.Timedelta(days=14), now - pd.Timedelta(days=7))]

        activity_last = last_7d.groupby('user_id')['event_type'].count().rename('events_last_7d')
        activity_prev = prev_7d.groupby('user_id')['event_type'].count().rename('events_prev_7d')

        result = behavior.join(recency).join(activity_last).join(activity_prev).fillna(0)
        result['activity_trend'] = (
            result['events_last_7d'] - result['events_prev_7d']
        ) / (result['events_prev_7d'] + 1)

        return result

    def score_purchase_propensity(self, features: pd.DataFrame,
                                    model: lgb.LGBMClassifier) -> pd.DataFrame:
        """Оценка вероятности покупки для каждого пользователя"""
        scores = model.predict_proba(features)[:, 1]

        result = pd.DataFrame({
            'user_id': features.index,
            'purchase_probability': scores,
            'audience_tier': pd.cut(
                scores,
                bins=[0, 0.1, 0.3, 0.6, 1.0],
                labels=['cold', 'warm', 'hot', 'ready_to_buy']
            )
        })

        return result.sort_values('purchase_probability', ascending=False)


class BehavioralClusteringAudience:
    """Поведенческая сегментация без supervision"""

    def segment_by_behavior(self, user_features: pd.DataFrame,
                              n_clusters: int = 8) -> pd.DataFrame:
        """
        K-Means кластеризация для выявления скрытых аудиторных сегментов.
        """
        from sklearn.preprocessing import StandardScaler

        feature_cols = user_features.select_dtypes(include=[np.number]).columns
        X = user_features[feature_cols].fillna(0)

        scaler = StandardScaler()
        X_scaled = scaler.fit_transform(X)

        kmeans = MiniBatchKMeans(n_clusters=n_clusters, random_state=42, n_init=10)
        clusters = kmeans.fit_predict(X_scaled)

        user_features = user_features.copy()
        user_features['cluster'] = clusters

        # Профили кластеров
        profiles = user_features.groupby('cluster')[feature_cols].mean()

        return user_features, profiles

    def label_clusters(self, cluster_profiles: pd.DataFrame) -> dict:
        """Автоматическая маркировка кластеров по профилям"""
        labels = {}
        for cluster_id, row in cluster_profiles.iterrows():
            # Упрощённая эвристическая маркировка
            if row.get('checkout_starts', 0) > 2:
                label = 'high_intent_buyers'
            elif row.get('product_views', 0) > 10 and row.get('cart_adds', 0) == 0:
                label = 'browsers_not_buyers'
            elif row.get('total_sessions', 0) > 20:
                label = 'loyal_visitors'
            elif row.get('hours_since_last_event', 9999) > 720:
                label = 'dormant_users'
            else:
                label = f'segment_{cluster_id}'
            labels[cluster_id] = label
        return labels

Contextual Targeting without Cookies

class ContextualTargetingEngine:
    """ML-таргетинг на основе контента страницы (cookieless)"""

    def classify_page_context(self, page_text: str,
                               page_url: str) -> dict:
        """
        IAB категоризация страницы для контекстуального таргетинга.
        Работает без user-level data (GDPR-compliant).
        """
        # Ключевые сигналы контекста
        url_signals = self._extract_url_signals(page_url)

        # В production: BERT-based classifier, обученный на IAB taxonomy
        # Здесь упрощённая keyword-based версия
        iab_keywords = {
            'IAB19': ['technology', 'software', 'programming', 'tech'],
            'IAB13': ['finance', 'investment', 'stock', 'crypto', 'money'],
            'IAB7': ['health', 'fitness', 'medical', 'diet'],
            'IAB9': ['hobby', 'crafts', 'games', 'gaming'],
        }

        text_lower = page_text.lower()
        scores = {}
        for iab_cat, keywords in iab_keywords.items():
            score = sum(text_lower.count(kw) for kw in keywords)
            if score > 0:
                scores[iab_cat] = score

        if not scores:
            return {'categories': ['IAB24'], 'confidence': 0.5}

        primary_cat = max(scores, key=scores.get)
        total = sum(scores.values())

        return {
            'primary_category': primary_cat,
            'all_categories': list(scores.keys()),
            'confidence': round(scores[primary_cat] / total, 2),
            'url_signals': url_signals,
        }

    def _extract_url_signals(self, url: str) -> list:
        signals = []
        if '/news/' in url or '/article/' in url:
            signals.append('editorial_content')
        if '/product/' in url or '/shop/' in url:
            signals.append('ecommerce')
        if '/blog/' in url:
            signals.append('blog_content')
        return signals

Comparison of Targeting Methods

Method CPM CTR Conversion Privacy
Demographics (age/gender) low 0.05–0.1% low safe
Behavioral (3rd party cookies) high 0.2–0.5% medium limited
Predictive (ML propensity) medium 0.3–0.8% high 1st party
Lookalike ML medium 0.2–0.6% medium 1st party
Contextual (cookieless) medium 0.1–0.3% medium safe

Predictive targeting on first-party data is the most robust option in a world without third-party cookies. It requires quality event data — at least 50,000 users with conversion history — to train a propensity model with acceptable AUC above 0.72. Demographic targeting is a legacy approach. CTR stays at 0.05–0.1%. Predictive ML on first-party data delivers CTR of 0.3–0.8%. It also eliminates dependency on regulatory risk. In the long term, first-party is the only sustainable strategy.

Implementation Steps

  1. Data audit: assess tracking quality in Google Tag Manager, Amplitude, or your own pipeline.
  2. Feature engineering: Python and Pandas scripts for activity, funnel depth, and trend features.
  3. Model training: LightGBM classifier with probability calibration and time-series cross-validation.
  4. Clustering: MiniBatchKMeans for identifying dormant, warm, and high-intent segments.
  5. Contextual engine: BERT-based NLP module for IAB page classification across up to 30 categories.
  6. DSP integration: API to push segments to Facebook Ads, Google Ads, or a self-serve platform.
  7. A/B test: 2-week run against baseline targeting with ROAS improvement target of 25%+ included in scope.

Timeline: 4 to 6 weeks to a working MVP. We validate results against agreed metrics before handoff.