通过分布偏移形成训练数据样本

免责声明:本文是Max Halforda的翻译产品翻译不是干净的,而是自适应的。这样,任何知识领域都可以理解。







“我和我的朋友们最近获得了2017年数据科学游戏决赛的资格。比赛第一部分是Kaggle,数据来自Deezer(1)。问题在于解决二进制分类问题:有必要预测用户是否将要切换到收听提供给他的构图。



与其他团队一样,我们提取了相关功能并训练了XGBoost(2)分类器。但是,我们做了一件特别的事情-训练数据集的子样本,以使它(训练数据集)更能代表测试集。”




机器模型成功运行的学习过程的基本要求之一是训练和测试数据集中分布的相同性质。举一个粗糙的例子:该模型是针对20岁以下的用户进行训练的,而在测试样本中,该用户已经60岁以上。



从直觉上讲,自然而然的是,随着模型未受训练的年龄,它将无法应付。当然,这样的例子纯粹是综合性的,但是实际上,由于存在明显的差异,将模型训练为20+并尝试使其适用于30+就足够了。结果将是相似的。



这是因为模型学习数据的分布(3)。如果功能在训练集中和测试集中的分布相同,则模型将感谢您。



翻译插入: 当我坐下来翻译时,我有一个问题:为什么要对测试进行培训调整,因为事实上,测试反映了将在生产开始时进入模型的不可见数据。然后我睡过头了,重读了,一切都消失了。诀窍在于,在各种因素的影响下,回顾可能与现在无关。稍后再详细介绍(示例稍作重新适应)。



出于一种原因,可能会因一种功能而出现分配偏差。最直观的示例可以从Facebook借用。



假设某公司在几分钟内就接受了基于功能(功能与功能相同)作为消遣的模型的培训。让它以十分制综合预测用户忠诚度水平。



当将普通Facebook应用程序拆分为主要社交网络(Feed等)和消息传递系统时,主要应用程序中的时间减少了,也就是说,传入的数据集发生了变化,不再与过去的回顾相对应。

从数学上讲,考虑到时间特征,该模型将预测较低的忠诚度,尽管实际上并非如此-时间转移仅分为两个应用程序。可悲地出来。



因此,当历史数据的分布与预测新数据无关时,发生分布偏移。



在Deezer数据集中,分布的不一致性在于测量在解决预测问题之前所听歌曲数量的特征。在公共数据集和测试数据集中,此功能均呈指数分布(4)。但是,在测试数据集中它更明显,因此训练集中的平均值低于测试集中的平均值。在对培训分布进行重新采样后,我们设法提高了ROC-AUC指标(5),并将评分提高了约20点。



以下是分布差异的示例:



import numpy as np
import plotly.figure_factory as ff

train = np.random.exponential(2, size=100000)
test = np.random.exponential(1, size=10000)

distplot = ff.create_distplot([train, test], ['Train', 'Test'], bin_size=0.5)
distplot.update_layout(title_text=' Test, Train')






整平的分布偏移的想法是重塑训练样本以反映测试分布。



假设我们要从训练集中创建50,000个观测值的子集,以适合测试集的分布。您想直观地做什么?



使其在测试数据集中更常见的对象在训练中也很常见!但是,您如何确定需要更多的对象,而较少地需要哪些对象?



天秤座!



步骤将如下所示:



  • 将分布的数字直线分成相等的间隔(或篮子(箱)
  • 计算每个篮子中的物品数量(垃圾箱大小)
  • 对于篮子中的每个观测值,计算其权重等于1 /(垃圾箱大小)
  • 创建具有加权分布的k子样本(权重较高的对象会更频繁地出现在子样本中)


转移到代码,我们执行以下操作:



SAMPLE_SIZE = 50000
N_BINS = 300

#   ,       .
#        
step = 100 / N_BINS

test_percentiles = [
    np.percentile(test, q, axis=0)
    for q in np.arange(start=step, stop=100, step=step)
]

#     . 
#    ,    
train_bins = np.digitize(train, test_percentiles)

#          i   ,
#  0      , 1    1    i 
train_bin_counts = np.bincount(train_bins)

#    ,        
weights = 1 / np.array([train_bin_counts[x] for x in train_bins])

#   ,     
weights_norm = weights / np.sum(weights)

np.random.seed(0)

sample = np.random.choice(train, size=SAMPLE_SIZE, p=weights_norm, replace=False)

distplot_with_sample = ff.create_distplot([train, test, sample], ['Train', 'Test', 'New train'], bin_size=0.5)
distplot_with_sample.update_layout(title_text=' Test, Train, New train')






新的分布(绿色)现在更好地与测试样本的分布(橙色)匹配。我们在比赛中使用了类似的操作-原始数据集包含300万行,我们从130万个对象中生成了新样本的大小。数据变小了,但是分布的代表性提高了训练的质量。



作者的亲身经历:



  • 篮子的数量并不重要,但是篮子的数量越少,算法学习的越快(在示例中,尝试将篮子的数量(N_BINS)更改为3、30),您会发现差异确实很小)
  • , , , “” , , .

    ( , “” , “” . . , )



重塑算法在作者的github(xam文件夹)上。将来,作者计划分析新主题并在博客中分享。



希望译文和注释对您有所帮助并且清楚。希望您以建设性的态度提出反馈。感谢您的时间。



脚注:



1. Deezer是法国的在线音乐流媒体服务。键入Spotify的,Ya.Muzyki和好,你会得到



2 XGBoost-极限梯度提升算法。我绝对喜欢称其为“逐步增强类固醇”。提升的想法是训练几个同质的弱学生,每个学生都是根据前一个的回顾性学习经验来形成成绩的,并且要注意前一个算法最失败的那些课程。简单来说,梯度背后的想法是最大程度地减少学习错误。 XGBoost作为一种算法,是Gradient Boosting



3的一种在计算上更具优势的配置。这里的分布恰好是指描述数字分散在变量中的定律的事物。



4.我个人认为,可视化指数是最容易理解的刺激。头部中的分布是其定义,即具有恒定强度的分布。



5. ROC-AUC(接收器工作特性曲线下的面积)-“接收器处理特性”曲线下的面积-直译名称,因为该度量标准来自信号处理理论。 ROC曲线非常陡峭-它证明了模型响应的“正肯定”与“假肯定”之比作为分配给类别的概率的阈值变化,从而形成“弧”。由于TP和FP的比率可见,因此可以根据第一和第二种误差选择最佳概率阈值。



在考虑模型的准确性的情况下,不注意响应的概率阈值,将使用ROC-AUC度量标准,该度量标准的取值范围为[0,1]。对于具有类平衡的恒定模型,ROC-AUC将近似等于0.5,因此,以下模型无法通过健全性检查(健全性检查)。ROC曲线下的面积越接近1越好,但是通常为了索引结果的有用性,将经过训练的模型的AUC-ROC与恒定模型的AUC-ROC进行比较很重要。



All Articles