做出决策

贝叶斯法则的一个主要用途是基于不完整的信息做出决策,并在新信息到来时将其纳入考虑。本节指出了在做出决策时牢记假设的重要性。

[In ]:
import matplotlib
from datascience import *
path_data = '../../../assets/data/'
%matplotlib inline
import matplotlib.pyplot as plots
import numpy as np
plots.style.use('fivethirtyeight')
[In ]:
def population(prior_prob_disease):
    n_d = int(prior_prob_disease*100000)
    n_nd = 100000 - n_d
    n_pos_d = int(0.99*n_d)
    n_neg_d = n_d - n_pos_d
    n_pos_nd = int(0.005*n_nd)
    n_neg_nd = n_nd - n_pos_nd
    condition = np.array(['Disease']*n_d + ['No Disease']*n_nd)
    d_test = np.array(['Positive']*n_pos_d + ['Negative']*n_neg_d)
    nd_test = np.array(['Positive']*n_pos_nd + ['Negative']*n_neg_nd)
    test = np.append(d_test, nd_test)
    t = Table().with_columns(
        'True Condition', condition,
        'Test Result', test
    )
    return t

许多疾病医学检测会返回阳性或阴性结果。阳性结果意味着,根据检测,患者患有该疾病。阴性结果意味着检测结论是患者没有患病。

医学检测经过精心设计,非常准确。但很少有检测能达到 100% 的准确率。几乎所有检测都会犯两种类型的错误:

  • 假阳性 是检测得出阳性结论但患者并未患病的错误。

  • 假阴性 是检测得出阴性结论但患者确实患病的错误。

这些错误可能会影响人们的决策。假阳性可能引起焦虑和不必要的治疗(在某些情况下,治疗可能昂贵或危险)。如果患者因为阴性检测结果而没有接受治疗,假阴性可能产生更严重的后果。

罕见疾病的检测

假设有一个大的人群,某种疾病侵袭了该人群中很小的一部分。下面的树状图总结了关于这种疾病以及针对它的医学检测的信息。

树状图的第一个分支 0.004 指向“患病”,0.996 指向“未患病”。从“患病”出发,另一个分支中 0.99 指向“检测阳性”,0.01 指向“检测阴性”。从“未患病”出发,也有另一个分支,其中 0.005 指向“检测阳性”,0.995 指向“检测阴性”。

总体而言,人群中只有千分之四的人患有该疾病。检测非常准确:假阳性率非常低,为千分之五;假阴性率稍高(但仍然很低),为百分之一。

个体可能知道也可能不知道自己是否患病;通常,人们通过检测来了解自己是否患病。

因此,假设从人群中随机选择一个人进行检测。如果检测结果为阳性,你会如何分类他们:患病,还是未患病?

我们可以通过应用贝叶斯法则和使用我们的“可能性较大”分类器来回答这个问题。在已知检测结果为阳性的情况下,他或她患病的概率是顶部分支相对于检测阳性分支总比例的比例。

[In ]:
(0.004 * 0.99)/(0.004 * 0.99  +  0.996*0.005 )
0.44295302013422816

在已知检测结果为阳性的情况下,他或她患病的概率约为 44%。因此,我们将他们分类为:未患病。

这是一个奇怪的结论。我们有一个相当准确的检测,一个人检测结果为阳性,而我们的分类是……他们没有患病?这似乎毫无道理。

面对一个令人不安的答案,首先要做的是检查计算。上面的算术是正确的。让我们看看能否以不同的方式得到相同的答案。

函数 population 返回 100,000 名患者的结果表,列显示“真实状况”和“检测结果”。检测与树中描述的相同。但患病比例是函数的参数。

我们将以 0.004 为参数调用 population,然后进行透视以对 100,000 人中的每个人进行交叉分类。

[In ]:
population(0.004).pivot('Test Result', 'True Condition')
True Condition | Negative | Positive
Disease        | 4        | 396
No Disease     | 99102    | 498

表中的单元格具有正确的计数。例如,根据对人群的描述,每 1000 人中有 4 人患病。表中有 100,000 人,因此应该有 400 人患病。这正是表所显示的:4 + 396 = 400。在这 400 人中,99% 获得阳性检测结果:0.99 x 400 = 396。

在阳性结果中,患病的比例为:

[In ]:
396/(396 + 498)
0.4429530201342282

这就是我们通过贝叶斯法则得到的答案。阳性列中的计数显示了为什么它小于 1/2。在阳性结果中,没有患病的人多于患病的人。

原因是,首先,人群中很大一部分人没有患病。那些假阳性的人虽然比例很小,但数量仍然大于真阳性的人数。这在树状图中更容易可视化:

