Как разделить “сплитануть” пользователей(user_id) на группы для А/Б теста.
В данной статье я бы хотел показать как можно разделить правильно пользователей на группы для проведения А/Б теста и получить…
Как разделить “сплитануть” пользователей(user_id) на группы для А/Б теста.
В данной статье я бы хотел показать как можно разделить правильно пользователей на группы для проведения А/Б теста и получить репрезентативную выборку для сравнения. Не буду разбрасываться теорией сразу перейду к примерам, чтобы вы могли взять и использовать.
Сплит с помощью SQL:
SELECT conv(substr(md5(concat(USER_ID, 'gywrnbf132')), 1, 12), 16, 10)%6 as bucket
Где gywrnbf132 — это соль которую можно менять. При изменении может меняться группа в которую попадёт пользователь. Если вы в дальнейшем хотите воспроизвести точно такую же выборку, то просто используете старую соль и настройки.
%6 это количество бакетов которые мы хотим получить на выходе. Их можно также обьеденить в группы:
(CASE WHEN bucket in (1,2) then 'A'
WHEN bucket in (3,4) then 'B'
WHEN bucket in (5,6) then 'C'
ELSE null END)
Сплит с помощью Python:
import hashlib
import pandas as pd
# Определяем соль :
salt= 'OkMdZa18pfr8m5sy2IL52pW9ol2EpLekgakJAIZFBbgZ'
# Функция которая будет делить на группы:
def funnel_user(base_traffic_split, test_seed, user_id):
test_id = hashlib.md5(test_seed.encode('ascii') + str(user_id).encode('ascii')).hexdigest()
bits = bin(int(test_id, 16))[3:]
r = sum([int(bit)*(0.5**(i+1)) for i, bit in enumerate(bits)])
if r < base_traffic_split:
return 'A'
else:
return 'B'
Проверяем:
new_split = [] # Сюда записываем группу
new_users= [] # Тут будет user_id
# df это ДатаФрейм с нашими user_id
for i in df['user_id']:
x = funnel_user(base_traffic_split= 0.5, test_seed=salt, user_id = i)
new_users.append(i)
new_split.append(x)
# Получаем Дата Фрейм с нашим сплитом
df_with_groups = pd.DataFrame({'user_id': new_users, 'ab_new_group': new_split})
# Следующий пример на основе библиотеки разработанной коллегами из FaceBook(Meta)
from planout.experiment import SimpleExperiment
from planout.ops.random import *
salt= 'OkMdZa18pfr8m5sy2IL52pW9ol2EpLekgakJAIZFBbgZ'
class MyExpiriment(SimpleExperiment):
def assign(self, params, userid):
self.salt = salt
params.test_group = UniformChoice(choices=['A', 'B'],
weights=[0.3, 0.7], unit=userid)
new_split = []
new_users= []
# experiment objects include all input data
for i in ab_test['user_pseudo_id']:
new_users.append(i)
new_split.append(MyExpiriment(userid=i).get('test_group'))
df_with_groups = pd.DataFrame({'user_id': new_users, 'ab_new_group': new_split})
Надеюсь кому-то это пригодится и буду рад вопросам, комментариям. Всем хороших А/Б тестов
메타데이터
- post_id
- 118c4cabbdec
- slug
- как-разделить-сплитануть-пользователей-user-id-на-группы-для-а-б-теста-118c4cabbdec
- url
- https://medium.com/@azizbek_performance/%D0%BA%D0%B0%D0%BA-%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%BB%D0%B8%D1%82%D0%B0%D0%BD%D1%83%D1%82%D1%8C-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B5%D0%B9-user-id-%D0%BD%D0%B0-%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%B0-%D0%B1-%D1%82%D0%B5%D1%81%D1%82%D0%B0-118c4cabbdec
- canonical_url
- https://medium.com/@azizbek_performance/%D0%BA%D0%B0%D0%BA-%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%BB%D0%B8%D1%82%D0%B0%D0%BD%D1%83%D1%82%D1%8C-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B5%D0%B9-user-id-%D0%BD%D0%B0-%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%B0-%D0%B1-%D1%82%D0%B5%D1%81%D1%82%D0%B0-118c4cabbdec
- author_url
- https://medium.com/@azizbek_performance
- status
- ok
- fetched_at
- 2026-07-25 17:14:12