Если вы слышите «AB‑тесты» и у вас в голове возникает что‑то вроде «да, я это где‑то видел, но понятия не имею, как работает», то эта статья — для вас. Я объясню, что такое AB‑тесты, зачем они нужны, какие инструменты использовать и как их настроить, чтобы результат был не просто для галочки, а действительно полезным.


Что такое AB-тест?

Начнём с самого простого: AB‑тест — это способ сравнить два (или больше) варианта чего‑либо (страницы, кнопки, дизайна) и понять, какой из них лучше работает для пользователей. Это как спросить у кота: «Ты хочешь валерьянку или кусочек мяса?» и наблюдать за его реакцией. Только в нашем случае «кот» — это пользователи.

К примеру, в магазине для котиков мы хотим узнать, какой дизайн карточки товара увеличит количество покупок. Мы делаем два варианта:

  • Вариант A — текущий, привычный.

  • Вариант B — новый, экспериментальный.

Без AB‑тестов вы принимаете решения на основе догадок. Это примерно как поменять дизайн сайта, потому что «так круче смотрится». В бренном мире может оказаться, что пользователи путаются в новом интерфейсе, и вы теряете продажи.

AB‑тесты помогают:

  • Повысить конверсию: узнать, какой вариант приводит больше пользователей к целевому действию (например, покупке).

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

  • Принимать решения на основе данных: никаких «мне кажется». Только числа.

Этапы AB-теста

Определение цели

Перед началом AB‑теста важно чётко сформулировать цель. Без ясной цели эксперимент превратится в бессмысленную трату времени.

Варианты целей:

  1. Увеличение кликов (CTR, Click‑Through Rate):
    Хотим, чтобы больше пользователей нажимали, к примеру, кнопку Купить.

  2. Увеличение конверсии (CR, Conversion Rate):

  3. Увеличение среднего чека (AOV, Average Order Value):
    Чтобы пользователи покупали больше товаров за один раз.

  4. Снижение отказов (Bounce Rate)

  5. Повышение удержания (Retention Rate)

Пример цели:

«Мы хотим увеличить конверсию на 10% за счёт изменения текста на кнопке с 'Купить' на 'Добавить в корзину'».

Создание вариантов

После постановки цели приступаем к созданию разных версий тестируемого элемента. Это может быть дизайн страницы, текст кнопки, расположение блока и т. д.

Что можно тестировать?

  1. Копирайтинг:
    Например, меняем текст на кнопке:

    • Вариант A: «Купить»

    • Вариант B: «Добавить в корзину»

  2. Дизайн:
    Изменяем цвет кнопки, шрифт, или макет страницы:

    • Вариант A: кнопка синяя.

    • Вариант B: кнопка зелёная.

  3. Функционал:
    Например, добавляем новую функцию:

    • Вариант A: обычный просмотр товаров.

    • Вариант B: просмотр с быстрым добавлением в корзину.

P.S:если вы измените текст, цвет кнопки и дизайн сразу, то не поймёте, что дало результат. Изменения должны быть заметными, но не слишком радикальными.

Распределение трафика

После создания вариантов нужно настроить распределение пользователей между ними.

Как распределять?

  1. Равномерное распределение (50/50):
    Идеальный вариант для большинства тестов: половина пользователей видит вариант A, половина — вариант B.

  2. Нерегулярное распределение (например, 90/10):
    Если хочется протестировать радикально новый вариант на небольшом сегменте перед массовым запуском.

  3. Сегментированное распределение:
    Можно разбить пользователей по группам (например, мобильные и десктопные) и тестировать варианты только внутри одной группы.

P.S: учитывайте источники трафика: пользователи из соцсетей и поисковиков могут вести себя по‑разному.

Сбор данных

Без качественного сбора данных тест превращается в гадание. Важно собирать только те данные, которые действительно нужны для анализа.

Что логировать?

  1. ID пользователя: чтобы отслеживать действия конкретного пользователя.

  2. Группа (A или B): для сравнения поведения в разных версиях.

  3. Событие: тип действия (например, «клик», «покупка», «посещение страницы»).

  4. Время события: чтобы понимать, как быстро пользователи совершают действия.

  5. Доп. данные: устройство, источник трафика, версия браузера.

Анализ результатов