树状图的第一个分支 0.004 指向“患病”,0.996 指向“未患病”。从“患病”出发,另一个分支中 0.99 指向“检测阳性”,0.01 指向“检测阴性”。从“未患病”出发,也有另一个分支,其中 0.005 指向“检测阳性”,0.995 指向“检测阴性”。

  • 真阳性的比例是人群中很小一部分(0.004)的很大一部分(0.99)。
  • 假阳性的比例是人群中很大一部分(0.996)的很小一部分(0.005)。

这两个比例具有可比性;第二个略大一些。

因此,在给定随机选择的人检测呈阳性的情况下,我们将他们分类为更可能没有患病是正确的。

主观先验概率

正确并不总是令人满意。对于如此准确的检测,将阳性患者分类为未患病似乎还是有点不对。既然计算是正确的,让我们来看看我们概率计算的基础:随机性假设。

我们的假设是,一个随机选择的人接受了检测并得到了阳性结果。但这在现实中不会发生。人们去接受检测是因为他们认为自己可能患病,或者因为他们的医生认为他们可能患病。接受检测的人并不是随机选择的人群成员。

这就是为什么我们对人们接受检测的直觉与我们得到的答案不太吻合的原因。我们想象的是一个现实情况,即患者因为有某种原因而去做检测,而计算是基于一个随机选择的人接受检测。

因此,让我们在更现实的假设下重新进行计算:患者接受检测是因为医生认为患者有可能患病。

这里需要注意的是,“医生认为有可能”意味着这个概率是医生的意见,而不是人群中的比例。这被称为主观概率。在我们关于患者是否患病的情境中,它也是一个主观先验概率。

一些研究者坚持认为所有概率都必须是相对频率,但主观概率比比皆是。候选人赢得下一次选举的概率、未来十年湾区发生大地震的概率、某个国家赢得下一届世界杯的概率:这些都不是基于相对频率或长期频率。每个都包含主观因素。因此,所有涉及它们的计算也带有主观因素。

假设医生的主观意见是患者有 5% 的概率患病。那么树状图中只有先验概率会改变:

树状图的第一个分支 0.05 指向“患病”,0.95 指向“未患病”。从“患病”出发,另一个分支中 0.99 指向“检测阳性”,0.01 指向“检测阴性”。从“未患病”出发,也有另一个分支,其中 0.005 指向“检测阳性”,0.995 指向“检测阴性”。

在已知患者检测结果为阳性的情况下,他或她患病的概率由贝叶斯法则给出。

[In ]:
(0.05 * 0.99)/(0.05 * 0.99  +  0.95 * 0.005)
0.9124423963133641

改变先验概率的效果令人震惊。尽管医生认为患者患病的先验概率相当低(5%),但一旦患者检测结果为阳性,患病的后验概率飙升至超过 91%。

如果患者检测结果为阳性,医生按照患者患病的情况进行后续处理将是合理的。

确认答案

尽管医生的意见是主观的,但我们可以生成一个人工人群,其中 5% 的人患病,并使用相同的检测方法进行检测。然后,我们可以统计不同类别的人数,看看这些计数是否与使用贝叶斯法则得到的答案一致。

我们可以使用 population(0.05)pivot 来构建对应的人群,并查看四个单元格中的计数。

[In ]:
population(0.05).pivot('Test Result', 'True Condition')
True Condition | Negative | Positive
Disease        | 50       | 4950
No Disease     | 94525    | 475

在这个人工创建的 100,000 人中,5000 人(5%)患病,其中 99% 检测为阳性,产生 4950 个真阳性。与 475 个假阳性相比:在阳性结果中,患病的比例与通过贝叶斯法则得到的结果相同。

[In ]:
4950/(4950 + 475)
0.9124423963133641

因为我们可以生成一个具有正确比例的人群,所以我们也可以使用模拟来确认我们的答案是合理的。表 pop_05 包含一个以医生先验患病概率 5% 和检测错误率生成的 100,000 人人群。我们从人群中抽取一个大小为 10,000 的简单随机样本,并提取表 positive,仅包含样本中检测结果为阳性的人。

[In ]:
pop_05 = population(0.05)

sample = pop_05.sample(10000, with_replacement=False)

positive = sample.where('Test Result', are.equal_to('Positive'))

在这些阳性结果中,真阳性的比例是多少?即阳性结果中患病的比例:

[In ]:
positive.where('True Condition', are.equal_to('Disease')).num_rows/positive.num_rows
0.9218181818181819

运行这两个单元格几次,你会看到阳性结果中真阳性的比例在我们通过贝叶斯法则计算的 0.912 附近波动。

你也可以使用不同的参数调用 population 函数来改变先验患病概率,并观察后验概率如何受到影响。