概率论基础相关笔记

一、基础

原文:prob140/textbook/notebooks/ch01

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

究竟是什么概率,一直是有争议的辩论主题。有些人认为概率是长期的频率,只适用于在相同条件下可能反复发生的事件。其他人则认为概率量化了个体对任何事件的不确定性的主观程度,并且可能因人而异。还有一些人并不严格属于这些分组。

概率含义的争论使伟大的概率论者吉米·萨维奇(Jimmie Savage,1917-1971)观察到“自从巴别塔以来很少有这种完全的分歧和争论。”

现在,频率论者和主观主义者之间的分歧,并不像以前那么广泛。在 Prob140 中,对于概率的含义,欢迎你自己做出决定。

无论哲学上的争论如何,概率的基本组合方式都可以通过考虑比例来理解。这就是我们将在前两章中探讨的内容。我们先来介绍一些概率论的标准术语。

结果空间和事件

任何涉及随机性的实验都会产生许多可能的结果之一。结果空间是所有这些结果的集合。

形式上,结果空间只是一个集合,通常用Ω表示。这是大写的希腊字母 Omega。

现在我们将假设Ω是有限的。从某种意义上说,这不是限制性的,因为即使是最大的数据集也是有限的,而且功能最强大的计算机每个任务都执行许多有限操作。但是,我们很快就会看到,允许无限的可能结果,不仅会产生丰富而优雅的理论,而且会让我们更深入地了解涉及有限结果空间的问题。因此,一旦我们理清了有限的情况,那么Ω是有限的假设将在后面的章节中被解除。

结果ω是结果空间Ω的一个元素。虽然ω看起来像字母w,但它是小写的希腊 omega,通常比w更圆润。

事件是Ω的一个子集。允许空集φ和整个空间Ω作为子集。按照惯例,像AB这样的前面几个字母通常用作事件的符号。

示例一:排列

假设你正在对三张牌洗牌,分别是abc。 那么所有可能的结果空间是:

\Omega ~=~ \{ abc, ~acb, ~bac, ~bca, ~cab, ~cba \}

事件{abc, acb}可以被描述为“首先出现a”。 通过将事件定义为子集,事件的这种口头描述变得正式。这是发展精确而一致的理论的第一步,同时也应用于自然语言中。

事件 口头描述 子集
A a首先出现 {abc, acb}
B bc不挨着 {bac, cab}
C 字母是字母表中的顺序 {abc}
D a首先出现,b其次,但是c不是第三个 ϕ
E c是第一个,第二个或者第三个 Ω
F 字母来自于表示"taxi"的单词 {cab}

“类型”的注解:结果ω = cab与事件F = {cab}不同。结果是结果空间的一部分,事件是结果空间的一个子集。 这个子集碰巧只包含一个结果,但它仍然是一个子集,而不是一个元素。 你可以把它看作类似 Python 中的不同类型:'cab'是一个字符串,而['cab']是一个列表。

该表包含六个事件,你可以想出更多。 对于每一个,看看你是否可以提供一个有趣的口头描述。

当你为游戏洗牌时,目标是使牌的顺序变得“随机”。 最好是,你希望任何排列与其他排列可能性相同。 那么让我们开始研究等可能的结果。

等可能结果

“如果投掷一枚硬币,那么它是正面的几率是多少呢?”提出这个问题,你会得到的最常见的答案是 1/2。如果你询问理由,没有意外会听到,“因为硬币有两面。”一枚硬币确实有两面,但是注意到一个隐藏在你所得到的“推理”中的假设:两面中的每一面都与另一面相同。

等可能的结果的假设是一种简单而古老的随机性模型。它将概率定义为比例。Ω是有限的假设,使得易于将比例识别为结果总数的一小部分。

对于一些n>1,令Ω包含n个结果。让A ⊆ Ω成为一个事件。将#(A)定义为子集A中结果的数量。因此,对于任何其他事件,#(Ω )= n#(φ) = 0,并且0 < #(A) < n

对于事件A,设P(A)表示 A发生的概率或几率。我们将同义地使用“probability”和“chance”两个词(翻译为“概率”或“几率”),并且我们通常会使用“happens”而不是更正式的“occurs”(都翻译为“发生”)。

等可能的结果空间中的概率

假设Ω中的所有n个结果是等可能的,则事件A发生的概率由下式定义:

