kaggle较量里常常会产生shake up的景象,说的间接点就是在有切榜或多榜单的较量中,可能存在榜单排名强烈触动的状况,例如上面这个例子:Data Science Bowl 2017

咱们看到,第一名是从公榜回升了130多名,而第5名则回升了349.

公榜后果就是好的模型私榜不肯定就好,因为Kaggle是模仿real world的时刻在变动的数据,不肯定听从过来的法则,用过来的数据是无奈确定就能预测将来的。个别状况下shake的起因能够归为如下几种:1.数据不同散布2.数据量太小3.异样值影响较大4.metric过于敏感5.模型太靠近6.overfit等。那么第一名中的模型与第二名中的模型之间有什么区别呢?

如果你的答案是:“区别在于,第一款模型比第二型模型更好,因为它具备较小的损失”,那么这个答复就太仓促了。事实上,

咱们如何能力确定测试集上更好的度量规范象征的是更好的模型,而不是一个更侥幸的模型呢?

对于数据科学家来说,晓得模型抉择中哪一部分是偶尔施展的作用是一项基本技能。在本文中,咱们将阐明如何量化抉择最佳模型过程中波及的随机性。

什么是“最好模型”?

首先,咱们须要明确定义所说的“最佳模型”。

假如有两个模型A和B,咱们想抉择最好的一个。最好的模型是在看不见的数据上体现最好的模型,这个应该是一个公认的判断形式

所以咱们收集了一些测试数据(在训练期间没有应用的),并在此基础上评估我模型。假如模型A的ROC值为86%,模型B为85%。这是否意味着模型A比模型B更好?就目前咱们把握的信息而言:是的。

但在一段时间之后,又收集了更多的数据并将其增加到测试集中。当初模型A依然是86%,但模型B减少到87%。那么当初来说,B比A好了,对吧

所以能够定义如下:

对于一个给定的工作,最好的模型是在所有可能的不可见数据上体现最好的模型。

这个定义的重要局部是“所有可能”。咱们可能拜访的数据是无限的,所以测试数据集只是所有可能的不可见数据的一小部分。这就像是说咱们永远都不晓得什么才是最好的模型!

为了解决这个问题,咱们须要一个新的概念。

Universe

咱们将将所有可能的看不见数据的汇合称为“Universe”。在事实世界中,咱们永远无奈察看到残缺的Universe,而只有一个从Universe中随机采样的测试数据集。

模型的真正性能是其在Universe上的性能, 在这种状况下该模型的实在ROC得分为80.4%。然而咱们永远无奈察看到Universe,咱们永远无奈察看到模型的实在ROC。

咱们察看到的是在测试集上计算的ROC分数。有时它会更高(81.6%),有时会更低(79.9%和78.5%),然而咱们无奈晓得真正的ROC分数与察看到的ROC得分有多远。

咱们所能做的就是尝试评估该过程中波及多少随机性。为此须要模仿Universe并从中取样许多随机测试数据集。这样咱们就能够量化察看到的分数的离散度。

如何模仿Universe?

咱们的指标是取得具备给定ROC评分的样本(观测后果),有一种非常简单的办法能够做到这一点。

首先须要设定的所需的个体数量(通常是一个很大的数字)。而后设置风行率prevalence(下面的例子是2分类问题,所以只有正负样本),即阳性的百分比(能够将其保留为50%,这是默认值)。第三步是抉择咱们想要在Universe中的ROC分数。最初能够计算Universe中每个个体的预测概率:负的必须在0和1之间平均距离,而正的必须在和1之间平均距离。

其中能够通过以下公式从ROC取得:

在Python中,应用以下函数实现:

 def get_y_proba(roc, n=100000, prevalence=.5):   n_ones = int(round(n * prevalence))   n_zeros = n - n_ones   y = np.array([0] * n_zeros + [1] * n_ones)   alpha = (roc - .5) * 2    proba_zeros = np.linspace(0, 1, n_zeros)   proba_ones = np.linspace(alpha, 1, n_ones)   proba = np.concatenate([proba_zeros, proba_ones])      return y, proba

获取咱们的不确定性

当初能够创立合成数据了,通过以下命令来获取universe:

 y_universe, proba_universe = get_y_proba(roc=.8, n=100000, prevalence=.5)

咱们的全量数据(universe)是由10万次观测组成的,其中一半是真值的,ROC得分为80%。

让咱们模仿不同测试集的提取。每次将提取5000个不同的测试集,每个测试集蕴含1000个观测数据。这是相应的代码:

 rocs_sample = [] for i in range(5_000):   index = np.random.choice(range(len(y_universe)), 1_000, replace=True)   y_sample, proba_sample = y[index], proba[index]   roc_sample = roc_auc_score(y_sample, proba_sample)   rocs_sample.append(roc_sample)

以下是察看到的ROC散布:

