如何从Low/Medium/High intent三类各抽50%样本完成A/B测试分组
分层A/B测试分组实现方案
以下给出两种最常用场景的实现方式,均满足按Low intent/Medium intent/High intent三层独立1:1拆分的要求:
1. Python Pandas 实现(本地小数据集)
适合本地处理csv/excel格式的小批量数据,支持固定随机种子复现分组结果:
import pandas as pd import numpy as np # 1. 读取数据,可替换为 pd.read_csv("你的数据文件路径") df = pd.DataFrame({ "ID": [1,2,3,4,5,6], "Buyer Intent": ["Low Intent", "Medium Intent", "Medium Intent", "Low Intent", "High Intent", "High Intent"], "Email": ["john@gmail.com", "jane@gmail.com", "tom@gmail.com", "sara@gmail.com", "mich@gmail.com", "sall@gmail.com"] }) # 2. 固定随机种子,保证后续可复现本次分组结果,数值可自定义 SEED = 42 # 3. 按买家意图分层,每层独立随机拆分50%对照组/50%实验组 def split_group(df_group): rand_arr = np.random.RandomState(SEED).rand(len(df_group)) df_group['Group'] = np.where(rand_arr < 0.5, 'Control', 'Treatment') return df_group df = df.groupby('Buyer Intent', group_keys=False).apply(split_group) # 需要存文件就执行 df.to_csv("分组结果.csv", index=False) print(df)
2. SQL 实现(数仓大数据集)
适合数据存储在数据库/数仓的场景,直接跑SQL生成结果:
SELECT ID, `Buyer Intent`, Email, -- 行号奇数为对照组,偶数为实验组 CASE WHEN MOD(rn, 2) = 1 THEN 'Control' ELSE 'Treatment' END AS `Group` FROM ( SELECT *, -- 按买家意图分层后随机排序生成行号 ROW_NUMBER() OVER (PARTITION BY `Buyer Intent` ORDER BY RAND()) AS rn FROM your_table_name -- 替换为你的表名 ) t
不同数据库的随机函数略有差异,PostgreSQL用RANDOM()替换RAND()即可,Hive/Spark SQL直接用RAND()
注意事项
- 两种实现均保证每个意图层级的对照组、实验组占比严格接近1:1,避免不同意图用户的分布偏差影响实验结论
- 固定随机种子(Python)或者固定排序种子(SQL可以把
RAND()换成RAND(固定数值))可以保证分组结果可复现,方便后续回溯
内容的提问来源于stack exchange,提问作者Ryan Dan
相关产品推荐
相关产品推荐