P(A) ~=~ \frac{\#(A)}{\#(\Omega )} ~=~ \frac{\#(A)}{n} ~=~ \text{proportion of outcomes in } A

这种概率是比例的想法是许多计算的核心。 你将会看到,比例的组合规则成为概率的组合规则,无论所有结果是否是等可能的。 但是现在我们将在结果可能性相同的自然假设下开展工作。

示例一:随机排列

Ω是字母abc的所有排列的空间。 那么Ω包含n = 6个结果:

\Omega ~=~ \{ abc, ~acb, ~bac, ~bca, ~cab, ~cba \}

如果我们假设所有六种排列是等可能的,我们着手于三个字母的随机排列。 在这个假设下,我们可以用一列几率来扩展我们的事件表。

事件 口头描述 子集 概率
A a首先出现 {abc, acb} 2/6 = 1/3
B bc不挨着 {bac, cab} 1/3
C 字母是字母表中的顺序 {abc} 1/6
D a首先出现,b其次,但是c不是第三个 ϕ 0
E c是第一个,第二个或者第三个 Ω 1
F 字母来自于表示"taxi"的单词 {cab} 1/6

要注意:

P(a \text{ appears last}) = \frac{\#\{ bca, ~cba \}}{6} ~=~ \frac{1}{3} ~=~ \frac{\#\{ bac, ~cab \}}{6} ~=~ P(a \text{ appears second})

因此,所有排列等可能的假设,使得所有三个位置是等可能的。你应该检查bc的位置也是如此。

示例二:随机数生成

假设一个随机数生成器从00,01,02,...,98,99的 100 个偶对 中返回一对数字,使得所有偶对等可能返回。

你会注意到这些偶对与 0 到 99 的 100 个整数相对应。在下面的内容中,乘法法则会很有用:

第一个数字有 10 个选项:0,1,2,3,4,5,6,7,8,9
对应于第一位数字的每个选择,第二位数字有 10 个选择。
所以总共有10×10 = 100对数字。

这里“偶对”是两个数字的序列,一个接一个。偶对 27 与 72 不同。它们有时称为“有序对”。在本文中,所有序列都是有序的。

现在我们来计算一些事件的概率。通过假设,所有偶对都是等可能的。因此,每个答案将包括计算事件中的偶对数量,然后除以总数,即 100。

(1)偶对由两个不同的数字组成的概率是多少?

我们必须计算a ≠ b的偶对ab的数量。数字a可以按 10 种方式选择;对于每种方式,只有 9 种方法用于选择b,因为b必须与a不同。所以答案是:

P(\text{the pair consists of two different digits}) ~=~ \frac{90}{100} ~=~ 0.9

(2)两个数字相同的几率是多少?

让我们尝试使用我们对(1)的回答。 在 100 对中的每一对中,两个数字相同或不同。 没有一对可以属于两个类别,所以按照我们的比例规则:

P(\text{the two digits are the same}) ~=~ 1 ~-~ P(\text{the pair consists of two different digits}) ~=~ 0.1

为了通过计数来检查这一点,你必须统计aa形式的偶对。 有 10 种方法可供选择,之后就没有更多的选择了。 所以答案是10/100 = 0.1,证实了以上我们的计算。

散列中的碰撞

在计算机科学中,散列函数将一个称为散列值的代码分配给一组个体中的每一个。为每个个体分配一个独特的值是很重要的。如果相同的值分配给了两个个体,则会发生碰撞,这会产生认证问题。然而,跟踪哪些散列值已分配或未分配是很麻烦的,因为散列值和个体的数量可能非常大。

如果散列值只是随机分配,而并不考虑哪些已经分配了呢?如果存在大量不同的值和相对较少的个体,那么认为碰撞的可能性很小,似乎是合理的。例如,如果有 1,000 个可用的散列值并且只有 5 个个体,那么如果你为这 5 个个体选择了 5 个值的随机序列,则似乎不太可能会发生冲突。

让我们对随机性做一些假设,找出没有碰撞的概率。假设有N个散列值和n个个体,并且假设你的散列函数是这样的,那么对个体的所有 N^n 个赋值都是等可能的。赋值是序列 a_0 a_1 \ldots a_n,其中,对于每个i,将散列值 a_i 分配给个体i

请注意,我们假定n个个体中的每一个,都可以被分配N个值中的任何一个,而不管分配给其他人的是什么。这包括了不幸的概率,所有n个个体被赋予相同值。

无碰撞

无碰撞的概率是什么?

如果个体数量n大于散列值N的数量,则答案为 0。如果个体数量多于个人数量,那么你将不得不重复使用某些值,因此无法避免碰撞。

但是我们对n很小的情况感兴趣,所以假设n ≤ N,我们没有问题。

如果回顾前一部分中,随机数生成器的例子中的第(1)部分,你会发现,在N = 10n = 2的情况下,它与我们当前的问题相同。 我们可以按照相同的流程来获得我们的答案。

根据假设,所有 N^n 个可能的赋值都是等可能的。其中一些赋值不包含碰撞。我们的工作是统计它有多少。

你熟悉 Python 的从 0 开始的索引系统,它在这里派上用场。 我们必须计算序列 a_0a_1 \ldots a_{n-1} 的数量,其中每个 a_i 是 N 个哈希值之一,并且所有 a_i 都彼此不同。

  • a_0N个选项。
  • 对于每一种选择,a_1 都有N-1个选项,因为 a_1 必须与 a_0 不同。
  • 因此,有N(N-1)种方式填充位置 0 和 1 而避免碰撞。
  • 对于这些选择 a_0a_1N(N-1)种方法,a_2N-2个选择。 这是因为 a_2 必须不同于彼此不同的 a_0a_1
  • 因此,有N(N-1)(N-2)种填充位置 0, 1 和 2 的方式。
  • 请注意,对于每个i,与位置i对应的乘积中的项是N-i。这使序列容易延续到最后,即位置(n-1)

P(\mbox{no collisions}) ~=~ \frac{N(N-1)(N-2) \cdots (N-(n-1))}{N^n} ~=~ \frac{N(N-1)(N-2) \cdots (N-n+1)}{N^n}

“延续序列”是一个需要数学证明的非正式过程。 你可以通过归纳法来证明。

分子中的乘积有n项,分母中有n个因子。 这使我们可以用不同的方式编写公式,作为n个分数的乘积:

P(\mbox{no collisions}) ~=~ frac{N}{N} \cdot \frac{N-1}{N} \cdot \frac{N-2}{N} \cdots \frac{N-n+1}{N} ~=~ \prod_{i=0}^{n-1} \frac{N-i}{N}

符号 \prod 表示求积,就像 \sum 表示求和。

现在是坏消息了:

至少一个碰撞

每个序列要么至少有一次碰撞,要么没有碰撞。 没有序列可以位于这两个类别中,所以按照我们的比例规则:

P(\mbox{at least one collision}) ~=~ 1 ~-~ \prod_{i=0}^{n-1} \frac{N-i}{N}

我们有了公式。这很棒!但是答案很大,还是很小?仅通过观察公式不容易分辨。那么让我们以不同的方式开始检验答案。

第一种方法是数字。为此,我们必须处理Nn的数值。我们在一个背景中会实现它,这个背景让这个计算变得著名。

生日问题

一个经典的概率问题是生日的“碰撞”。这个生日问题由理查德·冯·米塞斯和其他数学家提出 - 它的起源并不完善。主要问题是,“如果一个房间里有n个人,那么他们中的一些人有相同的生日的几率是多少?”

随机性假设

这个问题通常在每年 365 天的假设下得到解决,并且无论其他人的生日如何,每个人都有可能在 365 天中的任何一天出生。

你可以看到,这些假设忽略了闰年以及多胎(例如双胞胎)以及一年中出生分布不均匀的情况。这些假设使得计算更简单,但可能并不能反映人口中的生日的实际情况。数据科学家必须小心他们的假设 - 如果假设没有反映真相,那么结论也不会。

所以让我们注意,我们正在根据简化的假设进行工作,在对特定的群体做出结论之前我们应该检查一下。在任何情况下,忽略闰年和多胎都不应对结论产生重大影响。如果在一年中的某些时候,出生比其他时候更可能发生,那么就证明了生日相同的几率将大于我们在假设下得到的答案。

生日问题有很多变化,但我们会专注于经典问题。

匹配的概率

我们将简洁地陈述我们的假设,因为“所有 365^n 个生日序列是等可能的”。 你可以看到,这使得生日问题与上一节的碰撞问题相同,其中N = 365。 如前所述,唯一有趣的情况是当n ≤ N时,为此:

P(\text{no match}) ~=~ P(\text{all n birthdays are different}) ~=~ \prod_{i=0}^{n-1} \frac{N-i}{N}

计算几率

N固定在 365 时,函数p_no_matchn为参数并返回在n个生日之中不存在匹配的概率。

代码的其余部分在一个表中显示所有结果。该表还包含一列,包含存在碰撞的几率:

P(\text{at least one matching pair}) ~=~ 1 - P(\text{no match}) ~=~ 1 ~-~ \prod_{i=0}^{n-1} \frac{N-i}{N}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
N = 365

def p_no_match(n):
individuals_array = np.arange(n)
return np.prod( (N - individuals_array)/N )

results = Table().with_column('Trials', np.arange(1, N+1, 1))

different = results.apply(p_no_match, 'Trials')

results = results.with_columns(
'P(all different)', different,
'P(at least one match)', 1 - different
)

results
Trials P(all different) P(at least one match)
1 1 0
2 0.99726 0.00273973
3 0.991796 0.00820417
4 0.983644 0.0163559
5 0.972864 0.0271356
6 0.959538 0.0404625
7 0.943764 0.0562357
8 0.925665 0.0743353
9 0.905376 0.0946238
10 0.883052 0.116948

… (355 rows omitted)

表中首先要注意的是,使用标签Trials来表示人。在概率中,通常将随机试验看作是试验序列,其中每个试验的结果取决于旅几率。 在生日问题中,每个人都被认为是一个试验,我们正在研究所有试验中是否至少有一对匹配的生日。

接下来,请注意,在只有一个人的无聊情况下,不能存在一对匹配的生日,因此P(no match)定义为 1。在许多问题中存在这样的“边界情况”,必须单独处理。

最后,请注意,当人数很少时,他们生日不同的几率很大。这与我们的直觉是一致的,即如果个体数量相对于可用散列值的数量较小,并且随机给个人赋值,那么碰撞的几率很小。

生日“悖论”

但是碰撞几率随人数增加而增加。实际上,它增加得很快。

1
2
3
results.scatter('Trials', 'P(at least one match)')
plt.xlim(0, N/3)
plt.ylim(0, 1);

你可以看到,如果有超过 50 人,那么生日相同的几率就接近 1。

为了使碰撞几率超过 50%,必须有多少人? 让我们看看我们能否找到这种情况发生的最少人数。

1
results.where('P(at least one match)', are.between(0.5, 0.51))
Trials P(all different) P(at least one match)
23 0.492703 0.507297

仅仅是 23 人,碰撞的可能性就大于不碰撞。 这让那些没有做计算的人感到惊讶,因此被称为生日悖论。 但事实上,它根本就没有任何矛盾或矛盾之处。 这与生日相同几率随着人数的增加而增长的方式有关。

我们已经完成了N = 365的计算,但如果 N 是其他数字,函数的增长有多快? 如果我们要在生日以外的案例中应用我们的结果,我们需要知道它。

为了解决这个问题,我们可以重新编写各种不同N值的代码,并查看输出告诉我们的这些值的结果。 但是使用数学更加高效和富有洞察力,这是我们将在下一节中做的事情。

指数近似

本节的目标是,了解当有N个散列值且N大于n时,至少有一次碰撞的几率,如何表现为个体数n的函数。

我们知道几率是:

P(\text{at least one collision}) ~=~ 1 ~-~ \prod_{i=0}^{n-1} \frac{N-i}{N}

虽然这给出了准确的几率公式,但它并不能让我们了解函数如何增长。让我们看看我们是否可以开发一个近似值,它的形式更简单,因此更容易学习。

近似中的主要步骤将在本课程中重复使用,因此我们将在这里详细介绍它们。

步骤 1:仅仅近似需要近似的项

虽然这看起来很明显,但值得注意的是,它可以节省大量不必要的操作。 我们正在尝试近似:

1 ~-~ \prod_{i=0}^{n-1} \frac{N-i}{N}

所以我们需要近似的所有东西,就是:

\prod_{i=0}^{n-1} \frac{N-i}{N}

最后我们可以将 1 减去近似值。

换句话说,我们将近似P(no collision)

步骤 2:使用对数将乘法变成加法

我们的公式是乘法,但使用加法要好得多。 对数函数可帮助我们将乘积变成和:

\log (P(\text{no collision})) ~=~ \sum_{i=0}^{n-1} \log(\frac{N-i}{N})

一旦我们有了log(P(no collision))的近似值,我们就可以使用指数将其转换为我们想要的近似值,即P(no collision)

步骤 3:使用对数的性质

这通常是主要计算的步骤。 请记住对于较小的x\log(1+x) \sim x,其中符号 \sim 表示当x变为 0 时,双方的比例变为 1。对于较大的x,近似值可能不是很好,但无论如何让我们尝试一下。

\begin{align*} \log(P(\text{no collision})) ~ &=~ \sum_{i=0}^{n-1} \log(\frac{N-i}{N}) \\ &=~ \sum_{i=0}^{n-1} \log(1 - \frac{i}{N}) \\ &\sim ~ \sum_{i=0}^{n-1} (- \frac{i}{N}) \\ &=~ -\frac{1}{N} \sum_{i=0}^{n-1} i \\ \\ &= - \frac{1}{N} \cdot \frac{(n-1)n}{2} \end{align*}

根据前n-1个正整数的和的公式。

步骤 4:按需转换来完成近似

艰苦的工作已经完成,现在我们只需要清理干净。 第 3 步给了我们:

\log(P(\text{no collision})) ~\sim ~ - \frac{1}{N} \cdot \frac{(n-1)n}{2}

对两边取指数,我们得到:

P(\text{no collision}) ~\sim ~ e^{- \frac{1}{N} \cdot \frac{(n-1)n}{2}} ~=~ e^{- (n-1)n/2N } ~ \sim ~ e^{-n^2/2N}

最后:

P(\text{at least one collision}) ~\sim ~ 1 - e^{- \frac{(n-1)n}{2N}} ~ \sim ~ 1 - e^{-n^2/2N}

现在你可以看到,作为人数的函数,为什么P(at least one collision)迅速上升。 记住N是固定的,n在 1 和N之间变化。随着 n 增加,(n-1)n快速增加,基本上类似n^2。 所以-n2 / 2N快速下降,使得 e^{-n^2 / 2N} 迅速下降;这让 1-e^{-n^2 / 2N} 飞了起来。

值得注意的是,在整个计算中只有一个近似值:它在步骤 3 的中间,我们使用ln(1 + x) ~ x表示较小的x。我们会在课程中多次遇到这个近似值。

近似值有多好

为了查看指数近似值与确切概率的相比如何,让我们在生日的背景下开展工作;如果你更喜欢不同的配置,你可以在代码中更改N

为了查看整个步骤序列,我们将重新进行精确计算并用一列近似值扩展它们。 我们将使用上述两者的更精细的近似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
N = 365 

def p_no_match(n):
individuals_array = np.arange(n)
return np.prod((N - individuals_array)/N)

trials = np.arange(1, N+1, 1)
results = Table().with_column('Trials', trials)
different = results.apply(p_no_match, 'Trials')

results = results.with_columns(
'P(at least one match)', 1 - different,
'Exponential Approximation', 1 - np.e**( -(trials - 1)*trials/(2*N) )
)

results
Trials P(at least one match) Exponential Approximation
1 0 0
2 0.00273973 0.00273598
3 0.00820417 0.00818549
4 0.0163559 0.016304
5 0.0271356 0.0270254
6 0.0404625 0.0402629
7 0.0562357 0.0559104
8 0.0743353 0.0738438
9 0.0946238 0.0939222
10 0.116948 0.115991

… (355 rows omitted)

前 10 个近似值看起来不错。 让我们来看看更多。

1
2
3
results.scatter('Trials')
plt.xlim(0, N/3)
plt.ylim(0, 1);

在这张图的尺度上,蓝点(精确值)与金点(我们的指数近似值)几乎没有区别。 你可以再次运行代码,使用不精确的近似法,它将(n-1)n替换为n^2,并看到近似值仍然很好。

我们从近似的第二种形式中学到,n个指定值中至少有一次碰撞的几率,大致是 1-e^{-cn^2},其中c是正的常数。

当我们稍后在课程中研究瑞利(Rayleigh)分布时,我们将再次遇到函数 1-e^{-cx^2}

二、计算几率

原文:prob140/textbook/notebooks/ch02

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

一旦你开始处理概率问题,你很快就会意识到所有可能结果是等可能的假设并不总是合理的。例如,如果你认为硬币有偏差,那么你就不会认为它的正反面具有相同的几率。

为了处理一些情况,其中某些结果比其他结果几率更高,需要更普遍的理论。在 20 世纪 30 年代,俄罗斯数学家安德烈科尔莫戈罗夫(Andrey Kolmogorov,1903-1987)提出了一些基本规则,称为公理,涵盖了丰富的情况,并成为现代概率论的基础。

公理从结果空间Ω开始。我们现在假设Ω是有限的。概率是一个定义在事件上的函数P,正如你所知,它是Ω的子集。前两个公理只是设置了度量的尺度:他们将概率定义为 0 和 1 之间的数字。

  • 概率是非负的:对于每个事件AP(A) \ge 0
  • 整个空间的概率为 1:P(\Omega)= 1

第三个也是最后一个公理,它是概率成为事件“测度”的关键。在我们制定了一些相关术语后,我们会研究它。

加法

第三个公理关于互斥事件。非正式来讲,如果最多只有一个事件发生,则两个事件AB是互斥的;换句话说,它们不能同时发生。

例如,假设你从一门课中随机抽取一名学生,其中 40% 的学生是新生,20% 是大二学生。每个学生既可以是大一学生,也可以是大二学生,也可以什么都不是;但没有一个学生既是大一学生,也是大二学生。所以如果A是“所选学生是新生”而B是事件“所选学生是二年级”的事件,则AB是相斥的。

互斥事件有什么大不了的?要理解这一点,首先考虑所选学生是大一学生或大二学生的事件。在集合论的语言中,这是“新生”和“大二”两个事件的结合。使用维恩图来显示事件是一个好主意。在下图中,将AB设想为两个互斥的事件,显示为蓝色和金色圆圈。因为事件是互斥的,所以相应的圆不重叠。并集是两个圆圈中所有点的集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def show_disjoint_union():
plt.figure(figsize=(10, 20))
# create the circles with shapely
a = sg.Point(1.4,2.5).buffer(1.0)
b = sg.Point(3.3,2.5).buffer(0.75)


# use descartes to create the matplotlib patches
ax = plt.subplot(121)
ax.add_patch(descartes.PolygonPatch(a, fc='darkblue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(b, fc='gold', ec='k', alpha=0.6))
ax.annotate('A', [1.4, 2.5])
ax.annotate('B', [3.3, 2.5])

# control display
plt.title('Mutually Exclusive Events')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

# use descartes to create the matplotlib patches
ax = plt.subplot(122)
ax.add_patch(descartes.PolygonPatch(a, fc='blue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(b, fc='blue', ec='k', alpha=0.8))

# control display
plt.title('Disjoint Union')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

show_disjoint_union()

学生是大一或大二的几率是多少? 在总体中,40% 是大一,20% 是大二,所以自然答案是 60%。 这是满足我们“大一或大二”标准的学生的百分比。 简单的加法是有效的,因为两组不相交。

科尔莫戈罗夫用这个想法来形成第三个,也是最重要的概率公理。正式来讲,如果交集为空,则AB是互斥事件:

A \cap B = \phi

第三个公理,加法规则

在有限结果空间的背景下,公理表明:

  • 如果AB是互斥事件,那么 P(A \cup B) = P(A) + P(B)

你将在练习中表明这个公理蕴涵着更一般的东西:

  • 对于任何固定的n,如果 A_1, A_2, \ldots, A_n 是互斥的(也就是对于所有 i \ne jA_i \cap A_j = \phi),那么:

    P\big{(} \bigcup_{i=1}^n A_i \big{)} = \sum_{i=1}^n P(A_i)

    有时叫做有限可加性公理。

这个看似简单的公理具有巨大的力量,特别是当它扩展到无数个互斥的事件时。首先,它可以用来创建一些方便的计算工具。

嵌套事件

假设一个班级中有 50% 的学生将数据科学作为他们的专业之一,40% 的学生主修数据科学和计算机科学(CS)。 如果你随机选择一个学生,那么该学生主修数据科学,但不是 CS 的几率是什么?

下面的维恩图显示了一个对应于事件A(数据科学作为专业之一)的深蓝色圆圈,和一个对应B(主修数据科学和 CS)的金色圆圈(未按比例绘制)。这两个事件是嵌套的,因为BA的一个子集:B中的每个人都把数据科学作为他们的专业之一。

所以 B \subseteq A,那些主修数据科学但不是 CS 的人是AB的差:

A - B = A \cap \bar B

其中 \bar BB的补集。差是右侧浅蓝色的圆圈。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def show_difference():
plt.figure(figsize=(10, 20))
# create the circles with shapely
a = sg.Point(2,2.5).buffer(1.0)
b = sg.Point(2,2.5).buffer(0.75)

# compute the 2 parts
left = a.difference(b)
middle = a.intersection(b)

# use descartes to create the matplotlib patches
ax = plt.subplot(121)
ax.add_patch(descartes.PolygonPatch(left, fc='darkblue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(middle, fc='olive', ec='k', alpha=0.8))

# control display
plt.title('Nested Events')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

# use descartes to create the matplotlib patches
ax = plt.subplot(122)
ax.add_patch(descartes.PolygonPatch(left, fc='blue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(middle, fc='None', ec='k', alpha=0.8))

# control display
plt.title('The Difference')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

show_difference()

这个学生在浅蓝色的差中的几率是多少呢? 如果你回答“50% - 40% = 10%”,你是对的,你的直觉说概率的行为就像区域一样。他们是这样。 事实上,这个计算是从可加性的公理出发的,我们也通过查看这些区域来受它们启发。

减法规则

假设AB是事件,B \subseteq A。那么 P(A - B) = P(A) - P(B)

证明。由于 B \subseteq A

A = B \cup (A - B)

这是个不相交集合,根据加法公理:

P(A) = P(B) + P(A - B)

所以,

P(A - B) = P(A) - P(B)

补集

如果一个事件的几率是 40%,它不会发生的几率是多少? 60% 的“明显”答案是减法规则的特例。

补集规则

对于任何事件BP(\bar B) = 1 - P(B)

证明。 下面的维恩图显示了要做什么。 在减法公式取A = Ω,记住第二个公理 P(Ω)= 1。或者,在这种特殊情况下为减法规则重新取参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def show_complement():
plt.figure(figsize=(10, 20))
# create the square and circle with shapely
a = sg.box(0, 0, 4.5, 4.5)
b = sg.Point(2.25,2.5).buffer(1)

# compute the 2 parts
left = a.difference(b)
middle = a.intersection(b)

# use descartes to create the matplotlib patches
ax = plt.subplot(121)
ax.add_patch(descartes.PolygonPatch(left, fc='None', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(middle, fc='darkblue', ec='k', alpha=0.8))

# control display
plt.title('An Event (Square = Omega)')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

# use descartes to create the matplotlib patches
ax = plt.subplot(122)
ax.add_patch(descartes.PolygonPatch(left, fc='blue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(middle, fc='None', ec='k', alpha=0.8))

# control display
plt.title('The Complement')
plt.axis('off')
ax.set_xlim(0, 5); ax.set_ylim(0, 5)
ax.set_aspect('equal')

show_complement()

当你在概率计算中看到减号时,就像在上面的补集规则中一样,你会经常发现减号是由于在附加规则的应用中,术语的重新排列。

当你加或减概率时,你就隐式地将一个事件分解成不相交的部分。这被称为划分事件,是需要掌握的一项基本的重要技术。在随后的章节中,你将看到很多划分的用法。

示例

让我们看看我们是否可以使用我们开发的结果来计算一些几率。一些步骤不计算也能清楚;其他东西需要更多的工作。

示例 1:n次投掷中的正面和反面

一枚硬币被抛出n次,以使所有 2^n 种可能的正反面序列是等可能的。

问题。获得至少一个正面和至少一个反面的几率是多少?

回答。许多序列中每一面至少出现一次。例如,如果n = 4,则这样的序列包括HTTTHTHTTTHT等等。

方法 - 补集:当一个事件可能以多种不同的方式发生时,查看它不会发生的方式可能是一个好主意,因为这样情况较少。

对于n = 4,每个面没有至少出现一次的唯一序列是HHHHTTTT。事实上,对于任何n,只有两个序列,我们不能从中得到两个面:所有都是正面和所有都是反面。这些是所有元素都相同的两个序列。

A成为事件“我们得到至少一个正面和至少一个反面”。问题要求P(A)。因为 \bar A 是事件“序列的所有元素都相同”,所以我们有:

P(\bar A) = \frac{2}{2^n} = \frac{1}{2^{n-1}}

根据补集规则:

P(A) = 1 - \frac{1}{2^{n-1}}

请注意,随着n变大,答案趋于 1。随着大量的投掷,你几乎肯定可以看到正面和反面。

示例 2:骰子的 12 次投掷的最大值

一个骰子投掷了 12 次,所以所有 6^12 个点数序列是等可能的。将 12 个投掷的最大值定义为 12 个点数中出现的最大值。 例如,序列354222143351的最大值是 5。

问题 1。最大值小于 5 的概率是多少?

答案 1。关键是观察事件“最大值小于 5”与事件“所有 12 个面都小于 5”相同。 为了发生这种情况,12 个点数中的每一个都必须具有四个值 1 到 4 之一。所以:

P(\text{maximum is less than 5}) = \frac{4^{12}}{6^{12}}

是的,我们可以进一步简化,但我们不打算,因为很快就会明白原因。

问题 2。最大值小于 4 的概率是多少?

答案 2。这里没有什么新东西,除了在问题 1 中将 5 替换成 4。

P(\text{maximum is less than 4}) = \frac{3^{12}}{6^{12}}

问题 3。最大值等于 4 的概率是多少?

答案 3:写下所有最大值等于 4 的序列的并不容易。 让我们看看,我们是否可以使用我们已经知道的。 最大值等于 4:

最大值必须小于 5,
并且不能小于 4。

我们将集合{4}看作一个差:{1,2,3,4} - {1,2,3}

所以通过减法规则,

\begin{align*} P(\text{maximum is equal to 4}) &= P(\text{maximum is less than 5}) - P(\text{maximum is less than 4}) \\ &= \frac{4^{12}}{6^{12}} - \frac{3^{12}}{6^{12}} \end{align*}

12 次投掷没有什么特别之处。你可以在整个过程中用n代替 12,并且参数将如上所述。

最大值是一个极值的例子,另一个是最小值。

解决问题的技巧:当你使用极值时,请记住我们在本例中使用的观察结果:说最大值很小等同于说所有元素都很小。类似地,说最小值很大等同于说所有元素都很大。

示例 3:大于第一个随机数的第二个随机数

一个随机数生成器产生两个数字,因此所有 100 对数字都是等可能的。

问题。第二位数字大于第一位的可能性是多少?

答案,方法一 - 划分:制定事件发生的所有方式的组织清单。 列出第二个数字大于第一个数字的一个好方法是,根据第一个数字的值来划分它们:

  • 第一位数字 0,第二位 1 到 9
  • 第一位数字 1,第二位 2 到 9
  • 第一位数字 2,第二位 3 到 9
  • 等等,直到
  • 第一位数字 8,第二位 9

这个划分使其很容易计算,在 100 个可能的偶对中,第二个数字大于第一个数字的所有偶对:有9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = (9×10) / 2 = 45种。所以答案是 0.45。

答案,方法二 - 对称性:用一些对称性说服自己:第二个数字大于第一个数字的几率与第一个数字大于第二个数字的几率相同。一种方法是根据第二个数字的值,来划分第二个事件,并注意与方法一中的划分的对应关系。

所以如果 p = P(\text{second digit is greater than the first}),加法规则表明:

\begin{align*} 1 &= P(\text{first digit is greater than the second}) + P(\text{the two digits are equal}) + P(\text{second digit is greater than the first}) \\ &= p + \frac{10}{100} + p \end{align*}

因为有 10 对相等的数字:00, 11, 22, ..., 99。现在求解p

p = \frac{1 - 0.1}{2} = 0.45

像之前一样。

学习这两种方法是一个好主意。划分和对称将在整个课程中使用。

乘法

概率的主要公理有关互斥事件,事实证明,我们不需要任何其他公理来处理相交的事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def show_intersection():
plt.figure(figsize=(8, 16))
# create the circles with shapely
a = sg.Point(-.5,0).buffer(1.0)
b = sg.Point(0.5,0).buffer(0.75)

# compute the 3 parts
left = a.difference(b)
right = b.difference(a)
middle = a.intersection(b)

# use descartes to create the matplotlib patches
ax = plt.subplot(121)
ax.add_patch(descartes.PolygonPatch(left, fc='darkblue', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(right, fc='gold', ec='k', alpha=0.6))
ax.add_patch(descartes.PolygonPatch(middle, fc='olive', ec='k', alpha=0.8))
ax.annotate('A', [-0.5, 0])
ax.annotate('B', [0.5, 0])

# control display
plt.title('Two Events')
plt.axis('off')
ax.set_xlim(-2, 2); ax.set_ylim(-2, 2)
ax.set_aspect('equal')

# use descartes to create the matplotlib patches
ax = plt.subplot(122)
ax.add_patch(descartes.PolygonPatch(left, fc='None', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(right, fc='None', ec='k', alpha=0.8))
ax.add_patch(descartes.PolygonPatch(middle, fc='blue', ec='k', alpha=0.8))

# control display
plt.title('The Intersection')
plt.axis('off')
ax.set_xlim(-2, 2); ax.set_ylim(-2, 2)
ax.set_aspect('equal')

show_intersection()

AB为两个事件。 交集A ∩ BAB都是发生的事件,右侧的维恩图中以亮蓝色显示。

因为我们会一直遇到交集,所以在我们的表示法中我们会有点偷懒:我们将使用AB来表示交集,而不会写入交集符号。你必须记住AB是一个事件,而不是乘积。

这里有一个例子可以帮助解释我们即将制定的一些定义。

无放回随机抽取

假设我有一个小牌组,由一张红色,一张绿色和一张蓝色的牌组成。假设我洗牌,抽一张,给剩下的两张洗牌,然后从中抽出一张。这被称为在不从牌组替换的情况下,随机抽取两张牌。

一个合理的结果空间是Ω = {RG, RB, GB, GR, BR, BG},其中所有六个元素的等可能的。

我们首先获得绿色,然后是红色的牌的几率,是单个序列GR的几率:

P(\text{GR}) = \frac{\#\{\text{GR}\}}{6} = \frac{1}{6}

简单的计算包含更有趣的东西。 注意:

P(\text{GR}) = \frac{1}{6} = \frac{1}{3} \times \frac{1}{2}

第二个因子 1/2 是什么?要理解这一点,只要看看G排在第一位的偶对。 其中,只有一个的下一张牌是R。乘积的第二个因子是:

\frac{\#\{\text{GR}\}}{\#\{\text{GR, GB}\}} = \frac{1}{2}

这个分数被称为,在G是第一个的条件下,R是第二个的条件概率。

它表示为P(second card R∣first card G)。这是垂直的条形,不是倾斜的。

现在我们对这张牌的原始计算可以写成一次一张牌:

\begin{align*} P(\text{GR}) &= \frac{\#\{\text{GR}\}}{6} \\ \\ &= \frac{\#\{\text{GR, GB}\}}{6} \times \frac{\#\{\text{GR}\}}{\#\{\text{GR, GB}\}} \\ \\ &= P(\text{first card G}) \times P(\text{second card R} \mid \text{first card G}) \end{align*}

条件概率

像上面这样的计算启发了一个新的定义。让AB为两个事件。那么BA条件下的条件概率定义为:

除法规则:

P(B \mid A) = \frac{P(AB)}{P(A)}

这里有一些滥用符号的情况。B|A不是一个事件。 但是符号很方便。整个左侧应被理解为“在发生A的情况下的B发生的概率”。

定义表明:给定A发生了,所以把你的注意力限制在A发生的结果上。 这就是你现在的整个空间,所以所有的几率必须相对于P(A)来计算。 现在B发生的几率是什么?答案是P(AB)/P(A)

我们除以P(A),你们之间更加小心可能会想知道如果P(A) = 0会发生什么。 那么,在这种情况下,我们不会给定A发生,因为A不会发生。所以我们不必担心这种情况。

乘法规则:

这只是条件概率定义的重新排列,但它也许是所有规则中最常用的规则。

AB为两个事件。 那么他们都发生的几率是:

P(AB) = P(A) \cdot P(B \mid A)

注意答案是“小部分的小部分”。AB都发生的几率小于A发生的几率 - 事件上条件越多,发生的概率就越小。

由于AB ⊆ B,你知道P(AB)小于P(B)。你也检查一下:

P(AB) = P(B) \cdot P(A \mid B)

我们将以一些简单的例子结束本节。 下一节包含一些需要更多工作的例子。

示例 1:两张牌中的两个 A

标准牌组由 52 张牌组成,其中 4 张是 A。两张牌无放回地随机发放。

问题 1。给定第一张牌是 A,第二张牌是 A 的几率是多少?

答案 1。3/51,因为现在你的套牌有 51 张牌,其中 3 张是 A。

问题 2。两张牌都是 A 的机会是多少?

答案 2:通过乘法规则和答案 1,答案是:

\frac{4}{52} \cdot \frac{3}{51}

问题 3。如果带放回地发牌,问题 1 和问题 2 的答案如何改变?

答案 3(究竟谁带放回地发牌?仅仅在概率班里面……)在抽出第二张牌之前,你放回了牌。在这个假设下,你每次都从完全相同的牌组上进行抽取,所以:

P(\text{second card is an ace} \mid \text{first card is an ace}) = \frac{4}{52}

无论第一张牌是什么,答案都是一样的。同时:

P(\text{both aces}) = \frac{4}{52} \cdot \frac{4}{52}

注意,改变随机性的性质不会改变你是否乘以几率。你仍然在寻找交集的几率,所以你打算做乘法。假设的改变只会改变你的相乘方式。

示例 2:99 岁

根据你在 Data8 中看到的人口普查估计,2014 年美国人口为 318,857,056。 共有 9,037 名 99 岁男性和 32,791 名 99 岁女性。

问题。假设你在 2014 年从美国人口中随机挑选了一个人,那个人是 99 岁。根据这些信息,这个人是女性的几率是多少?

回答。答案自然是 99 岁中的女性百分比:

\frac{32791}{32791 + 9037} = 78.4\%

这与条件概率的定义一致,即你应该计算:

\begin{align*} P(\text{woman} \mid \text{99 years old}) &=  \frac{P(\text{woman and 99 years old})}{P(\text{99 years old})} \\ \\ &= \frac{32791\big{/}318857056}{(32791 + 9037)\big{/}318857056} \\ \\ &= \frac{32791}{32791 + 9037} = 78.4\% \end{align*}

美国整体人口数字并不需要;它可以消去。 这是条件的重要观察。当你随机抽样并且你知道你的选择位于特定的子组中时,该子组内的数字都是重要的。

给定 99 岁的年龄,这个人的女性的概率几乎是男性的四倍。但正如你在 Data 8 中看到的,在我们最年轻的居民中 - 新生儿 - 男性多于女性。

更多示例

仅仅是一个加法规则和一个乘法规则 - 这就是所需要的一切。以下是标准问题求解技巧的一些示例。

示例 1:基本方法 - 从划分开始

一个盒子包含 6 个黑巧克力和 4 个牛奶巧克力。 我随机挑选了两个,不带放回。

问题。我得到每一种的几率是多少?

回答。你会注意到这个问题没有说明第一个是黑的还是牛奶。两个都可能发生。因此,请列出事件发生的不同方式,即事件划分:

第一个是黑的然后是牛奶:根据乘法规则,几率为(6/10)·(4/9)
第一个是牛奶然后是黑的:几率为(4/10)·(6/9)

(啊!这两项是相同的!为无放回抽样中的更多这样的对称性做好准备。)

现在将两个几率相加。 答案是2·(6/10)·(4/9)

这种方法应该像呼吸一样自然。 你应该在不自然的假设下重做这个问题,即巧克力是带放回抽样的,看看什么变化了,什么保持不变。

示例 2:波利亚坛子模型

一个盒子包含b个黑球和w个白球。随机抽取一个球,然后把它放回,并放入d个同颜色更多的球。然后从坛子中随机抽出一个球。

问题 1。第一个抽出的球是黑色的几率是多少?

答案 1。不需要太多努力。

P(\text{first ball black}) = \frac{b}{b+w}

问题 2:第二个抽出的球是黑色的几率是多少?

答案 2。你自然而然会想,第一个球是什么,所以根据那个球的颜色进行划分,然后相加。基本方法再次发挥作用。

\begin{align*} P(\text{second ball black}) &= P(WB) + P(BB) \\ \\ &= \frac{w}{b+w} \cdot \frac{b}{b+w+d} ~+~ \frac{b}{b+w} \cdot \frac{b+d}{b+w+d} \\ \\ &= \frac{wb + b^2 + bd}{(b+w)(b+w+d)} \\ \\ &= \frac{b(b+w+d)}{(b+w)(b+w+d)} \\ \\ &= \frac{b}{b+w} \end{align*}

这与第一个球是黑色的几率是一样的,不管d是什么。这个规律很有趣!

问题 3:给定第一个球是黑色的,第二个球是黑色的概率是多少?

答案 3。我们已经在上面的计算中使用了它。 “随时间前进”的条件概率通常可以从问题中的信息中读出,例如:

P(\text{second ball black} \mid \text{first ball black}) = \frac{b+d}{b+w+d}

问题 4:给定第二个球是黑色的,第一个球是黑色的几率是多少?

答案 4,这种“时光倒流”的条件概率不易读出。这是除法规则的所在。

\begin{align*} P(\text{first ball black} \mid \text{second ball black}) &= \frac{P(BB)}{P(\text{second ball black})} \\ \\ &= \frac{\frac{b}{b+w} \cdot \frac{b+d}{b+w+d}}{\frac{b}{b+w}} \\ \\ &= \frac{b+d}{b+w+d} \end{align*}

这个确实取决于d,但它与答案3一样。前后颠倒似乎没有什么区别。

现在你开始明白,为什么这个规律带有着名的创始人乔治波利亚(George Polya,1887-1985)的名字。你可以继续重复这个规律 - 用d个另一个颜色的球代替抽出的球,然后再次抽出 - 获得一个过程,具有美丽和有用的属性,以便在数据进入时更新观点。我们将在课程的后面看到。

更新概率

数据改变了思想。我们可能会从世界如何运作的一系列假设开始,但随着我们收集更多数据,我们可能需要根据数据中看到的内容更新我们的观点。

观点可以通过概率来反映,而这些观点也可以在信息进入时更新。在本节中,我们将建立一个给定数据情况下的概率更新方法。我们将从一个例子开始,然后我们将更广泛地陈述该方法。

示例:真阳性

人口中有一种罕见的疾病:只有 0.4% 的人拥有它。有一种针对这种疾病的检验,用于拥有这种病的人,有 99% 的几率返回阳性结果。用于没有疾病的人,它有 99.5% 的机会返回阴性结果。总的来说,这是一个相当不错的检验。

从这个人口中随机挑选一个人。给定这个人的测试结果为阳性,这个人患病的概率有多大?

以下是我们在 Data8 中绘制的树状图,用于总结问题中的信息。

为了解决这个问题,我们将使用除法规则。 让D为患者拥有疾病的事件,并且在一些数学符号被滥用的情况下,让+成为患者测试结果为阳性的事件。 那么我们要找的是P(D | +)。按照除法规则,

P(D \mid + ) = \frac{P(D \text{ and } +)}{P(+)} = \frac{0.004 \cdot 0.99}{0.004 \cdot 0.99 + 0.996 \cdot 0.005} = 44.3\%

1
2
(.004*.99)/(0.004*.99 + 0.996*.005)
# 0.44295302013422816

贝叶斯规则

一般来说,如果整个结果空间可以划分为事件 A_1, A_2 \ldots , A_nB是一个正概率事件,那么对于每个i

这种计算称为贝叶斯规则,是一个环境下的除法规则的应用,其中事件 A_1, A_2 \ldots , A_n 可以看做“较早”阶段的结果,并且B是“较晚”阶段的结果。通过计算,我们可以求出给定较晚事件的,较早事件的“时光倒流”的条件概率,通过写出给定较早事件的,较晚事件的“随时间前进”的条件概率。

先验的影响

让我们仔细看看在我们在例子中得到的答案的数值。这有点令人不安。它说,即使这个人结果为阳性,他们患病的几率也不到 50%。这似乎很奇怪,因为测试的准确率非常高。

这不是测试或贝叶斯规则的错误。这是因为我们的前提是“这个人是随机从人群中挑选的”。这种疾病非常罕见,患有该疾病并且是阳性的人的比例,实际上比没有该疾病并且测试结果错误的人少一些。这解释了为什么随机挑选的人的答案少于 50%。

但是做疾病测试的人,通常由于他们或他们的医生认为他们应该做。在这种情况下,他们不再是“随机挑选”的人口成员。

对于这样的人,我们必须重新思考我们对随机性的假设。如果一个人认为他们可能患有这种疾病,那么他们患这种疾病的主观概率,应该大于随机成员的概率。让我们执行以下步骤,看看之前的差异有多大。

  • 我们将把疾病的“先验概率”从 0.004 改为其他值;“无疾病”的先验概率将相应做出改变。
  • 我们将保持测试准确率不变。
  • 我们将观察对于先验的不同值,给定某人是阳性,疾病的“后验概率”的变化。
1
2
3
4
5
prior = make_array(0.004, 0.01, 0.05, 0.1, 0.5)
Table().with_columns(
'Prior P(D)', prior,
'Posterior P(D|+)', (prior*0.99)/(prior*0.99 + (1-prior)*0.005)
)
先验P(D) 后验`P(D +)`
0.004 0.442953
0.01 0.666667
0.05 0.912442
0.1 0.956522
0.5 0.994975

该表格显示,给定测试结果为阳性,这个人患病的后验几率,很大程度上取决于先验。例如,如果这个人认为他们甚至有 10% 的几率患病,那么,给定他们测试为阳性,他们患病的概率会更新为 95% 以上。

三、随机变量

原文:prob140/textbook/notebooks/ch03

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

许多数据科学涉及数值变量,它的观察值取决于几率。其他值提供的变量的预测值,随机样本中观察到的不同类别个体的数量,以及自举样本的中值,仅仅是几个例子。 你在 Data8 中看到了更多例子。

在概率论中,随机变量是在结果空间上定义的数值函数。 也就是说,函数的定义域是Ω,它的值域是实数行。 随机变量通常用靠后的字母表示,如XY

结果空间上的函数

随机抽样可以看做重复的随机试验,因此许多结果空间由序列组成。代表硬币投掷两次的结果空间是:

\Omega = \{ \text{HH, HT, TH, TT} \}

如果你投掷 10 次,结果空间将包含 10 个元素的 2^10 个序列,其中每个元素是HT。手动列出结果比较痛苦,但计算机善于为我们避免这种痛苦。

乘积空间

两个集合AB的乘积是所有偶对(a, b)的集合,其中a ∈ Ab ∈ B。 这个概念正是我们需要的,用于描述代表多个试验的空间。

例如,表示一枚硬币投掷结果的空间是 Ω1 = {H,T}Ω1 与其本身的乘积是偶对的集合(H, H), (H, T), (T, H), (T, T),你可以认出这是硬币投掷的结果。 这个新空间和 Ω1 的乘积是代表三次投掷的空间,以此类推。

Python 模块itertools包含构造乘积空间的函数product。 让我们导入它。

1
from itertools import product

要了解product是如何工作的,我们将从投掷硬币的结果开始。我们正在使用make_array创建一个数组,但你可以使用任何其他方式创建数组或列表。

1
one_toss = make_array('H', 'T')

为了使用product,我们必须指定基本空间和重复次数,然后将结果转换为列表。

1
2
3
4
two_tosses = list(product(one_toss, repeat=2))
two_tosses

# [('H', 'H'), ('H', 'T'), ('T', 'H'), ('T', 'T')]

对于三次投掷,只需改变重复次数:

1
2
3
4
5
6
7
8
9
10
11
12
three_tosses = list(product(one_toss, repeat=3))
three_tosses
'''
[('H', 'H', 'H'),
('H', 'H', 'T'),
('H', 'T', 'H'),
('H', 'T', 'T'),
('T', 'H', 'H'),
('T', 'H', 'T'),
('T', 'T', 'H'),
('T', 'T', 'T')]
'''

概率空间是结果空间,带有所有结果的概率。 如果假设三次投掷的八次结果是等可能的,则概率均为 1/8:

1
three_toss_probs = (1/8)*np.ones(8)

相应的概率空间:

1
2
3
4
5
three_toss_space = Table().with_columns(
'omega', three_tosses,
'P(omega)', three_toss_probs
)
three_toss_space
omega P(omega)
['H' 'H' 'H'] 0.125
['H' 'H' 'T'] 0.125
['H' 'T' 'H'] 0.125
['H' 'T' 'T'] 0.125
['T' 'H' 'H'] 0.125
['T' 'H' 'T'] 0.125
['T' 'T' 'H'] 0.125
['T' 'T' 'T'] 0.125

乘积空间增长得非常快。 如果你投掷 5 次,将会有近 8000 种可能的结果:

1
2
6**5
# 7776

但是我们有product,所以我们仍然可以列出所有乘积! 这是一个表示 5 次骰子投掷的概率空间。

1
2
3
4
5
6
7
8
9
10
11
12
die = np.arange(1, 7, 1)

five_rolls = list(product(die, repeat=5)) # All possible results of 5 rolls

five_roll_probs = (1/6**5)**np.ones(6**5) # Each result has chance 1/6**5

five_roll_space = Table().with_columns(
'omega', five_rolls,
'P(omega)', five_roll_probs
)

five_roll_space
omega P(omega)
[1 1 1 1 1] 0.000128601
[1 1 1 1 2] 0.000128601
[1 1 1 1 3] 0.000128601
[1 1 1 1 4] 0.000128601
[1 1 1 1 5] 0.000128601
[1 1 1 1 6] 0.000128601
[1 1 1 2 1] 0.000128601
[1 1 1 2 2] 0.000128601
[1 1 1 2 3] 0.000128601
[1 1 1 2 4] 0.000128601

… (7766 rows omitted)

结果空间上的函数

假设你投掷一个骰子五次,并将你看到的点数加起来。如果这看起来不清楚,请耐心等待一会儿,你很快就会明白为什么它很有趣。

点数的总和是五个点数的结果空间Ω上的数值函数。 总和是一个随机变量。我们称它为S。然后,在形式上,

S: \Omega \rightarrow \{ 5, 6, \ldots, 30 \}

S的范围是 5 到 30 的整数,因为每个骰子至少有一个点,最多六个点。 我们也可以使用相同的符号:

\Omega \stackrel{S}{\rightarrow} \{ 5, 6, \ldots, 30 \}

从计算的角度来看,Ω的元素位于five_roll_spaceomega列中。让我们应用这个函数并创建一个更大的表格。

1
2
3
4
5
6
five_rolls_sum = Table().with_columns(
'omega', five_rolls,
'S(omega)', five_roll_space.apply(sum, 'omega'),
'P(omega)', five_roll_probs
)
five_rolls_sum
omega S(omega) P(omega)
[1 1 1 1 1] 5 0.000128601
[1 1 1 1 2] 6 0.000128601
[1 1 1 1 3] 7 0.000128601
[1 1 1 1 4] 8 0.000128601
[1 1 1 1 5] 9 0.000128601
[1 1 1 1 6] 10 0.000128601
[1 1 1 2 1] 6 0.000128601
[1 1 1 2 2] 7 0.000128601
[1 1 1 2 3] 8 0.000128601
[1 1 1 2 4] 9 0.000128601

… (7766 rows omitted)

我们现在有五次投掷的所有可能的结果,以及它的总点数。你可以看到表格的第一行显示了尽可能少的点数,对应于所有投掷都显示 1 点。 第 7776 行显示了最大的:

1
five_rolls_sum.take(7775)
omega S(omega) P(omega)
[6 6 6 6 6] 30 0.000128601

S的所有其他值都在这两个极端之间。

随机变量的函数

随机变量是Ω上的数值函数。 因此,通过复合,随机变量的数值函数也是随机变量。

例如,S^2 是一个随机变量,计算如下:

S^2(\omega) = \big{(} S(\omega)\big{)}^2

所以 S^2(\text{[6 6 6 6 6]}) = 30^2 = 900

S确定的事件

从表five_rolls_sum中,很难判断有多少行显示 6 或 10 或其他任何值。 为了更好地理解S的属性,我们必须组织five_rolls_sum中的信息。

对于S中的任何子集A,定义事件{S∈A}为:

\{S \in A \} = \{\omega: S(\omega) \in A \}

在特殊情况下尝试这个定义。令A = {5,30}。 然后{S∈A},当且仅当所有点数都是 1 点或 6 点。 所以:

\{S \in A\} = \{\text{[1 1 1 1 1], [6 6 6 6 6]}\}

询问总和是否为某个特定值的几率是很自然的,例如 10。读取表格并不容易,但我们可以访问相应的行:

1
five_rolls_sum.where('S(omega)', are.equal_to(10))

… (116 rows omitted)

S(ω)=10ω有 126 个值。由于所有的ω都相同,因此S的值为 10 的几率是 126/7776。

非正式情况下,我们通常会用符号表示,写成{S = 10}而不是{S∈{10}}

分布

我们的空间是骰子的五次投掷的结果,而我们的随机变量S是五次投掷的点数总数。

1
five_rolls_sum
omega S(omega) P(omega)
[1 1 1 1 1] 5 0.000128601
[1 1 1 1 2] 6 0.000128601
[1 1 1 1 3] 7 0.000128601
[1 1 1 1 4] 8 0.000128601
[1 1 1 1 5] 9 0.000128601
[1 1 1 1 6] 10 0.000128601
[1 1 1 2 1] 6 0.000128601
[1 1 1 2 2] 7 0.000128601
[1 1 1 2 3] 8 0.000128601
[1 1 1 2 4] 9 0.000128601

… (7766 rows omitted)

在最后一节中,我们找到了P(S = 10)。我们可以使用相同的过程,为每个可能的s值查找P(S = s)group方法允许我们在同一时间为所有s这样做。

为此,我们首先丢掉omega列。 然后,我们将按S(omega)的不同值对表格进行分组,并使用sum来将每组中的所有概率相加。

1
2
dist_S = five_rolls_sum.drop('omega').group('S(omega)', sum)
dist_S
S(omega) P(omega) sum
5 0.000128601
6 0.000643004
7 0.00192901
8 0.00450103
9 0.00900206
10 0.0162037
11 0.0263632
12 0.0392233
13 0.0540123
14 0.0694444

… (16 rows omitted)

该表格显示了所有可能的S值及其所有概率。它被称为S的概率分布表。

表中的内容 - 随机变量的所有可能值及其所有概率 - 称为S的概率分布,或者简称为S的分布。该分布显示了 100% 的总概率如何分布在S的所有可能值上。

让我们来检查一下,以确保结果空间中的所有ω都已经在概率一列中得到了解释。

1
2
3
dist_S.column(1).sum()

# 0.99999999999999911

它在计算环境中是 1。这是任何概率分布的一个特征:

分布的概率是非负的,总和为 1。

展示分布

在 Data8 中,你使用datascience库来处理数据分布。prob140库建立在它上面,为处理概率分布和事件提供了一些便利的工具。

首先,我们将构造一个概率分布对象,虽然它看起来非常像上面的表格,但它的第二列中预计会有概率分布,并且如果它发现了其他任何东西,就会报错。

为了使代码易于阅读,让我们以数组的形式分别提取可能的值和概率:

1
2
s = dist_S.column(0)
p_s = dist_S.column(1)

要将这些转换为概率分布对象,请从空表开始,然后使用表的valuesprobability方法。values的参数是可能值的列表或数组,而probability的参数是相应概率的列表或数组。

1
2
dist_S = Table().values(s).probability(p_s)
dist_S
Value Probability
5 0.000128601
6 0.000643004
7 0.00192901
8 0.00450103
9 0.00900206
10 0.0162037
11 0.0263632
12 0.0392233
13 0.0540123
14 0.0694444

… (16 rows omitted)

除了列标签更具可读性之外,这看起来与我们之前的表完全相同。但是这是好处:在直方图中展示分布,只需使用prob140Plot方法,如下。

1
Plot(dist_S)

Plot的注解

  • 回想一下,datascience库中的hist显示原始数据的直方图,包含在表格的列中。prob140库中的Plot显示概率直方图,基于概率分布作为输入。

  • Plot仅适用于概率分布对象,使用valuesprobability方法创建的。 它不适用于Table类的普通成员。

  • Plot适用于具有整数值的随机变量。 你将在接下来的几章中遇到的许多随机变量是整数值。 为了展示其他随机变量的分布,分箱决策更加复杂。

S的分布的注解

在这里,五次投掷的点数总和的分布曲线出现了钟形。 注意这个直方图和你在 Data 8 中看到的钟形分布之间的差异。

这个显示确切的分布。它是根据实验的所有可能结果进行计算的。这不是一个近似值也不是一个经验直方图。

Data8 中的中心极限定理的表述表明,大型随机样本总和的分布大致是正态的。但是在这里你看到的只是五次投掷的总和呈现钟形分布。如果你从均匀的分布开始(这是单次投掷的分布),那么在总和的概率分布变成正态之前,你不需要大型样本。

展示事件的概率

从 Data8 中可知,钟形曲线拐点之间的区间约占曲线面积的 68%。 虽然上面的直方图并不完全是一个钟形曲线 - 它是一个只有 26 个条形的离散直方图 - 但它非常接近。 拐点似乎大约是 14 和 21。

Plotevent参数可让你可视化事件的概率,如下所示。

1
Plot(dist_S, event = np.arange(14, 22, 1))

金色区域是P(14 <= S <= 21)

prob_event方法操作概率分布对象,来返回事件的概率。为了找到P(14 <= S <= 21),请按如下所示使用它。

1
2
3
dist_S.prob_event(np.arange(14, 22, 1))

# 0.6959876543209863

几率是 69.6%,离 68% 并不远。

数学和代码的对应

P(14 <= S <= 21)可以通过将事件划分为 14 到 21 范围内的事件{S = s}的并集,然后使用加法规则来找到。

P(14 \le S \le 21) = \sum_{s = 14}^{21} P(S = s)

请小心使用小写字母s作为通用可能值,与大写字母S作为随机变量相对应;不这样做会使公式含义非常混乱。

这意味着:

首先为 14 到 21 范围内的每个s值抽取事件{S = s}

1
2
event_table = dist_S.where(0, are.between(14, 22))
event_table
Value Probability
14 0.0694444
15 0.0837191
16 0.0945216
17 0.100309
18 0.100309
19 0.0945216
20 0.0837191
21 0.0694444

然后将所有这些事件的概率相加。

1
2
3
event_table.column('Probability').sum()

# 0.6959876543209863

prob_event方法一步完成所有这些。 在这里再次进行比较。

1
2
3
dist_S.prob_event(np.arange(14, 22, 1))

# 0.6959876543209863

你可以通过各种方式,使用相同的基本方法来查找由S确定的任何事件的概率。这里有两个例子。

示例 1:P(S^2 = 400) = P(S = 20) = 8.37\%

示例 2:P(S > 20) = \sum_{s=20}^{30} P(S = s)

一个查找数值的简便方法:

1
2
dist_S.prob_event(np.arange(20, 31, 1))
# 0.30516975308642047

示例 3:P(\big{\vert} S - 10 \big{|} \le 6) ~ = ~ P(4 \le S \le 16) ~ = ~ \sum_{s=4}^{16} P(S=s)

1
2
dist_S.prob_event(np.arange(4, 17, 1))
# 0.39969135802469169

相等性

我们知道两个数字相等意味着什么。 然而,随机变量的相等可能不止一种。

相同

如果相同结果空间上定义的两个随机变量XY的值,对于空间中的每个结果都是相同的,那么它们是相同的。符号X = Y意味着 X(\omega) = Y(\omega) \text{ for all } \omega \in \Omega。非正式来说,无论结果如何, 如果X是10,那么Y也必须是 10;如果X是11,Y必须是 11,依此类推。

一个例子会把它说清楚。 假设 N_H 是三次硬币投掷的正面数量,并且 N_T 是相同的三次投掷的背面数量。 那么两个随机变量 N_H3 - N_T 是相等的。 对于三次投掷的每一种可能结果,N_H 的值等于 3 - N_T 的值。

我们简单地写成 N_H = 3 - N_T

同分布

如上所述,N_HN_T 不相等。例如,

然而,有一种感觉是,正面数量与背面数量“以相同的方式出现”。两个随机变量具有相同的概率分布。

结果空间是three_tosses

1
2
3
4
5
6
7
8
9
10
11
12
13
coin = make_array('H', 'T')
three_tosses = list(product(coin, repeat=3))
three_tosses
'''
[('H', 'H', 'H'),
('H', 'H', 'T'),
('H', 'T', 'H'),
('H', 'T', 'T'),
('T', 'H', 'H'),
('T', 'H', 'T'),
('T', 'T', 'H'),
('T', 'T', 'T')]
'''

只有 8 个结果,因此很容易检查上表并写出 N_HN_T 的分布。它们都取值为 0, 1, 2 和 3,概率分别为 1/8,3/8,3/8 和 1/8。该分布如下表所示。

1
2
dist = Table().values(np.arange(4)).probability(make_array(1, 3, 3, 1)/8)
dist
Value Probability
0 0.125
1 0.375
2 0.375
3 0.125

我们说 N_HN_T 是同分布的。

一般而言,如果两个随机变量具有相同的概率分布,则它们是同分布的。 这表示为 X \stackrel{d}{=} Y

相等性之间的关系

相同比同分布更强。如果两个随机变量在结果层面上相同,那么它们必须具有相同的分布,因为它们在结果空间上是相同的函数。

也就是说,对于任意两个随机变量XYX = Y \implies X \stackrel{d}{=} Y

但三次投掷的正面和反面的例子表明,反面不一定是正确的。

示例:来自小牌组的两张牌

一个牌组包含 10 张牌,分别标记为1,2,2,3,3,3,4,4,4,4。两张牌是不放回随机发放的。让 X_1 为第一张卡上的标记,X_2 为第二张卡上的标记。

问题 1。X_1X_2 是否相同?

答案是否定的,因为结果可能是 31,在这种情况下 X_1 = 3X_2 = 1

问题 2。X_1X_2 是否同分布?

回答 2。让我们找到两个分布并进行比较。显然,每种情况下可能的值是 1,2,3 和 4。X_1 的分布很简单:P(X_1 = i ) = \frac{i}{10} , ~~ i = 1, 2, 3, 4。当分布由这样的公式定义时,你可以定义一个函数来表示公式所说的内容:

1
2
def prob1(i):
return i/10

然后,你可以像之前一样,使用value创建一个概率分布对象,但现在使用probability_function,它将函数的名称作为其参数:

1
2
3
possible_i = np.arange(1, 5, 1)
dist_X1 = Table().values(possible_i).probability_function(prob1)
dist_X1
Value Probability
1 0.1
2 0.2
3 0.3
4 0.4

相信下面的函数prob2会为每个i返回P(X_2 = i)。事件已根据 X_1 的值进行划分。

1
2
3
4
5
def prob2(i):
if i == 1:
return (9/10)*(1/9)
else:
return (i/10)*((i-1)/9) + ((10-i)/10)*(i/9)
1
2
dist_X2 = Table().values(possible_i).probability_function(prob2)
dist_X2
Value Probability
1 0.1
2 0.2
3 0.3
4 0.4

这两个分布是相同的!这是另一个不放回抽样的对称性的例子。 结论是 X_1 \stackrel{d}{=} X_2