Когда данные собраны, начинается самое интересное: анализ. Именно здесь вы решаете, какой вариант работает лучше.

Какие метрики анализировать?

  1. Click-Through Rate (CTR):
    Доля пользователей, кликнувших по кнопке.
    Формула:
     CTR = \frac{\text{Клики}}{\text{Просмотры}} \times 100% ]=

  2. Conversion Rate (CR):
    Доля пользователей, которые совершили покупку.
    Формула:

     CR = \frac{\text{Покупки}}{\text{Уникальные пользователи}} \times 100%

  3. Средний чек (AOV):
    Средняя стоимость заказа.
    Формула:

     AOV = \frac{\text{Сумма заказов}}{\text{Количество заказов}}

  4. Retention Rate:
    Доля пользователей, которые вернулись на сайт через определённый период.

  5. Bounce Rate:
    Доля пользователей, которые покинули сайт, не совершив ни одного действия.

Для проверки, является ли разница между вариантами статистически значимой, используют:

Chi‑Square Test. Используется, когда нужно проверить, отличаются ли результаты двух групп по каким‑либо категориальным данным. Этот инструмент больше про конверсию или процент кликов, где мы анализируем количество успешных событий относительно общего числа пользователей. Суть теста в том, чтобы сравнить фактические результаты с ожидаемыми, если бы различий между вариантами не было. Например, если в группе A 150 из 1000 пользователей совершили покупку, а в группе B — 200 из 1000, тест поможет определить, является ли эта разница случайной или она статистически значима.

T‑Test (t‑тест Стьюдента) используется, если вы работаете с непрерывными метриками, такими как средний чек или время на сайте. Этот тест сравнивает средние значения двух групп (A и B) и проверяет, есть ли статистически значимые различия между ними. Например, если средний чек в группе A составляет $50, а в группе B — $55, t‑тест поможет понять, вызвана ли эта разница статистически значимыми факторами или является результатом случайности.

Принятие решения

Когда анализ завершён, пора принять решение: какой вариант оставить. Возможные сценарии:

  1. A выиграл:
    Оставляем текущий вариант и не внедряем изменения.

  2. B выиграл:
    Новый вариант работает лучше, внедряем изменения.

  3. Различия незначимы:
    Возможно, нужно увеличить выборку или вернуться к гипотезе и пересмотреть, что вы тестируете.

Пример реализации A/B теста

Магазин котиков продаёт домики. Текущая конверсия, ну, скажем, 5%. Это значит, что из 100 хвостатых (ну ладно, их хозяев) только 5 решаются купить домик. Мы хотим увеличить этот показатель.

Если мы добавим на карточку товара большой баннер «Котики рекомендуют!» с милым мурлыкой, то покупки возрастут. Логично? Логично. Но сначала это нужно доказать.

Разделим пользователей на группы

Наша задача — разделить пушистых покупателей (ну, их людей) на две группы:

  • Группа A: видит текущий дизайн страницы.

  • Группа B: получает экспериментальный дизайн.

Главное тут — честность. Никакого «перекидывания» пользователей между вариантами. Поэтому будем использовать трюк с хэшированием.

import hashlib

def assign_user_to_variant(user_id, variants=("A", "B")):
    """Назначаем пользователя в одну из групп. 
    User_id всегда будет приводить к одному и тому же варианту."""
    hashed_id = int(hashlib.md5(str(user_id).encode()).hexdigest(), 16)
    return variants[hashed_id % len(variants)]

# Пример:
print(assign_user_to_variant("user_12345"))  # Вернёт A или B
print(assign_user_to_variant("user_54321"))  # Другой пользователь

Пользователи всегда будут в одной и той же группе.

Логируем действия пользователей

Кто‑то должен собирать данные о том, как котики (и их люди) ведут себя на сайте. Лучше будем отправлять данные на сервер, а он пусть уже разбирается, что с этим делать.

Простой сервер на Flask:

from flask import Flask, request, jsonify
import json
import os

app = Flask(__name__)

LOG_FILE = "events.log"

@app.route('/log', methods=['POST'])
def log_event():
    """Логируем событие пользователя."""
    data = request.json
    required_fields = {"user_id", "variant", "event", "timestamp"}
    
    # Проверяем, что нам передали всё, что нужно
    if not required_fields.issubset(data):
        return jsonify({"error": "Данные некорректны!"}), 400

    # Записываем событие в лог-файл
    with open(LOG_FILE, "a") as f:
        f.write(json.dumps(data) + "\n")
    
    return jsonify({"status": "ok"}), 200

