mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-26 21:26:41 +08:00
877 lines
24 KiB
HTML
877 lines
24 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
||
<head>
|
||
|
||
<head>
|
||
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
|
||
<link rel="icon" href="/static/favicon.png">
|
||
|
||
<title>11 灰度实验:如何设计灰度实验并计算实验的收益?.md</title>
|
||
|
||
<!-- Spectre.css framework -->
|
||
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
|
||
<!-- theme css & js -->
|
||
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
|
||
</head>
|
||
|
||
|
||
|
||
<body>
|
||
|
||
|
||
|
||
<div class="book-container">
|
||
|
||
<div class="book-sidebar">
|
||
|
||
<div class="book-brand">
|
||
|
||
<a href="/">
|
||
|
||
<img src="/static/favicon.png">
|
||
|
||
<span>技术文章摘抄</span>
|
||
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="book-menu uncollapsible">
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="../">上一级</a></li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/00 开篇词 数学,编程能力的营养根基.md">00 开篇词 数学,编程能力的营养根基.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/01 从计数开始,程序员必知必会的数制转换法.md">01 从计数开始,程序员必知必会的数制转换法.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/02 逻辑与沟通,怎样才能讲出有逻辑的话?.md">02 逻辑与沟通,怎样才能讲出有逻辑的话?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/03 用数学决策,如何规划好投入、转化和产出?.md">03 用数学决策,如何规划好投入、转化和产出?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/04 万物可数学,经典公式是如何在生活中应用的?.md">04 万物可数学,经典公式是如何在生活中应用的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/05 求极值:如何找到复杂业务的最优解?.md">05 求极值:如何找到复杂业务的最优解?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/06 向量及其导数:计算机如何完成对海量高维度数据计算?.md">06 向量及其导数:计算机如何完成对海量高维度数据计算?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/07 线性回归:如何在离散点中寻找数据规律?.md">07 线性回归:如何在离散点中寻找数据规律?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/08 加乘法则:如何计算复杂事件发生的概率?.md">08 加乘法则:如何计算复杂事件发生的概率?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/09 似然估计:如何利用 MLE 对参数进行估计?.md">09 似然估计:如何利用 MLE 对参数进行估计?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/10 信息熵:事件的不确定性如何计算?.md">10 信息熵:事件的不确定性如何计算?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
<a class="current-tab" href="/专栏/程序员的数学课/11 灰度实验:如何设计灰度实验并计算实验的收益?.md">11 灰度实验:如何设计灰度实验并计算实验的收益?.md.html</a>
|
||
|
||
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/12 统计学方法:如何证明灰度实验效果不是偶然得到的?.md">12 统计学方法:如何证明灰度实验效果不是偶然得到的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/13 复杂度:如何利用数学推导对程序进行优化?.md">13 复杂度:如何利用数学推导对程序进行优化?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/14 程序的循环:如何利用数学归纳法进行程序开发?.md">14 程序的循环:如何利用数学归纳法进行程序开发?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/15 递归:如何计算汉诺塔问题的移动步数?.md">15 递归:如何计算汉诺塔问题的移动步数?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/16 二分法:如何利用指数爆炸优化程序?.md">16 二分法:如何利用指数爆炸优化程序?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/17 动态规划:如何利用最优子结构解决问题?.md">17 动态规划:如何利用最优子结构解决问题?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/18 AI 入门:利用 3 个公式搭建最简 AI 框架.md">18 AI 入门:利用 3 个公式搭建最简 AI 框架.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/19 逻辑回归:如何让计算机做出二值化决策?.md">19 逻辑回归:如何让计算机做出二值化决策?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/20 决策树:如何对 NP 难复杂问题进行启发式求解?.md">20 决策树:如何对 NP 难复杂问题进行启发式求解?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/21 神经网络与深度学习:计算机是如何理解图像、文本和语音的?.md">21 神经网络与深度学习:计算机是如何理解图像、文本和语音的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/22 面试中那些坑了无数人的算法题.md">22 面试中那些坑了无数人的算法题.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/23 站在生活的十字路口,如何用数学抉择?.md">23 站在生活的十字路口,如何用数学抉择?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/24 结束语 数学底子好,学啥都快.md">24 结束语 数学底子好,学啥都快.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
|
||
<div class="sidebar-toggle-inner"></div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script>
|
||
|
||
function add_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.add('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
function remove_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.remove('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
function sidebar_toggle() {
|
||
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let content = document.querySelector('.off-canvas-content')
|
||
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
|
||
sidebar_toggle.classList.remove('extend')
|
||
|
||
sidebar.classList.remove('hide')
|
||
|
||
content.classList.remove('extend')
|
||
|
||
} else { // hide
|
||
|
||
sidebar_toggle.classList.add('extend')
|
||
|
||
sidebar.classList.add('hide')
|
||
|
||
content.classList.add('extend')
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
function open_sidebar() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.add('show')
|
||
|
||
overlay.classList.add('show')
|
||
|
||
}
|
||
|
||
function hide_canvas() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.remove('show')
|
||
|
||
overlay.classList.remove('show')
|
||
|
||
}
|
||
|
||
|
||
|
||
</script>
|
||
|
||
|
||
|
||
<div class="off-canvas-content">
|
||
|
||
<div class="columns">
|
||
|
||
<div class="column col-12 col-lg-12">
|
||
|
||
<div class="book-navbar">
|
||
|
||
<!-- For Responsive Layout -->
|
||
|
||
<header class="navbar">
|
||
|
||
<section class="navbar-section">
|
||
|
||
<a onclick="open_sidebar()">
|
||
|
||
<i class="icon icon-menu"></i>
|
||
|
||
</a>
|
||
|
||
</section>
|
||
|
||
</header>
|
||
|
||
</div>
|
||
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
|
||
overflow-x: auto;
|
||
|
||
overflow-y: hidden;">
|
||
|
||
<div class="book-post">
|
||
|
||
<p id="tip" align="center"></p>
|
||
|
||
<div><h1>11 灰度实验:如何设计灰度实验并计算实验的收益?</h1>
|
||
|
||
<p>在之前的课时,我们对问题进行了形式化定义,并利用一个很牛的算法进行了最优化求解,之后我们便打造了一个全新的策略优化解决方案。</p>
|
||
|
||
<p>而接下来,你需要面对的问题,就是证明这个新的解决方案是有效的,是优于之前的解决方案的,而这个证明方法就是做 AB 实验。所以,这一讲我们就来说说 AB 实验的那些事。</p>
|
||
|
||
<h3>灰度实验</h3>
|
||
|
||
<p>在实际的工作中,通常需要进行灰度实验来验证某个新系统相对于旧系统的收益。<strong>灰</strong>是介于黑和白之间的颜色,可以理解为是个中间态。灰度实验,也可以称作为 AB 实验、灰度发布,名称虽然不同,但本质上是没有什么区别的。</p>
|
||
|
||
<p>AB 实验的理念,是构造一个平行世界,去观察两个世界的不同。具体来说就是,把线上的流量随机地拆分为具有同样分布的实验组和对照组,然后将新旧两个系统分别作用在这两组流量上,去观察业务指标的变化。</p>
|
||
|
||
<p>我们举个例子,假设大迷糊负责某个 App 信息流的推荐系统算法的开发。</p>
|
||
|
||
<p>原本推荐系统的版本号是 v1.0,大迷糊经过对算法和策略的功能迭代,开发了推荐系统 v2.0。接下来,他需要测试 v2.0 相比 v1.0 是否有效果的提升。如果没有提升,则说明开发失败;如果有提升,则开发成功,并可以考虑在线上用 v2.0 来代替 v1.0。</p>
|
||
|
||
<ul>
|
||
|
||
<li>为了测验证 v2.0 相比 v1.0 是否有效果的提升,大迷糊从数据库里筛出了 N 个用户。</li>
|
||
|
||
<li>接着,大迷糊通过某个随机算法,把这 N 个用户随机地拆分为人数相等的两组,分别命名为实验组和对照组,每组 N/2 个用户。</li>
|
||
|
||
<li>下一步,大迷糊用 v2.0 的推荐系统给实验组的 N/2 个用户推荐信息,再用 v1.0 的推荐系统给对照组的 N/2 个用户推荐信息。</li>
|
||
|
||
<li>经过了几周后,大迷糊分别计算了实验组和对照组用户的业务指标,可能有点击率 CTR、阅读量 PV、UV、用户活跃度等指标。</li>
|
||
|
||
<li>最终,大迷糊发现,实验组用户的各项指标都优于对照组用户的指标。</li>
|
||
|
||
</ul>
|
||
|
||
<p>这就证明 v2.0 的效果要优于 v1.0 的效果,因此 v2.0 系统成功代替了 v1.0 的系统,并在线上环境中全量生效。</p>
|
||
|
||
<h4>灰度实验的两个关键步骤</h4>
|
||
|
||
<p>虽然,大迷糊全量 v2.0 推荐系统的流程很复杂,但灰度实验本质上只有两个大步骤。</p>
|
||
|
||
<ul>
|
||
|
||
<li>第一步,分流。即如何获得实验组和对照组的两波流量。</li>
|
||
|
||
<li>第二步,评估。即用什么指标来分别衡量实验组和对照组的效果。</li>
|
||
|
||
</ul>
|
||
|
||
<p>可以说,这两步将直接决定灰度实验的成败。</p>
|
||
|
||
<p>你可能会困惑,决定灰度实验成败的不应该是新系统吗?v2.0 开发得好不好,才应该是决定灰度实验成败的因素呀。</p>
|
||
|
||
<p>其实,v2.0 的开发是上一个篇章中“形式化定义”和“最优化求解”要解决的问题;而灰度实验要解决的问题,是假设 v2.0 开发后,如何客观、量化地计算 v2.0 相比于 v1.0 的效果。</p>
|
||
|
||
<h3>分流原理</h3>
|
||
|
||
<p>分流的理念,是构造一个假想的平行世界,用以分别观察两个世界中样本的表现。</p>
|
||
|
||
<p>举个例子,大迷糊想论证推荐系统 v2.0 相对于推荐系统 v1.0 的效果。理论上最完美的做法是,在 1月1日 将 v1.0 部署在线上,观察用户在1月1日~1月31日整体的阅读表现;接着,再让时间回退到 1月1日,将 v2.0 部署在线上,再观察用户在1月1日~1月31日整体的阅读表现。可惜的是,平行世界并不存在,我们永远也无法让时间回退。</p>
|
||
|
||
<p>因此,人们想到一个替代办法,那就是在现实世界中,分别构造两波差不多的集合(也可以称作流量),来拟作两个平行世界,分别评测两个版本的推荐系统的效果,这就是分流。</p>
|
||
|
||
<p>网络上有这样一个段子。一个生物专家把一个完好的蜘蛛放在地上,拿个锣一敲,蜘蛛跑了;然后将蜘蛛的腿拔光,将其放在地上,再拿个锣一敲,咦,蜘蛛没反应!于是得到结论:蜘蛛的听觉器官在腿上。</p>
|
||
|
||
<p>在这个实验中,两组实验的蜘蛛一个有腿、一个没有腿,很显然犯了分流不随机的错误。可以说,分流方案的好坏,将直接影响评估结果的对错。常见的分流方法包括下面几种:</p>
|
||
|
||
<ul>
|
||
|
||
<li>按用户分流,即把用户随机拆分为两组;</li>
|
||
|
||
<li>按时间分流,例如上半月上线 v1.0,下半月上线 v2.0;</li>
|
||
|
||
<li>按地区分流,例如北边的用户上线 v1.0,南边的用户上线 v2.0;</li>
|
||
|
||
<li>组合分流,将上面的方法组合在一起使用。</li>
|
||
|
||
</ul>
|
||
|
||
<p>分流的底线要求是保持随机性,但到底按照上面哪个方法去分流,则需要根据实际情况来选择。我们再举几个工作中的例子。</p>
|
||
|
||
<ul>
|
||
|
||
<li>案例一 大漂亮论证推荐系统 v2.0 相对于推荐系统 v1.0 的效果。</li>
|
||
|
||
</ul>
|
||
|
||
<p>她采用了按地区分流,即北方人上线 v1.0,南方人上线 v2.0。这显然不是个好方法。原因是,北方人和南方人的喜好并不一样。当你的 AB 实验论证有正向收益时,你很难证明收益的来源,是喜好的不同,还是系统升级带来的效果。</p>
|
||
|
||
<ul>
|
||
|
||
<li>案例二 大聪明负责公司火车票业务的系统开发。</li>
|
||
|
||
</ul>
|
||
|
||
<p>他的实验采用了按时间分流,即二月份采用老系统,三月份采用了新系统,来对比系统之间的稳定性效果。这显然也不是个好方法,因为二月份包含了春节,访问量天然就大,性能压力也就大。所以新系统在三月表现出性能好,也许不是因为系统本身性能的提升,而是因为三月份访问量下降。</p>
|
||
|
||
<p><strong>因此要想做好分流,除了要满足一定的随机性外,更要符合人们认知的常理。</strong></p>
|
||
|
||
<h3>分流的实现</h3>
|
||
|
||
<p>分流的实现一般需要借助一个随机函数,再通过这个随机函数的输出结果,来判断分流的结果。假设待分流的样本有 1000 个,我们希望把样本随机分拆为 7:3 的两组。对每个样本,则需要调用随机函数得到一个随机值,再根据这个随机值对样本进行打标。</p>
|
||
|
||
<p>我们给出下面的一段代码:</p>
|
||
|
||
<pre><code>import random
|
||
|
||
|
||
|
||
exp = []
|
||
|
||
|
||
|
||
con = []
|
||
|
||
|
||
|
||
for i in range(1000):
|
||
|
||
|
||
|
||
value = random.randint(1,100)
|
||
|
||
|
||
|
||
if value <= 30:
|
||
|
||
|
||
|
||
exp.Append(i)
|
||
|
||
|
||
|
||
else:
|
||
|
||
|
||
|
||
con.Append(i)
|
||
|
||
|
||
|
||
print len(exp)
|
||
|
||
|
||
|
||
print len(con)
|
||
|
||
</code></pre>
|
||
|
||
<p>我们对代码进行走读:</p>
|
||
|
||
<ul>
|
||
|
||
<li>第 3~4 行,用两个数组来保存实验组和对照组;</li>
|
||
|
||
<li>第 5~10 行,对 1000 个样本进行循环;</li>
|
||
|
||
<li>对于每个样本,第 6 行得到一个 1~100 的随机数;</li>
|
||
|
||
<li>第 7~10 行,根据这个随机数与 30 的大小关系,来判断样本到底应该归为实验组还是对照组。</li>
|
||
|
||
</ul>
|
||
|
||
<p>这样就实现了按比例的随机分组,代码执行的结果如下图:</p>
|
||
|
||
<p>![image(assets/CgqCHl_Ar3mAZ-X0AABHe97oDUs202.png)</p>
|
||
|
||
<p>我们分为了实验组 290 人,对照组 710 人。</p>
|
||
|
||
<h3>AB 实验的评估</h3>
|
||
|
||
<p>当我们分好了流量之后,就要对实验组应用新系统、对对照组应用老系统,来开展 AB 实验。那么,当经历了一段时间后,如何来对 AB 实验的结果进行评估呢?</p>
|
||
|
||
<p><strong>这里的关键问题就是指标的计算。指标,就是说用什么变量来衡量观察的效果;以及由于分流带来样本集合的缩小,这些指标在样本子集上又该如何计算。</strong></p>
|
||
|
||
<p>我们举个例子,大漂亮想论证推荐系统 v2.0 相对于推荐系统 v1.0 的效果。</p>
|
||
|
||
<p>她采用用户随机分流的方式,以 3:7 的分流比例,开展 AB 实验,其中实验组有 30% 的用户,对照组有 70% 的用户,假设分流过程完全正确、没有偏差。</p>
|
||
|
||
<p>经过了一周的时间后,她观察到如下的原始数据:</p>
|
||
|
||
<p><img src="assets/Ciqc1F_AvSuAXRbnAAEYyM-ekmQ623.png" alt="4.png" /></p>
|
||
|
||
<p>接下来,如何衡量实验效果的好坏呢?</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>一个误区,是实验组点击量为 9000 小于对照组的 16000。于是得到结论,新系统效果不如老系统。这很显然是不对的,因为实验组只有 290 人,而对照组有 710 人。流量的不平衡天然就会造成点击量的不同。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p><strong>因此 AB 实验的指标中有这样一个原则:“量”指标一定要对流量进行归一化,得到“率”指标后,才可以对比。</strong></p>
|
||
|
||
<p>基于这个原则,我们可以重新设计如下几个实验评估指标:</p>
|
||
|
||
<ul>
|
||
|
||
<li>CTR(点击通过率)= 点击量 / 曝光量</li>
|
||
|
||
<li>上线率 = 上线用户数 / 注册用户数</li>
|
||
|
||
<li>人均曝光量 = 曝光量 / 注册用户数</li>
|
||
|
||
<li>人均点击量 = 点击量 / 注册用户数</li>
|
||
|
||
</ul>
|
||
|
||
<p>并将数据整理成下表:</p>
|
||
|
||
<p><img src="assets/Ciqc1F_AvPKAVErnAAMfqhlP4FA154.png" alt="1.png" /></p>
|
||
|
||
<p>根据该表实验对比的结果,可以得到以下结论:</p>
|
||
|
||
<ul>
|
||
|
||
<li>v2.0 的推荐系统相对于 v1.0 的推荐系统,点击率提高了 0.2 pp,有正向收益,但并不算多;</li>
|
||
|
||
<li>然而,点击率的小幅度提高,带来了用户留存、复访的大幅度提高,体现在上线率提高了 4.9 pp;</li>
|
||
|
||
<li>上线率提高,又让人均曝光量提高了 45 篇,让人均点击量提高了 8 篇。</li>
|
||
|
||
</ul>
|
||
|
||
<p>可见,推荐系统的迭代,换来了点击率的提高,点击率的提高又带来了更多的用户留存和复访,进一步带来了更多的用户曝光量和点击量。因此,v2.0 的推荐系统技术指标更优,并且带来了明显的业务收益。</p>
|
||
|
||
<h3>小结</h3>
|
||
|
||
<p>这一讲的核心就是评估效果,即当你完成了某个系统的迭代后,如何衡量新系统相比于就系统的收益是多少,这个过程便依赖灰度实验。</p>
|
||
|
||
<p>灰度实验的关键步骤包括两步,分别是分流和评估:</p>
|
||
|
||
<ul>
|
||
|
||
<li>分流有很多种方法,但一定要保证分流的随机性。</li>
|
||
|
||
<li>评估则需要把握好一个原则,那就是先把“量”指标按照流量归一化为“率”指标后,再来进行对比分析。</li>
|
||
|
||
</ul>
|
||
|
||
<p>最后留一个课后作业:假设有下面的实验数据,请你试着去分析实验的效果。</p>
|
||
|
||
<p><img src="assets/Ciqc1F_AvRSAP8QXAAC2sSEV_Ps109.png" alt="2.png" /></p>
|
||
|
||
<p>欢迎你在评论区与我分享你的答案。</p>
|
||
|
||
<p>现在我们学习了通过灰度实验去验证评估效果,那么又如何证明我们实验效果的可信度呢?所以下一讲,我将向你讲解“12 | 统计学方法:如何证明灰度实验效果不是偶然得到的?”带你将灰度实验进行到底。</p>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<div style="float: left">
|
||
|
||
<a href="/专栏/程序员的数学课/10 信息熵:事件的不确定性如何计算?.md">上一页</a>
|
||
|
||
</div>
|
||
|
||
<div style="float: right">
|
||
|
||
<a href="/专栏/程序员的数学课/12 统计学方法:如何证明灰度实验效果不是偶然得到的?.md">下一页</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
|
||
</div>
|
||
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997bd52e2d3cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
|
||
</body>
|
||
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
|
||
<script>
|
||
|
||
window.dataLayer = window.dataLayer || [];
|
||
|
||
|
||
|
||
function gtag() {
|
||
|
||
dataLayer.push(arguments);
|
||
|
||
}
|
||
|
||
|
||
|
||
gtag('js', new Date());
|
||
|
||
gtag('config', 'G-NPSEEVD756');
|
||
|
||
var path = window.location.pathname
|
||
|
||
var cookie = getCookie("lastPath");
|
||
|
||
console.log(path)
|
||
|
||
if (path.replace("/", "") === "") {
|
||
|
||
if (cookie.replace("/", "") !== "") {
|
||
|
||
console.log(cookie)
|
||
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
setCookie("lastPath", path)
|
||
|
||
}
|
||
|
||
|
||
|
||
function setCookie(cname, cvalue) {
|
||
|
||
var d = new Date();
|
||
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
|
||
var expires = "expires=" + d.toGMTString();
|
||
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
|
||
}
|
||
|
||
|
||
|
||
function getCookie(cname) {
|
||
|
||
var name = cname + "=";
|
||
|
||
var ca = document.cookie.split(';');
|
||
|
||
for (var i = 0; i < ca.length; i++) {
|
||
|
||
var c = ca[i].trim();
|
||
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
|
||
}
|
||
|
||
return "";
|
||
|
||
}
|
||
|
||
|
||
|
||
</script>
|
||
|
||
|
||
|
||
</html>
|
||
|