Как мы можем измерить новую добавленную стоимость продукта компании, которая на самом деле связана с внесенными нами изменениями? Этим изменением может быть увеличение размера кнопки «Купить» на веб-сайте или замена фотографии товара на сайте. Все эти изменения произвольны. Некоторые люди будут утверждать, что эти изменения принесут прибыль нашему продукту, потому что клиенты почувствуют себя освеженными с новым внешним видом и купят наш продукт. Некоторые люди будут утверждать, что эти изменения принесут убытки нашему продукту, потому что клиенты не смогут адаптироваться к новому внешнему виду и перестанут покупать продукт у нас. Поэтому нам нужен механизм для определения влияния изменения. Если изменение принесло положительный эффект, мы все им довольны; Однако, если изменение оказало негативное влияние, нам необходимо быстро отменить изменение и провести дополнительный анализ. Это очень важно, потому что негативное влияние может привести к потере денег, увеличению количества зарегистрированных жалоб и снижению удовлетворенности клиентов.

Решение этой проблемы заключается в настройке теста AB для внесенных нами изменений. «A» в термине теста AB означает текущую реализацию (до изменения), а «B» в термине теста AB означает новая реализация (после изменения). По сути, мы сравниваем значение до и после изменения. К настоящему времени мы знаем значение и цель теста AB. Следующим шагом будет внедрение теста AB. Чтобы реализовать тест AB, нужно выполнить несколько шагов. Не волнуйтесь, мы пройдем эти шаги один за другим с кратким объяснением.

  • Определите метрику оценки для A/B-теста.
  • Определите коэффициент разделения/распределения группы AB.
  • Проведите анализ AA, чтобы убедиться, что разделение/распределение справедливо.
  • Рассчитайте достоверность теста AB, используя z-score/p-val.

Определить показатель оценки для теста AB

Для этого шага нам нужно определить соответствующую метрику, связанную с нашим изменением. Обычно этот показатель связан с ценностью бизнеса. Например, на платформе бронирования отелей/проживаний в семье номер бронирования можно использовать в качестве метрики оценки. Для платформы по продаже недвижимости количество кликов может быть показателем оценки. Большую часть времени владелец продукта будет работать вместе с командой, чтобы определить метрику оценки. Для иллюстрации давайте возьмем номер бронирования в качестве нашей оценочной метрики.

Определите коэффициент разделения/распределения трафика AB

Для этого шага нам нужно предложить способ разделения клиентов на 2 группы. 1 группа будет выделена стороне A (текущая реализация), 1 группа будет выделена стороне B (новая реализация за счет увеличения размера кнопки). Есть несколько способов разделить клиентов на группу A и группу B. Мы можем использовать идентификатор клиента для разделения. Клиенты с нечетным идентификатором будут отнесены к группе A, а клиенты с четным идентификатором будут отнесены к группе B. Затем мы получим разницу в бронировании между группой A (клиенты с нечетным идентификатором) и группой B (клиенты с четным идентификатором) для расчета дополнительная ценность, внесенная Группой B. Однако у некоторых клиентов может не быть идентификатора клиента, поскольку они не зарегистрированы в качестве участника платформы. В этом случае мы можем использовать распределение по времени. При распределении по времени мы могли бы распределить клиентов, которые сделали Бронирование на нашем веб-сайте в НЕЧЕТНОЕ время, как группу A, а клиентов, которые сделали Бронирование на нашем веб-сайте в ЧЕТНОЕ время, как группу B. Кроме того, мы могли бы дополнительно сделать наше непредвзятое распределение, распределяя бронирования на (НЕЧЕТНЫЕ дни, НЕЧЕТНЫЕ часы), (ЧЕТНЫЕ дни, ЧЕТНЫЕ часы) в группу A и (НЕЧЕТНЫЕ дни, ЧЕТНЫЕ часы), (ЧЕТНЫЕ дни, НЕЧЕТНЫЕ часы) к группе B, как показано в таблице ниже.

