深度解析机器学习中的置信区间(附代码)

机器学习很多时候需要估计某个算法在未知数据上的性能。

置信区间是一种对估计不确定性的量化方法,它们可以用来在总体参数(例如平均值mean,就是从总体中的一个独立观测样本上估计而来)上添加一个界限或者可能性。

在这篇教程中,你会了解置信区间以及如何在实践中计算置信区间。

学完本教程后,你会明白:

置信区间是总体参数估计的一个界限
我们可以直接计算分类方法估计能力的置信区间
任意总体统计的置信区间都可以用bootstrap以一种分布无关法(distribution-free)进行估计

我们开始吧。

教程概览

本教程分为3个部分:

什么是置信区间
分类精度(accuracy)的置信区间
非参数(Nonparametric)置信区间

什么是置信区间


置信区间是总体变量估计的界限,它是一个区间统计量,用于量化估计的不确定性。

深度解析机器学习中的置信区间(附代码)

置信区间与容忍区间(tolerance interval)不同,后者描述从分布中采样的数据的边界。它也不同于描述单一观察值边界的预测区间(prediction interval)。相反,对于总体参数,如平均值,标准差等等,置信区间提供了一个界限。

在应用机器学习中,我们可能想在展示一个预测模型的能力时使用置信区间。

例如,置信区间可以用来呈现分类模型的性能,可以这样描述:给定样本,范围x到y覆盖真实模型精度的可能性为95%。或者,在95%的置信水平下,模型精度是x+/-y。

置信区间也能在回归预测模型中用于呈现误差,例如:范围x到y覆盖模型真实误差的可能性有95%。或者,在95%的置信水平下,模型误差是x+/-y。

选择95%的置信度在展现置信区间时很常见,但是其他不那么常见的值也会被使用,比如90%和99.7%。实践中,你可以使用任何喜欢的值。

深度解析机器学习中的置信区间(附代码)

95%的置信区间(CI)是根据我们的数据计算出的值区间,很可能包括我们对总体估计的真实值。
---Page 4, Introduction to the New Statistics: Estimation, Open Science, and Beyond, 2016.

置信区间的价值在于它能够量化估计的不确定性。它提供了一个下限和上限以及一个可能性。作为单独的半径测量,置信区间通常被称为误差范围,并可通过使用误差图来图形化地表示估计的不确定性。

通常,得出估计的样本越大,估计就越精确,置信区间也越小(越好)。

更小的置信区间:更精确的估计
更大的置信区间:不太精确的估计

深度解析机器学习中的置信区间(附代码)

也可以说,CI透露给我们估计的精确程度,而误差范围是精度的衡量标准。一个短的CI意味着小的误差范围,说明我们有一个相对精确的估计[…],一个长的CI意味着大的误差范围,说明我们精度较低
---page 4, Introduction to the New Statistics: Estimation, Open Science, and Beyond, 2016

置信区间属于称为估计统计(estimation statistics)的统计学领域,估计统计用于表示和解释实验结果,可以替代或补充统计显著性检验。

深度解析机器学习中的置信区间(附代码)

估计提供了一种信息量更大的方式来分析和解释结果。[…]了解和思考一个影响的大小和精度对于定量科学而言更有用,而不是先假设完全没有影响,再考虑观察到极值数据的概率。
---Estimation Statistics should replace Significance testing, 2016

在实践中,比起统计显著性检验,置信区间可能更受偏爱。

原因是它们更容易让从业人员和利益相关者直接与具体领域相关联。它们也可以被解释并用于比较机器学习模型。

深度解析机器学习中的置信区间(附代码)

这些不确定性估计在两方面有帮助。首先,区间让模型的使用者了解模型的好坏。[…]这样一来,在比较不同模型时置信区间可以用于衡量证据的权重。置信区间的第二个好处是便于模型之间的权衡。如果两个模型的置信区间明显重叠,就表明两者之间存在(统计)等价性,并可能提供理由来支持更简洁或者更容易解释的模型。
---Page 416, Applied Predictive Modeling, 2013.

现在我们已经知道了什么是置信区间,让我们看几种给预测模型计算置信区间的方法。

分类精度的置信区间

分类问题是指给定一些输入数据,预测它们的标签或者类别结果变量。

通常用分类准确率(accuracy)或分类误差(Error,与准确率相反)来描述分类预测模型的性能。例如,如果一个模型在75%的情况中对类别结果做出了正确预测,则模型的分类准确率为75%,计算公式如下:

accuracy = total correct predictions / total predictions made * 100

该准确率可以用模型从未见过的数据集计算,例如验证集或测试集。

分类准确率或分类误差是一个比例。它描述了模型所做的正确或错误预测的比例。每个预测都是一个二元决策,可能正确也可能错误。在技术上,这种方法被称为伯努利审判(Bernoulli trial),因Jacob Bernoulli命名。伯努利审判中的比例具有一种特定的分布,被称为二项分布。值得庆幸的是,对于大样本量(例如超过30),我们可以用高斯分布近似。

