A/B测试流量切分做错,模型明明变好CTR却掉了?补完超参调优我才找到答案
A/B测试流量切分做错,模型明明变好CTR却掉了?补完超参调优我才找到答案上周三下午4点,我盯着Grafana上的A/B实验面板,实验组的CTR曲线像心脏病发作一样往下跳。前一天刚上的新推荐模型离线评估时CTR明明涨了3.5%,项目经理还在周会上夸了,结果灰度一开实验组反而不如对照组。我脑子里第一个念头:一定是流量切分出了问题。但排查了三天才发现,根本原因是模型本身就没训练到位,而我连超参调优的基本功都没打牢。后来补了一门机器学习入门课,才把实验设计里的根因一个个揪出来。那门课从数据预处理到模型评估,正好讲了我当时缺的那几块拼图,学完后的变化就是--我再也不会因为误判而扔掉一个好模型了。当时我完全不懂,一个好的实验设计远比调参本身更重要,而超参调优只是这个链条里的一环。下面就把那次翻车的完整复盘一五一十写出来,如果你也准备上线模型,或者被A/B结果折腾得怀疑人生,这篇东西应该能帮你省下至少两周的排障时间。那场A/B测试,差点让我把辛辛苦苦优化的推荐模型给毙了我们的推荐系统用了个双塔模型,离线N DCG涨了3.5%,召回也都正。我觉得稳了,直接开了A/B,给实验组10%的线上流量,监控三个指标:CTR、人均浏览时长、当日转化率。然后每天看板,第四天实验组CTR跌了1.2%,第八天跌了1.8%,统计上那个下降曲线持续不止。我当时慌得一批,赶紧把实验停掉,回滚了模型,写了个事后分析报告,结论是「新模型在线上劣于旧模型」。后来静下心来,翻了机器学习基础那门课里关于实验设计的章节,才发现我简直是反面教材里的教科书。超参调优没做透只是表象,更底层的是:流量切分方式让用户画像不均衡、指标选错了、样本量压根没算过、连p值都没算就拍脑袋看涨跌。这些坑但凡踩中一个,实验结论就可能完全是噪音,更别提我四个全踩了。从那以后我就长了个教训:模型上线前的实验设计,和模型开发至少五五开。机器学习入门课里有一章专门讲怎么设计可靠的在线实验,里面给出的清单我现在还贴在工位上,每次发版本前对照一遍。这门课适合转行做机器学习工程师的人,学完就能把实验流程标准化,不再拍脑袋决策。第一个坑:流量切分没用分层抽样,两组用户画像差了一截我当时做流量切分特别简单:用用户ID取哈希值,模100落在0-9的给实验组,10-99的给对照组。心想哈希均匀分布,这不就是随机均匀了嘛。结果上线四天后,我发现实验组的用户,近90天活跃度显著低于对照组--原来我们那周恰好搞了个大促拉回了一批沉睡用户,这群人刚好ID哈希落到了实验组居多。两组用户压根不可比,CTR的下降可能只是用户群体差异的假象。正确的做法应该用分层抽样,按用户的历史活跃度、购买频次、设备类型等维度分层,再在每一层内随机分配。我后来在补特征工程这个知识块时,才意识到从数据准备阶段就该把用户画像的特征拉出来做分层,而不是草草上线。那门机器学习入门课里的数据预处理部分,教了如何基于特征分布进行样本拆分,并给出了代码模板,这让我后面重做实验时直接复用了,少踩了不少坑。import pandas as pd from sklearn.model_selection import StratifiedShuffleSplit # 分层抽样示例 sss StratifiedShuffleSplit(n_splits1, test_size0.1, random_state42) for train_index, test_index in sss.split(df, df[[active_level, platform, purchase_freq]]): train_set df.iloc[train_index] test_set df.iloc[test_index]如果你在做在线实验,流量切分的代码一定要把分层逻辑嵌进去,不要像我一样用裸哈希。另外,数据预处理是整套机器学习管道的前置步骤,那门课里花了整整一个模块讲怎么清洗和取样,学完之后我才真正理解什么叫“垃圾数据进,垃圾结论出”。第二个坑:只盯CTR,忽略了转化率和复购率,掉进了过拟合的陷阱CTR下降让我慌了,但事后拉出漏斗分析才发现,虽然实验组的点击率掉了,但加购率反而涨了,最终的成交转化率与对照组持平。如果当时我同时监控转化率和复购率,就会看到实验组可能在“点击-购买”链条上表现更优,CTR的下降或许只是因为模型推荐了更精准的商品,减少了无效曝光。这其实是一个典型的过拟合思路--我过度优化了CTR这个单一指标,忽略了业务目标的多维性。A/B实验应该定义主指标(比如成交转化率)和多个护栏指标(CTR、人均曝光、留存等),任何一个护栏指标显著恶化都要叫停。混淆矩阵也能在离线阶段帮你分析模型在不同类别上的表现,但我在上线前根本没看混淆矩阵,只看了AUC,这也是致命疏忽。机器学习基础这类课程会教你如何定义评估体系,不只是看一个数字,而是建立多维指标矩阵。学了之后,我每次实验都要事先约定三个指标:核心指标(成交转化率)、正向辅助指标(用户停留时长)和反向护栏指标(CTR不能跌超2%),并设定阈值。这样即便某个指标有波动,也能做综合判断,而不是一刀切砍模型。第三个坑:没做统计显著性检验,拍了脑袋就下结论我回想起来最汗颜的一点:全程没算过p值,只是每天刷新看板,感觉CTR连续几天比对照组低,就下结论说模型不行。实际上,CTR本身的方差就很大,尤其是在样本量不够的时候,连续几天的下跌可能只是随机波动。如果我当时算一下双尾检验,或许根本就不存在显著差异。后来我翻教材,了解到最小可检测效应(MDE)和所需样本量之间的对应关系。我们每天实验组曝光量才5万次,要检测1%的CTR差异,至少需要跑两周以上才能达到80%的统计功效。我第四天就停了实验,等于根本没给模型展示真实能力的机会。from scipy import stats # 假设对照组和实验组的CTR比例 control_visitors 500000 control_conversions control_visitors * 0.05 experiment_visitors 50000 experiment_conversions experiment_visitors * 0.048 z_stat, p_val stats.proportions_ztest( [experiment_conversions, control_conversions], [experiment_visitors, control_visitors], alternativetwo-sided ) print(fp-value: {p_val:.4f})如果你也卡在「实验结果该怎么解读」这个点上,超参调优相关的课程会连带教你实验数据分析,因为调参过程本身也需要设计对比实验。那门机器学习入门里就有一个专门讲实验分析的小节,从置信区间到A/B测试,学完之后我甚至能把实验报告直接写进晋升材料里。补课超参调优后,才发现模型从未真正收敛排查完实验设计的问题后,我又回到模型本身。拉出训练过程的loss曲线一看,好家伙,模型在训练集上还没收敛,我居然就推上线了。learning rate设得太高,导致loss震荡,batch size又太小,梯度更新不稳定。我之前调参全凭感觉,学习率、正则化系数、网络层数都是拍脑袋试。直到系统学了一遍超参调优,我才知道有网格搜索、随机搜索、贝叶斯优化这一套方法论。用上了Hyperopt之后,只跑了15组实验,就在验证集上找到了比之前手动调参高出2%的AUC。from hyperopt import hp, fmin, tpe, Trials space { learning_rate: hp.uniform(learning_rate, 1e-5, 1e-2), batch_size: hp.choice(batch_size, [64, 128, 256]), hidden_units: hp.choice(hidden_units, [128, 256, 512]) } def objective(params): # 训练并返回验证loss val_loss train_and_evaluate(params) return val_loss trials Trials() best fmin(objective, space, algotpe.suggest, max_evals15, trialstrials)超参调优不是神秘的技术,而是一套科学的搜索策略。机器学习入门教你在小型项目里怎么用GridSearchCV入门,而更高级的深度学习课程里还会讲到针对大模型的超参搜索技巧。我补完这些,回头再看当初的模型,发现batch size和learning rate根本不匹配,相当于踩在地毯上跑步--使不上劲。重新设计实验后,5%的提升终于坐实了把上述坑全部填上后,我重新设计了一版实验: 1. 使用分层抽样确保两组用户画像可比; 2. 确定主指标为成交转化率,护栏指标为CTR(下跌不超过2%)和客单价; 3. 用统计功效计算所需最小样本量,决定至少跑满6万次曝光再分析; 4. 对模型做超参调优,确保在训练集和验证集上都收敛且无过拟合; 5. 上线前用混淆矩阵和校准曲线验证离线模型质量。这次跑了整整12天,中间每天只看护栏指标是否有异常,主指标等到样本量够了再做单次检验。最终结果显示,实验组成交转化率提升4.7%,p值小于0.01,CTR下降1.5%但在可接受范围内。我终于敢放心地把模型全量了。整个过程下来,我从一个乱来的实验新手,变成了能系统设计实验的老手。而帮助我完成这个转变的,就是那次翻车之后狠心去啃的几门课程。其中机器学习入门那门课把超参调优、评估和实验设计串了起来,特别适合刚转行或者从后端转过来的人。而机器学习管道相关的知识,又帮我把整个流水线标准化,从数据预处理到特征存储再到上线监控,全都可复现了。给同样处境的人几条建议别只盯一个指标,哪怕是CTR这种看起来最直接的。建立指标矩阵,主指标、护栏指标一起看,混淆矩阵在离线阶段就要画出来查漏补缺。统计显著性不是玄学,算一下p值和样本量需求,别拍脑袋叫停实验。超参调优的课程里一般都会教这部分实验设计,值得点进去看一看,把方法论吃透。流量切分必须分层,用户画像的分布差异可以轻松毁掉一次实验。特征工程和数据预处理这些环节,在实验设计阶段就要介入,而不是等到构建训练集才用。超参调优解决的是模型能力下限的问题,一个没收敛的模型直接上A/B,测出来的只是噪声。学了AWS机器学习相关的系统课程,你能获得的不仅是调参方法,更是整套模型上线前的检查清单。如果你跟当时的我一样,觉得「机器学习入门」太基础懒得学,那我劝你放低心态。我就是自以为已经入门,结果在实验设计上栽了跟头。那门课恰好补足了我缺失的评估和实验知识。最后,机器学习基础这门课里有一张实验设计流程图,我直接打印出来贴在显示器旁边,每次灰度前照做一遍,避免重蹈覆辙。那次翻车让我至少白扔了三个迭代的时间,但也逼我真正搞懂了超参调优和实验设计的底层逻辑。希望你的A/B测试,不要再走我走过的弯路。