Проведите анализ AA, чтобы доказать справедливость разделения/распределения.

Как упоминалось ранее, мы должны убедиться, что наше распределение является беспристрастным/справедливым при использовании распределения на основе времени. Мы могли бы добиться этого, проведя анализ АА. В анализе AA мы разделим бронирования на 2 группы. Две группы будут использовать текущую реализацию, если на веб-сайте не будет реализовано никаких изменений. Обозначим Бронирования на (НЕЧЕТНЫЕ дни, НЕЧЕТНЫЕ часы), (ЧЕТНЫЕ дни, ЧЕТНЫЕ часы) как A1, а Бронирования на (НЕЧЕТНЫЕ дни, ЧЕТНЫЕ часы), (ЧЕТНЫЕ дни, НЕЧЕТНЫЕ часы) как A2. Наши ожидания относительно бронирований, сделанных на A1 и A2, должны быть примерно одинаковыми. Или разница в бронировании между A1 и A2 должна быть приблизительно равна 0.

В принципе, мы можем убедиться в этом, используя историю Bookings. Приведенные ниже коды можно использовать для расчета разницы в бронировании (BD) и стандартного отклонения (STD) с использованием данных за 1 год. Поскольку мы рассчитываем разницу в бронировании за 28 дней, данные за 1 год могут дать нам 12 точек данных из 12 тестов АА. Например, BD1, показанный на диаграмме ниже, представляет точку данных 1. Эти данные получены из разницы суммы A1 и суммы A2 (сумма A1 — сумма A2) за 28 дней (4 недели).

Основываясь на 12 точках данных, у нас есть среднее значение и стандартное отклонение различий в бронировании, равное 18 и 138 соответственно. Как мы упоминали ранее, мы хотим, чтобы среднее значение разницы в бронировании было близко к 0, и в результате мы получаем 18. В нашем случае мы можем утверждать, что 18 очень близко к 0, поскольку разница в 18 бронирований получается из среднего значения разностей бронирований A1, которые близки к 50 000 бронирований, и бронирований A2, которые также близки к 50 000 бронирований.

Мы выбрали 28 дней, потому что это продолжительность 1 цикла теста АВ. мы могли бы выбрать другую продолжительность для 1 цикла теста AB. Однако чем короче продолжительность, тем выше стандартное отклонение. И чем выше стандартное отклонение, тем труднее нам заявить, что сторона Б побеждает (отклонить нулевую гипотезу). Мы можем доказать это с помощью статистики, и это будет объяснено в части 4.

import os
import pandas as pd
import numpy as np

booking_path = r"hourly_scale_bookings.csv"

booking_content = pd.read_csv(booking_path)
# the content is in this format 
#   index  datadate  hour  bookings
#   3254  20220302     0      94.0
#   3336  20220302     1      79.0
#    825  20220302     2      73.0
#    566  20220302     3      73.0
#   5850  20220302     4      69.0

booking_content_sort = booking_content.sort_values(by=['datadate','hour'])
booking_content_sort = booking_content_sort.reset_index()

print(booking_content_sort.head())
print(booking_content_sort.dtypes)


def calculate_std(bookings, time_interval, exp_time):
    '''
    time_interval : how many hour we do flip
    exp_time for how long we do the experiment
    '''
    day = 0
    bookings_diff = []
    AB_bookings = []
    a_sum = 0
    b_sum = 0
    off_site = 0
    a_hour = 0
    b_hour = 0
    for index, row in bookings.iterrows():
        hour = int(row["hour"])
        booking_counts = int(row["bookings"])
        if (int(hour / time_interval) + off_site) % 2 == 0:  # time_interval = flipping hours
            b_sum += booking_counts
            b_hour += 1
        else:
            a_sum += booking_counts
            a_hour += 1
        if hour == 23:
            day += 1
            off_site = (off_site + 1) % 2
            if day == exp_time:
                day = 0
                bookings_diff.append(b_sum - a_sum)
                AB_bookings.append([b_sum, a_sum])
                b_sum = 0
                a_sum = 0
    bookings_diff = np.array(bookings_diff)
    std = np.std(bookings_diff)
    return bookings_diff.mean(), std, bookings_diff, AB_bookings