深度解析机器学习中的置信区间(附代码)

在统计学中,一系列成功或失败的独立事件称为伯努利过程。 [...]对于大N,这个随机变量的分布接近正态分布。
---Page 148, Data Mining: Practical Machine Learning Tools and Techniques, Second Edition, 2005

我们可以使用比例(即分类准确度或误差)的高斯分布假设来轻松地计算置信区间。

在分类误差的情况下,区间半径可以这样计算:

interval = z * sqrt( (error * (1 - error)) / n)

在分类准确率的情况,这样计算:

interval = z * sqrt( (accuracy * (1 - accuracy)) / n)

公式中的interval是置信区间的半径,error和accuracy是分类误差和分类准确率,n是样本大小,sqrt是平方根函数,z是高斯分布的临界值。用术语表述,这就是二项式比例置信区间。

高斯分布中常用的临界值及其相应的显着性水平如下:

1.64(90%)
1.96(95%)
2.33(98%)
2.58(99%)

考虑在一个有50个样本的验证集上(n=50)误差为20%的模型(error=0.2),我们可以这样计算95%的置信区间(z=1.96):

# binomial confidence interval
from math import sqrt
interval = 1.96 * sqrt( (0.2 * (1 - 0.2)) / 50)
print('%.3f' % interval)

运行该示例,我们看到计算和打印的置信区间半径。

0.111

然后我们可以做出如下的声明:

该模型的分类误差为20%+/-11%
模型的真实分类误差可能在9%到31%之间

我们可以看到样本量对置信区间半径估计精度的影响。

# binomial confidence interval
interval = 1.96 * sqrt( (0.2 * (1 - 0.2)) / 100)
print('%.3f' % interval)

运行上述示例显示置信区间下降到了7%左右,从而提高了模型性能估计的精度。

0.078

请记住,置信区间是一个范围的可能性。 真正的模型性能可能在这个范围之外。

深度解析机器学习中的置信区间(附代码)

事实上,如果我们一遍一遍地重复这个实验,每次采集一个包含新示例的新样本S,我们会发现对于这些实验的大约95%来说,计算的区间将覆盖真实误差。出于这个原因,我们把这个区间称为95%置信区间估计
---Page 131, Machine Learning, 1997
Proportion_confint() statsmodels函数是二项比例置信区间的一个实现

默认情况下,它对二项分布进行高斯假设,但是对其他更复杂的计算变种也支持。 该函数将成功次数(或失败次数)、试验总数以及显著性水平作为参数,并返回置信区间的上下界。

下面的例子在假设的情况下演示了这个函数,其中一个模型从100个实例的数据集中做出88个正确的预测,并且我们对95%的置信区间(作为0.05的显著性供给函数)感兴趣。

from statsmodels.stats.proportion import proportion_confint
lower, upper = proportion_confint(88, 100, 0.05)
print('lower=%.3f, upper=%.3f' % (lower, upper))

运行示例输出模型分类准确率的上下界:

lower=0.816, upper=0.944

非参数置信区间

通常我们不知道所选性能指标的分布情况。或者,我们可能不知道计算
性能分数置信区间的分析方法。

深度解析机器学习中的置信区间(附代码)

参数型置信区间的假设经常不成立。预测变量有时不是正态分布的,即使是,正态分布的方差在预测变量的所有等级上可能也不相同。
---Page 326, Empirical Methods for Artificial Intelligence, 1995.

在这些情况下,bootstrap重采样方法可以用作计算置信区间的非参数方法,名义上称为bootstrap置信区间。

bootstrap是一种模拟蒙特卡罗方法,其中样本是从固定的有限数据集中有放回的抽取出来的,并且在每个样本上估计一个参数。该过程通过采样得到了对真实总体参数的一个健壮的(robust)估计。

可以用下面的伪代码来证明这一点:

statistics = []
for i in bootstraps:
sample = select_sample_with_replacement(data)
stat = calculate_statistic(sample)
statistics.append(stat)

这个过程可用于估计预测模型的性能,通过在每个样本上拟合模型并估计模型在未包含于这些样本中的样本上的性能。然后可以将平均值或中位数性能视作该模型在未知数据上的性能估计。

可以通过从特定百分位数的性能分数样本中选择观察值,将置信区间添加到此估计值中。

回想一下,百分位数是从排序好的样本中抽取的观测值,其中有相应百分比的样本观测值比它小。例如,样本的70百分位表示70%的样本低于该值。50百分位数是分布的中位数。

首先,我们必须选择置信水平的显著性水平,例如95%,表示为5.0%(例如100-95)。由于置信区间是围绕中位数对称的,我们必须选择2.5百分位和97.5百分位的观察值来给出整个范围。

我们可以通过一个实例来计算bootstrap置信区间。

假设我们有一个由均匀分布产生的数据集,其中包含1,000个观察值在0.5到1.0之间。

# generate dataset
dataset = 0.5 + rand(1000) * 0.5

我们将执行100次bootstrap过程,并从数据集中有放回的抽取1000个观测样本。 我们将把在bootstrap样本上计算的统计量作为总体平均值的估计。这很容易成为一个模型的评估。