能够看到后果是十分不同的,从低于76%到超过84%都会呈现。

在失常利用中,咱们抉择2个模型如下:一个ROC是78%,另一个是82%。他们有雷同的潜在ROC,而这种差别只是偶尔的后果的可能性有多大呢?

为了给咱们一个判断的根据,能够计算模仿中每对察看到的ROC得分之间的间隔。Scikit-learn有一个pairwise_distance函数能够实现这一点。

 import numpy as np from sklearn.metrics import pairwise_distances  dist = pairwise_distances(np.array(rocs_sample).reshape(-1,1)) dist = dist[np.triu_indices(len(rocs_sample), k=1)]

让咱们用教训累积散布函数来可视化ROC得分之间的两两间隔。

第95个百分位(用虚线突出显示)约为4%。这意味着两种模型(性能雷同)之间的差别只有5%的工夫大于4%。

应用统计术语咱们会说:小于4%的差别不显著!这很乏味,因为通常咱们会认为82%的ROC模型比78%的ROC模型要好得多。

为了取得这个概念的另一个可视化,我模仿了三个不同的universe,一个的ROC值为75%,另一个为80%,最初一个为81%。这些是察看到的ROC评分的散布。

从上图中能够显著看出,最好的模型通常不会获胜!设想一下,比拟几十个模型,每个模型的实在ROC得分都不同。

也就是说抉择可能不是最好的模型。而是抉择了一个最侥幸的。

还能做点什么吗?

下面的形容都阐明了一个问题:没有方法100%确定一个模型比另一个更好,这听起来像一场噩梦。当然:在数据迷信中不存在100%的确定性,然而咱们还是有一些小小的技巧

抉择最佳模型的不确定性水平既取决于universe的特色,也取决于从universe中提取的测试集的特色。这里有三个参数管制着不确定性:

  • 实在ROC:在universe中计算的ROC得分(这个必定是得不到的,所以只能假如)。
  • 样本数:测试集中的样本总数。
  • 样本风行率(prevalence):测试集中的阳性百分比。

为了理解这些元素对不确定性的影响,能够尝试每个元素的不同值来模仿产生的状况:

  • 实在ROC: 70%, 80%和90%。
  • 样本数:1000,5000和10000。
  • 样本风行率:1%,5%和20%。

因为咱们要为三个参数尝试三个值,这意味着27种可能的组合。

对于每个组合,我都能够应用下面的函数创立模仿universe,而后采样了1000个不同的测试集,并测量了各自的ROC得分。而后计算1000个ROC得分的间隔矩阵。最初取间隔的第95个百分位数(从当初开始称为“d”)。这就是下面所说的,对抉择模型的不确定性的掂量。

例如,这是27次试验中的前5次。

咱们用95百分位测量不确定性。这个数字越高,ROC曲线比拟的不确定性就越高。

因为咱们想晓得不确定性如何取决于3个参数,那么测量每个参数和“ D”之间的相干性能代表什么呢?这就是后果:

称为“ R”的列显示了每个参数和不确定性之间的局部相关性。所有相关系数均为阴性,表明减少了这三个中的任何一个都会升高不确定性。

实在ROC:全量数据中的ROC得分较高意味着不确定性较小。这是有情理的,因为依据定义,更高的ROC意味着较小水平的不确定性。

样本数:减少样品数会可升高不确定性。这很显著,并且在统计数据中始终存在。

样本风行率:减少风行率会升高不确定性。较小的风行率意味着更少的阳性。更少的阳性意味着在抽样时随机性的权重更大, 因而有更大的不确定性。

出于好奇心,对于固定的实在ROC(在这种状况下为80%)时,当扭转样本数和样本风行率时,咱们看看失去的ROC分数的散布。

我认为这张图很显著。以左上角为例:样本数和风行率都十分小,咱们有1000个察看后果和1%的阳性后果,这意味着10个阳性后果和990个阴性后果,在这种状况下不确定性十分高,失去的ROC评分散布简直是平均的,从75%到85%。ROC评分之间的间隔的第95百分位数为10%,这意味着察看到的ROC值为75%与察看到的ROC值为85%之间没有显著差别。

然而随着逐步提高样本维度数/或风行率,察看到的ROC评分散布越来越集中在实在值左近(本例中为80%)。例如,10000样本和20%的风行率,第95个百分位数变成了更正当的1.2%。

这对我有用吗?

应该会有一点用,因为咱们要晓得在哪些条件下模型的后果在统计上是正当的。例如反复像在下面看到模仿会帮忙你晓得测试集的数值和风行率是否足以检测模型性能之间的真正差别。

如果还是无奈模仿的话,那就Trust your CV 吧,其实咱们的CV也升高了咱们模型的随机性。

https://avoid.overfit.cn/post/b276c19ddaf44edc96db60b36db3034b

作者:Samuele Mazzanti