mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
965 lines
25 KiB
HTML
965 lines
25 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>08 加乘法则:如何计算复杂事件发生的概率?.md.html</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.html">00 开篇词 数学,编程能力的营养根基.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/01 从计数开始,程序员必知必会的数制转换法.md.html">01 从计数开始,程序员必知必会的数制转换法.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/02 逻辑与沟通,怎样才能讲出有逻辑的话?.md.html">02 逻辑与沟通,怎样才能讲出有逻辑的话?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/03 用数学决策,如何规划好投入、转化和产出?.md.html">03 用数学决策,如何规划好投入、转化和产出?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/04 万物可数学,经典公式是如何在生活中应用的?.md.html">04 万物可数学,经典公式是如何在生活中应用的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/05 求极值:如何找到复杂业务的最优解?.md.html">05 求极值:如何找到复杂业务的最优解?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/06 向量及其导数:计算机如何完成对海量高维度数据计算?.md.html">06 向量及其导数:计算机如何完成对海量高维度数据计算?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/07 线性回归:如何在离散点中寻找数据规律?.md.html">07 线性回归:如何在离散点中寻找数据规律?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
<a class="current-tab" href="/专栏/程序员的数学课/08 加乘法则:如何计算复杂事件发生的概率?.md.html">08 加乘法则:如何计算复杂事件发生的概率?.md.html</a>
|
||
|
||
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/09 似然估计:如何利用 MLE 对参数进行估计?.md.html">09 似然估计:如何利用 MLE 对参数进行估计?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/10 信息熵:事件的不确定性如何计算?.md.html">10 信息熵:事件的不确定性如何计算?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/11 灰度实验:如何设计灰度实验并计算实验的收益?.md.html">11 灰度实验:如何设计灰度实验并计算实验的收益?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/12 统计学方法:如何证明灰度实验效果不是偶然得到的?.md.html">12 统计学方法:如何证明灰度实验效果不是偶然得到的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/13 复杂度:如何利用数学推导对程序进行优化?.md.html">13 复杂度:如何利用数学推导对程序进行优化?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/14 程序的循环:如何利用数学归纳法进行程序开发?.md.html">14 程序的循环:如何利用数学归纳法进行程序开发?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/15 递归:如何计算汉诺塔问题的移动步数?.md.html">15 递归:如何计算汉诺塔问题的移动步数?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/16 二分法:如何利用指数爆炸优化程序?.md.html">16 二分法:如何利用指数爆炸优化程序?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/17 动态规划:如何利用最优子结构解决问题?.md.html">17 动态规划:如何利用最优子结构解决问题?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/18 AI 入门:利用 3 个公式搭建最简 AI 框架.md.html">18 AI 入门:利用 3 个公式搭建最简 AI 框架.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/19 逻辑回归:如何让计算机做出二值化决策?.md.html">19 逻辑回归:如何让计算机做出二值化决策?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/20 决策树:如何对 NP 难复杂问题进行启发式求解?.md.html">20 决策树:如何对 NP 难复杂问题进行启发式求解?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/21 神经网络与深度学习:计算机是如何理解图像、文本和语音的?.md.html">21 神经网络与深度学习:计算机是如何理解图像、文本和语音的?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/22 面试中那些坑了无数人的算法题.md.html">22 面试中那些坑了无数人的算法题.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/23 站在生活的十字路口,如何用数学抉择?.md.html">23 站在生活的十字路口,如何用数学抉择?.md.html</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="/专栏/程序员的数学课/24 结束语 数学底子好,学啥都快.md.html">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>08 加乘法则:如何计算复杂事件发生的概率?</h1>
|
||
|
||
<p>在我们的工作和生活中少不了对概率的计算,对概率的准确计算会帮助我们做出更加合理高效的决策。</p>
|
||
|
||
<p>例如,早上出门之前,你需要对是否携带雨伞进行决策。如果没有任何依据而随机决策,那么就会遇到下雨没带伞或者晴天带伞的麻烦;而如果有依据,你知道今天下雨的概率超过 80%,那么你就会做出带雨伞的决策,来规避下雨带来不便的风险。</p>
|
||
|
||
<p>那么问题来了,对于一个事件而言,其发生的概率该如何计算呢?这一讲我们就来解答。</p>
|
||
|
||
<h3>概率来自统计</h3>
|
||
|
||
<p>还记得我们最开始接触概率时的定义吗?概率用来描述一个事件发生的可能性,它是个 0 到 1 的数字。概率的定义式就是 m/n,含义为假设某个现象重复执行 n 次(n 较大),其中目标事件发生了 m 次,则目标事件发生的概率就是 m/n。</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>举个例子,一枚硬币重复抛 100 次,其中正面朝上 49 次,反面朝上 51 次,则硬币正面朝上的概率就是 0.49。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p>概率的定义式非常重要,如果你能灵活运用,并结合一定的代码开发,有时候可以快速解决一个复杂的数学问题。</p>
|
||
|
||
<p>我们举个例子,在一个正方形内有一个内切圆,在正方形内随机选取一点,问该点也在圆内的概率是多少?
|
||
|
||
<img src="assets/CgqCHl-zjyKAWZQDAABRFSgu6k0435.png" alt="Lark20201117-165117.png" />
|
||
|
||
这是个数学问题,但你可以借助概率的定义式完成计算,代码如下:</p>
|
||
|
||
<pre><code>import random
|
||
|
||
|
||
|
||
def main():
|
||
|
||
|
||
|
||
m = 0
|
||
|
||
|
||
|
||
n = 1000
|
||
|
||
|
||
|
||
for _ in range(n):
|
||
|
||
|
||
|
||
x = random.random()
|
||
|
||
|
||
|
||
y = random.random()
|
||
|
||
|
||
|
||
if x*x + y*y < 1:
|
||
|
||
|
||
|
||
m += 1
|
||
|
||
|
||
|
||
print 1.0*m/n
|
||
|
||
|
||
|
||
if __name__ == '__main__':
|
||
|
||
|
||
|
||
main()
|
||
|
||
</code></pre>
|
||
|
||
<p>我们对代码进行走读:</p>
|
||
|
||
<ul>
|
||
|
||
<li>第 4、5 行定义了 m 和 n 两个变量。其中,n 赋值为 1000,意味着我们要重复执行这个动作 1000 次,m 表示坐标点落入圆内的次数;</li>
|
||
|
||
<li>接下来,就是第 6~10 行的 1000 次实验的循环了。每次实验,我们随机生成一个坐标点 (x,y),其中 x 和 y 的取值范围都是 0~1 的浮点数;</li>
|
||
|
||
<li>这样,在第 9 行中,如果点 (x,y) 与原点的距离小于 1,则表示该点在圆内,m 自动加 1;</li>
|
||
|
||
<li>最后,打印出 m 和 n 的比值。</li>
|
||
|
||
</ul>
|
||
|
||
<p>我们运行程序的结果如下:
|
||
|
||
<img src="assets/CgqCHl-zj0mAcEsZAABNWAtZ0sk472.png" alt="Drawing 1.png" /></p>
|
||
|
||
<p>这个题目如果从数学的视角来计算,结果就是 P =πr2÷4r2= π÷4 = 0.785,这与我们的计算结果是一样的。</p>
|
||
|
||
<p>未来,如果你遇到复杂的概率计算时,不妨试着用这种统计法来求解。</p>
|
||
|
||
<h3>用加乘法则来计算复杂事件的概率</h3>
|
||
|
||
<p>统计法是一种用程序思想解决数学问题的范例,但这并不意味着你不需要学习数学中概率计算的原理。原因在于,有些场景下重复试验的条件并不成立;或者是事件极其复杂,重复试验的代价太大。这就需要我们掌握一些基本的概率计算法则。</p>
|
||
|
||
<p>在这一课时,我们重点介绍加法原理和乘法原理。</p>
|
||
|
||
<h4>1.加法原理</h4>
|
||
|
||
<p>加法原理可以理解为,一个事件有多个可能的发生路径,那么这个事件发生的概率,就是所有路径发生的概率之和。</p>
|
||
|
||
<p>例如,在掷骰子的游戏中,掷出的点数大于 4 的概率是多少?</p>
|
||
|
||
<p>掷骰子的 6 个可能的点数是 6 个路径,每个路径发生的概率是 1/6,其中满足条件中点数大于 4 的只有最后两条路径。利用加法原理则有,点数大于 4 的概率为 1/6 + 1/6 = 1/3,如下图:
|
||
|
||
<img src="assets/Ciqc1F-zj1qAN-hzAACxn7OHrQI389.png" alt="Lark20201117-165123.png" /></p>
|
||
|
||
<h4>2.乘法原理</h4>
|
||
|
||
<p>如果将加法原理理解为是串行的逻辑,那么乘法原理就是个并行的逻辑。乘法原理可以理解为,某个事件的发生,依赖多个事件的同时发生。那么原事件发生的概率,就是所有这必须发生的多个事件的乘积。</p>
|
||
|
||
<p>例如,你与大迷糊一起玩掷骰子的游戏,求大迷糊掷出 4 点的同时,你最终获胜的概率是多少?</p>
|
||
|
||
<p>这时候,计算的概率就必须两个条件同时发生。这两个条件分别是,大迷糊掷出 4 点和你的点数大于 4。根据前面的计算,我们知道掷骰子点数大于 4 的概率为 1/3。因此,这两个条件发生概率的乘积就是最终的结果,即 P (大迷糊掷出 4 点的同时,你最终获胜) = 1/6×1/3 = 1/18 = 0.0556。</p>
|
||
|
||
<p>对于这个例子,我们可以用统计法进行仿真,代码如下:</p>
|
||
|
||
<pre><code>import random
|
||
|
||
|
||
|
||
obj = 0.0
|
||
|
||
|
||
|
||
for _ in range(10000):
|
||
|
||
|
||
|
||
you = random.randint(1,6)
|
||
|
||
|
||
|
||
damihu = random.randint(1,6)
|
||
|
||
|
||
|
||
if damihu == 4 and you > damihu:
|
||
|
||
|
||
|
||
obj += 1
|
||
|
||
|
||
|
||
print obj/10000
|
||
|
||
</code></pre>
|
||
|
||
<p>我们对代码进行走读:</p>
|
||
|
||
<ul>
|
||
|
||
<li>第 3 行的 obj,就是最终事件发生的频次;</li>
|
||
|
||
<li>我们对现象观察 10000 次,这样就形成了第 4~8 行的 for 循环;</li>
|
||
|
||
<li>每次循环,在第 5 和 6 行,随机生成你的点数和大迷糊的点数;</li>
|
||
|
||
<li>第 7 行进行判断,大迷糊为 4 点且你的点数大于大迷糊的点数;</li>
|
||
|
||
<li>如果满足条件,则在第 8 行执行 obj 加 1;</li>
|
||
|
||
<li>最终,打印出 obj 除以 10000。</li>
|
||
|
||
</ul>
|
||
|
||
<p>这段代码运行的结果如下图,跟我们计算的结果几乎一致。
|
||
|
||
<img src="assets/Ciqc1F-zj2iAQDXfAAIhj_Pzl0k278.png" alt="Lark20201117-165125.png" /></p>
|
||
|
||
<h3>条件概率</h3>
|
||
|
||
<p>刚刚的加乘法则,适用于独立事件的概率求解。独立事件的含义,就是上面所提到的原子事件。也就是,拆解出的子事件之间没有任何的先后或互相影响结果的因素。例如,大迷糊爱喝咖啡,和大漂亮爱穿高跟鞋,就是两个毫无关系的独立事件。对于独立事件,应用加乘法则可以很快得到整体的概率。</p>
|
||
|
||
<p>那么,如果我们无法得到独立的事件,而都是耦合在一起的事件,又该如何计算概率呢?这就需要用到条件概率的知识了。</p>
|
||
|
||
<p><strong>条件概率</strong>,指事件 A 在另外一个事件 B 已经发生条件下的发生概率,记作 P(A|B),读作“B 条件下 A 的概率”。条件概率的定义式为 P(A|B) = P(AB) / P(B),将其变换一下就是 P(AB) = P(A|B) × P(B)。</p>
|
||
|
||
<blockquote>
|
||
|
||
<p>条件概率的特殊性,在于事件 A 和事件 B 有千丝万缕的联系。如果二者为毫无关联的独立事件的话,事件 A 的发生则与 B 毫无关系,则有 P(A|B) = P(A)。</p>
|
||
|
||
</blockquote>
|
||
|
||
<p>我们给一个例子辅助理解。假设有一对夫妻,他们有两个孩子。求他们在有女儿的条件下,两个孩子性别相同的概率是多少?</p>
|
||
|
||
<p>这个概率看似难求,但只要定义好事件并套用定义式,就能完成计算。我们把事件 B 定义为,这对夫妻有女儿,事件 A 为两个孩子性别相同。因此,计算的目标就是 P(A|B),也就是计算 P(A|B) = P(AB) / P(B)。</p>
|
||
|
||
<ul>
|
||
|
||
<li>事件 AB 的含义是这对夫妻有女儿,且两个孩子性别相同。也就是说,这对夫妻的孩子都是女儿,即第一胎是女儿,第二胎还是女儿。此时根据乘法原理,得到 P(AB) = (1/2)×(1/2) = 1/4。</li>
|
||
|
||
<li>事件 B 为这对夫妻有女儿,不管第几胎,甚至是两胎都是女儿。这样就有了 3 种可能的情况:分别是第一胎女儿、第二胎儿子;第一胎儿子、第二胎女儿;第一胎女儿、第二胎女儿。这样根据加法原理和乘法原理,得到 P(B) = (1/2)×(1/2)+(1/2)×(1/2)+(1/2)×(1/2) = 3/4。因此 P(A|B) = P(AB) / P(B) = (1/4) / (3/4) = 1/3。</li>
|
||
|
||
</ul>
|
||
|
||
<p>对于这个例子,我们用如下代码进行仿真:</p>
|
||
|
||
<pre><code>import random
|
||
|
||
|
||
|
||
fenzi = 0
|
||
|
||
|
||
|
||
fenmu = 0
|
||
|
||
|
||
|
||
for _ in range(1000):
|
||
|
||
|
||
|
||
#0 is girl; 1 is boy
|
||
|
||
|
||
|
||
first = random.randint(0,1)
|
||
|
||
|
||
|
||
second = random.randint(0,1)
|
||
|
||
|
||
|
||
if first == 1 and second == 1:
|
||
|
||
|
||
|
||
continue
|
||
|
||
|
||
|
||
else:
|
||
|
||
|
||
|
||
fenmu += 1
|
||
|
||
|
||
|
||
if first == second:
|
||
|
||
|
||
|
||
fenzi += 1
|
||
|
||
|
||
|
||
print 1.0*fenzi/fenmu
|
||
|
||
</code></pre>
|
||
|
||
<p>我们对代码进行走读。</p>
|
||
|
||
<ul>
|
||
|
||
<li>第 6 行开始,重复循环 1000 次。</li>
|
||
|
||
<li>第 8~9 行,随机生成两个孩子的性别。用 0 代表女儿,用 1 代表儿子。如果两个孩子都是儿子,则进行下一轮迭代。因为,这并不满足至少有一个女儿的假设条件。</li>
|
||
|
||
<li>第 12 行开始,如果有女儿,则分母加 1,如果两个孩子的性别一致,则分子也加 1。</li>
|
||
|
||
<li>最终打印出分子和分母的比值。</li>
|
||
|
||
</ul>
|
||
|
||
<p>程序执行的效果如下图所示,结果与我们计算的近似相等:
|
||
|
||
<img src="assets/Ciqc1F-zj3eAfosoAAIjh42fWgA084.png" alt="Lark20201117-165128.png" />
|
||
|
||
当你遇到一个复杂事件的时候,一定要通过串行或并行的两重逻辑进行拆解。再基于加乘法则,利用每个原子粒度事件的概率,合成最终复杂事件发生的概率。</p>
|
||
|
||
<p>接下来,我们看一些更复杂的问题。</p>
|
||
|
||
<h3>一个概率计算的案例</h3>
|
||
|
||
<p>假设大漂亮在某电商公司,负责实时的红包券投放策略。大漂亮设计的投放策略是,如果用户在商品的详情页停留了 1 分钟以上,则认为该用户正在纠结是否购买此商品。此时,给用户实时投放一定金额的红包,来增加用户的购买可能性。</p>
|
||
|
||
<p>试着分析一下,这里的事件之间的概率关系,以及投放红包到底产生了怎样的概率刺激效果?</p>
|
||
|
||
<p>可以想象,用户购买某个商品的动作顺序是,点击商品详情页,再付款购买。很显然“点击详情页”和“付款购买”并不是独立的事件,原因在于不点击详情页是无法完成购买动作的,二者存在先后关系。因此 <strong>P(点击并购买) = P(购买|点击) × P(点击)</strong>,这个公式对所有的用户都生效。</p>
|
||
|
||
<p>接下来,大漂亮的红包投放条件是,用户在商品的详情页停留了 1 分钟以上。此时,产生购买行为的用户就有两部分,分别是使用红包的购买用户和未使用红包的购买用户。很显然,使用红包和不使用红包是两个并行的逻辑,可以采用加法原理进行概率计算,因此有</p>
|
||
|
||
<p><strong>P(点击并购买) = P(点击并使用红包购买) + P(点击并未使用红包购买)</strong>。</p>
|
||
|
||
<p>再分别拆解两部分概率,根据乘法原理和条件概率,则有</p>
|
||
|
||
<p><strong>P(点击并购买) = P(购买|点击并获得红包) × P(获得红包|点击) × P(点击) + P(购买|点击并未获得红包) × P(未获得红包|点击) × P(点击)</strong>。</p>
|
||
|
||
<p>假设策略上线后,大漂亮根据上线前后的数据,统计得到了每个环节的概率如下表所示:</p>
|
||
|
||
<p><img src="assets/CgqCHl-zj4WAWvnJAAG9FsQTO-g751.png" alt="Lark20201117-165130.png" /></p>
|
||
|
||
<p>从表中数据可以发现以下几个结论:</p>
|
||
|
||
<ul>
|
||
|
||
<li>投放红包是在点击之后,因此对点击率无影响;</li>
|
||
|
||
<li>用户点击商品详情页的条件下,获得红包的概率是 0.3,未获得红包的概率是 0.7;</li>
|
||
|
||
<li>对于未获得红包的用户,其购买率与实验前一致,都是 0.4。对于获得红包的用户,其购买率会上升,达到 0.5。</li>
|
||
|
||
</ul>
|
||
|
||
<p>最终,根据公式计算下来,点击并购买的概率由 0.2 提升到了 0.215,这就是红包投放的收益。</p>
|
||
|
||
<h3>小结</h3>
|
||
|
||
<p>最后,我们对这一讲进行总结。概率的计算是高中和大学数学中有趣又让人头疼的内容,为了学好概率的知识,你不妨牢牢记住下面几个关键点。</p>
|
||
|
||
<ul>
|
||
|
||
<li>概率来自统计。当你束手无策时,不妨从多次的重复试验中,统计目标事件出现的频次,来估算概率。</li>
|
||
|
||
<li>加乘法则是计算概率的有力手腕。对复杂事件按照并行或串行来拆解,再利用加乘法则就可以完成复杂事件的概率计算。</li>
|
||
|
||
<li>条件概率是处理有关联事件的方法。虽然条件概率有些晦涩,但牢牢记住定义式 P(A|B) = P(AB) / P(B),就能让条件概率转换为普通事件的概率。在实际应用中,一定要耐着性子,仔细琢磨事件背后的相关关系,再利用这些方法,就能把概率计算清楚。</li>
|
||
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<div style="float: left">
|
||
|
||
<a href="/专栏/程序员的数学课/07 线性回归:如何在离散点中寻找数据规律?.md.html">上一页</a>
|
||
|
||
</div>
|
||
|
||
<div style="float: right">
|
||
|
||
<a href="/专栏/程序员的数学课/09 似然估计:如何利用 MLE 对参数进行估计?.md.html">下一页</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":"70997bce0f333cfa","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>
|
||
|