mean, std, bookings_diff, AB_bookings = calculate_std(booking_content_sort,1,28)
print('mean:',mean,'std:',std)


# calculate z-score
# z = (x - mean) / std
z = (501 - mean) / std
print(z, mean, std)

# calculate p_value, right tail test
p_value = 1.0-stat.norm(0,1).cdf(z)
print(p_value)

Рассчитайте достоверность теста AB, используя z-score/p-val.

К настоящему времени мы убедились, что распределение на основе времени является несмещенным. Далее мы проведем этот AB-тест на 4 недели. Освежим нашу память. В течение (нечетный день, нечетный час) и (ЧЕТНЫЙ день, четный час) мы будем использовать текущий размер кнопки. В течение (НЕЧЕТНЫЙ день, ЧЕТНЫЙ час) и (ЧЕТНЫЙ день, НЕЧЕТНЫЙ час) мы будем использовать кнопку «БОЛЬШОЙ» размер. Чтобы определить, приносит ли изменение на стороне B (увеличение размера кнопки) значительную дополнительную ценность платформе бронирования, нам нужно увидеть значительное увеличение числа бронирований на стороне B. Предполагая, что у нас есть дополнительные 500 бронирований после 28-дневного пробега после A/B-тестирования.

Здесь нам нужно понять несколько статистических терминов, таких как среднее значение, стандартное отклонение и нулевая гипотеза.

среднее: среднее количество бронирований по 12 точкам данных.
стандартное отклонение : определите разреженность 12 точек данных. Одно стандартное отклонение означает, что у нас есть 68% из 12 точек данных, то есть 8 точек данных попадают в диапазон (18–138, 18+138).
null-hypothesis : изменение на стороне B (большой размер кнопки) работает так же, как и на стороне A (без изменений).

Чтобы мы могли сказать, что изменение B значительно увеличивает ценность нашего продукта, нам нужно отвергнуть нулевую гипотезу, рассчитав z-значение и выполнив правосторонний тест, чтобы получить p-значение. Мы начнем с объяснения z-оценки.

Концепция z-показателя проста для понимания. Поскольку среднее значение близко к 0, мы просто делим новое значение на стандартное отклонение. Это покажет нам, насколько новые данные (дополнительное бронирование с кнопки «Большой») отличаются от наших исторических данных. Из нашего примера мы видим, что новые данные в 3,49 раза отличаются от наших исторических данных. Это показывает, что изменения на стороне B очень значительны. Однако мы хотим донести эту информацию до нетехнических людей. Они могут не знать значения стандартного отклонения и z-показателя. Поэтому нам нужно преобразовать z-оценку в p-значение. Формула для преобразования z-оценки в p-val показана в кодах. По сути, p-значение даст нам уверенность в наших изменениях. В нашем случае p-val = 0,00023. Это означает, что у нас есть шанс 0,023%, что изменение размера кнопки не скажет нам об увеличении дополнительных бронирований. С другой стороны, мы могли бы сказать нетехническим специалистам, что мы на 99,977 % уверены, что изменение размера кнопки принесет нам дополнительные бронирования.

Мы прошли 4 шага, чтобы создать беспристрастную платформу для экспериментов. Надеюсь, что это объяснение будет полезным, и поставьте нам лайк, если этот блог принесет вам пользу. Далее мы применим этот A/B-тест в обучении с подкреплением для постоянного совершенствования. Надеюсь, что мы сможем пройти через это вместе, это наш следующий блог. Увидимся там!