if __name__ == "__main__":
    if not os.path.exists(LOG_FILE):
        open(LOG_FILE, "w").close()
    app.run(debug=True)

И вот так выглядит код на клиенте, который будет отправлять события на сервер:

function logEvent(userId, variant, event) {
    fetch('/log', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            user_id: userId,
            variant: variant,
            event: event,
            timestamp: new Date().toISOString(),
        }),
    }).catch((err) => console.error('Ошибка логирования:', err));
}

// Логируем событие "Добавил в корзину"
logEvent('user_12345', 'A', 'add_to_cart');

События: page_view, add_to_cart, purchase — всё, что нужно для анализа.

Анализ данных

Наконец, данные собраны, и мы готовы выяснить, стоит ли внедрять новый дизайн. Вот что будем делать:

  • Сравним конверсии для двух вариантов.

  • Используем Chi-Square Test, чтобы проверить значимость разницы.

Пример данных в events.log:

{"user_id": "user_12345", "variant": "A", "event": "page_view", "timestamp": "2024-11-18T10:00:00"}
{"user_id": "user_54321", "variant": "B", "event": "add_to_cart", "timestamp": "2024-11-18T10:05:00"}
{"user_id": "user_67890", "variant": "A", "event": "purchase", "timestamp": "2024-11-18T10:10:00"}

Теперь пишем скрипт анализа:

import pandas as pd
from scipy.stats import chi2_contingency

# Загружаем данные
data = pd.read_json('events.log', lines=True)

# Считаем общее количество пользователей в каждой группе
total_users = data.groupby('variant')['user_id'].nunique()

# Считаем количество покупок
purchases = data[data['event'] == 'purchase'].groupby('variant')['user_id'].nunique()

# Вычисляем конверсию
conversion_rate = (purchases / total_users).fillna(0)
print("Conversion Rate:\n", conversion_rate)

# Chi-Square Test для проверки значимости
table = [
    [purchases.get('A', 0), purchases.get('B', 0)],
    [total_users['A'] - purchases.get('A', 0), total_users['B'] - purchases.get('B', 0)]
]
chi2, p, _, _ = chi2_contingency(table)

print(f"p-value: {p}")
if p < 0.05:
    print("Различия значимы! Побеждает дизайн с котиками!")
else:
    print("Различий не обнаружено. Котики не помогли ?.")

Принятие решения

Если тест показывает, что вариант B увеличил конверсию с 5% до 7%, то мы смело внедряем его на всех пользователей. Если разница незначима, то оставляем старый дизайн.


Заключение

Итак, A/B‑тесты помогают принимать решения на основе данных, а не интуиции. Но чтобы они работали, нужно придерживаться нескольких простых, но важных правил.

Во‑первых, всегда чётко формулируйте цель. Задачи вроде «посмотрим, что получится» не подойдут. Укажите конкретный показатель, который хотите улучшить (например, конверсию или средний чек).

Во‑вторых, тестируйте по одному элементу за раз. Если вы измените сразу текст, дизайн и расположение кнопки, то никогда не узнаете, что именно сработало.

Кроме того, рассчитывайте размер выборки заранее и не завершайте тест раньше времени. Для этого можно использовать калькуляторы вроде ABTestGuide. Маленькая выборка или подглядывание в данные до завершения теста могут исказить результаты и привести к неверным выводам. Установите чёткий срок или число пользователей, а затем проводите анализ.

Также не забываем документировать гипотезы, шаги и результаты. Хороший тест — это не только про текущие изменения, но и про знания, которые останутся для будущих экспериментов.

Кстати, если вы хотите упростить расчёт необходимой выборки для A/B‑теста, рекомендую воспользоваться калькулятором ABTestGuide.

Больше про актуальные инструменты и методы аналитики данных можно узнать на практических онлайн-курсах: в каталоге можно посмотреть список всех программ.

А еще сегодня, 21 ноября, в 20:00 пройдет открытый урок на тему инструментов для выгрузки данных. Записаться можно на странице курса "Data Engineer".

Комментарии (0)