# bootstrap
scores = list()
for _ in range(100):
# bootstrap sample
indices = randint(0, 1000, 1000)
sample = dataset[indices]
# calculate and store statistic
statistic = mean(sample)
scores.append(statistic)

一旦我们获得了bootstrap统计的样本,我们就可以计算出中心趋势。因为不对分布做任何假设,我们将使用中位数或50百分位数。

print('median=%.3f' % median(scores))

然后我们可以计算置信区间作为以中位数为中心的观察统计值的中间95%。

# calculate 95% confidence intervals (100 - alpha)
alpha = 5.0

首先,基于所选择的置信区间来计算较低的百分位数。然后从bootstrap统计的样本中提取出这个百分位的观察值。

# calculate lower percentile (e.g. 2.5)
lower_p = alpha / 2.0
# retrieve observation at lower percentile
lower = max(0.0, percentile(scores, lower_p))

我们对置信区间的上界做同样的事情。

# calculate upper percentile (e.g. 97.5)
upper_p = (100 - alpha) + (alpha / 2.0)
# retrieve observation at upper percentile
upper = min(1.0, percentile(scores, upper_p))

下面列出了完整的示例。

# bootstrap confidence intervals
from numpy.random import seed
from numpy.random import rand
from numpy.random import randint
from numpy import mean
from numpy import median
from numpy import percentile
# seed the random number generator
seed(1)
# generate dataset
dataset = 0.5 + rand(1000) * 0.5
# bootstrap
scores = list()
for _ in range(100):
# bootstrap sample
indices = randint(0, 1000, 1000)
sample = dataset[indices]
# calculate and store statistic
statistic = mean(sample)
scores.append(statistic)
print('50th percentile (median) = %.3f' % median(scores))
# calculate 95% confidence intervals (100 - alpha)
alpha = 5.0
# calculate lower percentile (e.g. 2.5)
lower_p = alpha / 2.0
# retrieve observation at lower percentile
lower = max(0.0, percentile(scores, lower_p))
print('%.1fth percentile = %.3f' % (lower_p, lower))
# calculate upper percentile (e.g. 97.5)
upper_p = (100 - alpha) + (alpha / 2.0)
# retrieve observation at upper percentile
upper = min(1.0, percentile(scores, upper_p))
print('%.1fth percentile = %.3f' % (upper_p, upper))

运行示例总结了bootstrap样本统计的分布,包括2.5,50(中位数)和97.5百分位数。

50th percentile (median) = 0.750
2.5th percentile = 0.741
97.5th percentile = 0.757

然后,我们可以使用这些观察结果对样本分布做出声明,例如:

有95%的可能性以0.741至0.757的范围涵盖了真实的统计中位数。

扩展

本节列出了一些有帮助的想法,如果您希望对本教程内容扩展:

在您自己的小型测试数据集上测试每个置信区间方法。
查阅3篇论文,它们展示了置信区间的不同使用方法
编写一个函数来计算给定的机器学习模型性能分数样本的bootstrap置信区间。

进一步阅读

如果您希望深入了解,本节提供了有关该主题的更多资源。

Posts

How to Report Classifier Performance with Confidence Intervals
How to Calculate Bootstrap Confidence Intervals For Machine Learning Results in Python
Understand Time Series Forecast Uncertainty Using Confidence Intervals with Python

Books

Understanding The New Statistics: Effect Sizes, Confidence Intervals, and Meta-Analysis, 2011.
Introduction to the New Statistics: Estimation, Open Science, and Beyond, 2016.
Statistical Intervals: A Guide for Practitioners and Researchers, 2017.
Applied Predictive Modeling, 2013.
Machine Learning, 1997.
Data Mining: Practical Machine Learning Tools and Techniques, Second Edition, 2005.
An Introduction to the Bootstrap, 1996.
Empirical Methods for Artificial Intelligence, 1995.

Papers

Estimation statistics should replace significance testing, 2016.
Bootstrap Confidence Intervals, Statistical Science, 1996.

API

statsmodels.stats.proportion.proportion_confint() API
numpy.random.rand() API
numpy.random.randint() API
numpy.random.seed() API
numpy.percentile() API
numpy.median() API

Articles

Interval estimation on Wikipedia
Confidence interval on Wikipedia
Binomial proportion confidence interval on Wikipedia
Confidence interval of RMSE on Cross Validated
Bootstrapping on Wikipedia

总结

在本教程中,你探索了置信区间以及如何在实践中计算置信区间。

具体来说,你学会了:

置信区间是总体参数估计的界限。
可以直接计算分类方法的估计性能的置信区间
任何总体统计数据的置信区间都可以使用bootstrap以分布无关方式进行估算。

原文发布时间为:2018-07-02
本文作者:Jason Brownlee
本文来自云栖社区合作伙伴“数据派THU”,了解相关信息可以关注“数据派THU”。

上一篇:python编程-19:Office编程及相关库


下一篇:Android自定义线程池的编程实战