如何标记训练数据是在发展机器学习应用中最昂贵的瓶颈。本研究开创性的研究如何利用已有知识来源进行若监督机器学习从而缩短训练时间和降低成本,这里使用了一种新型的弱监督管理系统Snorkel DryBell。在Google上进行的三个分类任务中,研究发现Snorkel DryBell提升了52%的性能并且在数十分钟内处理了上百万的数据。
在工业界中发展机器学习应用的最大的瓶颈之一就是标签数据的获取,由于以下4点原因,标题数据的获取变得更加昂贵:
(1)为了使机器学习的训练结果具有较好的泛化性,因此对训练数据的需求是其应该尽可能涵盖各种情况,包括一些不容易出现的边缘情况,这样就增加了收集训练数据方案的设计成本
(2)标记训练数据往往需要雇佣人力进行标注,有些数据由于涉及到专业领域知识,甚至必须要由专家才能标注,这样就增加了训练数据的标注成本
(3)机器学习的学习效果经常非常依赖于大数据,在同等条件下,更大的数据规模往往意味着更好的训练效果,这样就需要收集大规模的训练数据,而这可能会耗费数月或更久去收集数据,这样就增加了获取训练数据的时间成本
(4)机器学习应用随着时间变化可能出现需求变化,这样就意味着原本的数据集可能会部分不可用,或是需要增加某些属性项,这样就增加了训练数据的更新成本
由于获取训练数据这样昂贵,因此在工业界中十分推崇弱监督这样通过半自动化方法更高效的生成大量标记数据的方法,不过这种方法生成的标记数据往往有较大噪声。随着标准机器学习方法越来越流水线化、越来越千篇一律,监督方式的选取已经成为了决定模型最终性能的最关键因素,换言之,选择什么样的模型对于最终性能的影响还没有选取什么样的监督方式、什么样的数据大。
Snorkel的主要流程中有3步:
第(1)步:使用者设置标签函数,这些函数是简单的黑盒函数,可以看成是初始化的标签预测函数的若干个方案,这些函数读入原始无标签数据然后分别给出它们的预测,也可以对某个数据放弃预测
第(2)步:训练出一个标签预测模型,模型的关键参数就是对前面步骤中各标签函数计算的结果进行加权求和,从而得出实际使用的预测标签
第(3)步:使用生成的数据集训练出最终解决实际问题的分类器
设表示未标签的含有个数据的数据集,其中,表示该数据集未观察到的标签值,也就是真实值,在实际中Snorkel DryBell可以解决多分类任务,也就是说,但是在实验中为了简化问题,研究中默认进行二分类任务,也就是,表示个标签函数,每个标签函数将映射到,其中+1和-1分别表示正负标签,0表示“弃权”,是一个矩阵表示通过个标签函数分别对个数据进行运算后的结果,其中表示第个数据经过第个标签函数计算后的结果。接下来需要训练出模型参数,设带有参数的标签生成模型为,可以理解为对不同标签函数的结果进行权值分配从而得到最终的预测标签。训练中的目标是使得的预测结果相对于真实标签的极大似然估计尽可能大,也就是:
得到了生成标签估计模型,就可以使用它生成标签数据,然后使用数据集训练最终的分类器
正式的分析显示当这种弱监督中使用的无标签数据规模增加时,最终训练出来的分类器的泛化误差会下降,且下降的程度渐进接近使用传统的人工标记数据的有监督机器学习训练出来的结果。
研究中测试了本方法在3种Google上的分类任务的效果,分别是主题分类、商业产品分类和一些服务平台的实时分类任务。
对于Snorkel DryBell种第(2)步也就是得到预测标签的估计模型可以反过来进行一种应用,那就是判断出原有的各种质量参差不齐的数据来源的贡献程度,因为预测标签估计模型的训练实际上是得到初始设定的标签函数的权重分配,因此对于权重分配国小的标签函数背后的数据来源,我们可以摒弃,以后也可以避免此类数据的收集以减少成本,而对于那些权重分配较大的标签函数背后的数据,则可以适当加大人工投入力度,因为这些数据更加有用。
谷歌产品团队需要一个分类器来探测一段文本中是否为目标主题。实际中已经存在了超过100种这样的分类器,每种分类器都使用它们各自的不同数据集,因此直觉来说感觉可能存在某种方法可以综合这些现有的数据集或数据来得到一个更强大的分类器,然而由于现存的数据集各自都有不同的属性,因此如果要综合这些数据会需要大量的人工标记成本。
而本研究使用的Snorkel DryBell框架基于684K无标签数据,达到了另外实验中基于80K和175K人工标记数据训练出来的模型大提相当的效果。研究者花了很短的时间设计了10个标签函数,这些标签函数包含了URL启发式、NER标签启发式和主题模型启发式。Snorkel DryBell框架通过这些标签函数很好的将不同形式的数据来源整合在了一起。
由于产品分类随着时间的推移增加了一些类别,谷歌产品团队需要更新一个产品分类器来扩充原先的产品分类,这就意味着原先产品分类器所使用的训练数据集中的负标签部分都必须重新进行标记,看它能否符合新的产品分类条目。然而本研究的实验结果显示,即使只使用原先数据集中的正标签,也可以达到人工标记12K或50K数据训练出的分类器的效果。类似于主题分类器的训练过程,研究者在这里也先设计了8个初始的标签函数,分别是基于关键词的、基于知识图谱的和基于模型的。
研究者最后将Snorkel DryBell框架应用到了2个Google平台上的实时事件分类任务上。传统的方法是基于诸如聚合统计数据或关系图谱这样的离线特征来分类事件,这些离线特征是non-servable的。然而这种方法的实时性较差。替代的方法就是基于实时性的特征,但是这样就会需要巨大的人力成本去进行实时性的人工标注。然而Snorkel DryBell可以基于离线的non-servable特征(共有140种,分别为基于模型的、基于图的和其他的)来训练出可以根据实时特征来预测分类的神经网络模型。相较于不进行预测函数预测标签的权重分配,对权重分配进行训练了的Snorkel DryBell框架的识别数量提升了58%,预测性能也提升了4.5%
Snorkel DryBell中实现的弱监督方法的一个最重要的好处就是可以轻松且可扩展的将那些工业生产中缓慢、昂贵或私密的non-servable特征转换为可以快速处理的实时性特征。严格说来,这种希望从基于特征A的模型中训练出基于特征B的模型的弱监督机器学习方法也可以看成是某种形式的迁移学习。但是正常的迁移学习应当要求特征A和特征B要类似,而Snorkel DryBell框架则没有这个要求,它可以快速的将non-servable的特征A转换为servable的特征B。
在谷歌的实时事件分类任务中,这一点尤为重要,因为原有的non-servable特征的数据源单独来看没有一个可以训练出可以基于实时特征的分类器,但是经过Snorbel DryBell通过权重分配将这些non-servable的数据源整合起来后,就可以训练出一个基于实时特征的分类器了。在前2个实时性要求没那么高的文本分类任务中,经过Snorkel DryBell框架整合后了non-servable和servable特征的弱监督学习方法仍然可以训练出总体性能得到提升的分类器。
实验中以C++模板类库的形式实现了用户自定义标签函数的功能。开发高度抽象的模板库类的目的是让用户更好的聚焦在标签函数的设计上,而不是重复的代码编写,从而提高开发效率。
AbstractLabelingFunction类读取所有的输入并将结果输出到谷歌分布式文件系统中,每一个子类中都有一个MapReduce的过程,模板中预留了用户自定义函数的槽位,用户将自己设计好的标签函数置入即可实现开发。
模板库中预定义了2种执行流程。第1种流程是默认的流程,它就是简单的执行用户提供的标签函数,这种流程可以满足很多情况的需要,比如基于文本或模型等离线特征的情感分类,基于图的离线知识图谱查询。第2种流程则是整合了谷歌的通用NLP模型,之所以要进行整合而不是直接使用是因为谷歌的NLP模型实在是太消耗计算资源了,因此需要和用户另外提供的模型一起在MapReduce下共同使用,才能应对百万级别的数据。
模板库的开发人员仅仅需要定义标签函数就可以使用,这些函数代表了开发人员所掌握的对于弱监督学习有帮助的数据来源特征。
上图是一个使用NLP模型和NER启发式的标签函数示例,这里的目标假定为希望找到那些不包含目标明星的文本内容,NLPLabelingFunction首先有一个GetText函数通过NER技术把文本中关心的内容提取出来,输送到模型中,那就是标题和人名,接着GetValue就对数据进行标签,如果没有出现过人名就打上负标签,否则就弃用。
Snorkel DryBell框架中的一个关键人物就是要将带有噪音的各种标签函数整合成为尽可能贴近真实值的估计标签。Snorkel DryBell框架中使用了一个大大减少CPU负荷并且能够很便捷的进行分布式计算的免抽样模型。
它的原理是条件独立生成模型:
基本假设是每个标签函数在没有放弃时都有一个已知的准确率,并且每个标签函数都会尽可能不去放弃,所有的条件分布都共用一个参数,为了简便考虑,假定的模型形式是统一的,但是实际中各自模型的形式也可以是不统一的。
训练中的目标是最小化
在开源的Snorkel中采用了吉布斯采样器来计算梯度,但是这种采样方式太消耗CPU运算资源并且在进行分布式计算时格外复杂。而本实验中基于Tensorflow实现了无需采样的最优化计算。为了数值的稳定性,所有的参数都进行了对数化处理。设表示第个标签函数经过对数化处理后的在不弃权时的预测正确率,表示第个标签函数经过对数化处理后的不弃权率。
具体模型最优化目标的公式及推导过程如下:
拿10个标签函数在批处理大小为64的情况进行对比试验,吉布斯采样器每秒平均可以处理50个数据,而本研究的免采样方法可以每秒平均处理超过100个数据。所以可以说本研究将原有开源实现的速度性能提升了2倍。
使用Tensorflow的好处就在于它可以很好地调用Tensorflow内置API并行化处理,并且在本实验的实现下可以放宽条件独立性假设。
为了使得训练出的分类模型在工业中可用,实验中整合了Snorkel DryBell框架和谷歌的端到端工业级机器学习平台TFX。具体的分工是Snorkel DryBell生成估计标签数据,TFX再基于这些标签数据采用用户指定的方法训练出最终的模型。
除了前面提到的对于开源项目实现的更新改变(比如说结合了Tensorflow从而提升分布式处理能力),Snorkel还结合了谷歌的API,这是因为Snorkel的设计初衷是在单一共享的计算结点上进行运行,而谷歌的API则可以很好的利用其内置的MapReduce框架。另外,由于Snorkel是被设计为对于程序员新手友好的,即使程序员只有很有限的机器学习经验,它也可以运用Snorkel框架。它通过使用Jupyter的界面,并强制规定了文本数据集的形式。这种严苛的规定导致Snorkel很难很好的被扩展应用到多种多样的任务中。原始的Snorkel使用的是关系型数据库,这就和谷歌的文件存储系统不兼容,为了能够将谷歌的API整合进去,实验中将Snorkel改造为了使用谷歌文件系统存储数据。
实验使用了谷歌上的3类分类任务(主题分类、产品分类、实时事件分类)的数据作为测试数据集来评估Snorkel DryBell的性能。离线文本分类(即主题分类和产品分类)显示出弱监督学习中使用non-servable特征的好处,实时事件分类则显示出了Snorkel DryBell相对于原始框架的性能提升。尽管实时事件分类模型的整个训练过程整体上仍然是一个黑盒,但是研究人员已经给出了一些解释证明Snorkel DryBell的广泛应用性。
在主题分类和产品分类测试中,首先使用Snorkel DryBell生成估计标签数据,再使用这些数据训练类似于实际中使用的基于servable特征的逻辑回归分类器。不同任务中的数据规模从数十万到百万不等。
下图就是两个测试任务中的实验数据,其中主题分类任务的无标签数据规模有684K,其中人工标注数据集11K,测试集11K,测试集中有0.86%为正例,共使用了10个标签函数;产品分类测试中,无标签数据共6.5M,人工标注数据集14K,测试集13K,测试集中1.48%为正例,共使用了8个标签函数。
TFX中使用了逻辑回归模型,训练时采取FTLR算法(随机梯度下降算法的一个变种,能够调整每个坐标处的学习率,初始步长设置为0.2)。所有实验的批处理大小都为64。主题分类任务中迭代了10K次,产品分类任务中迭代了100K次,之所以产品分类任务的迭代次数比主题分类任务高出一个数量级是因为主题分类任务的特征的数量要比产品分类任务多出一个数量级,这样就可以使得两个任务的训练时间大体相当。
下图是分别使用原始的生成式模型(原始的生成式模型所使用特征是non-servable的,因此只能在实验中使用而无法在实际中使用)和经过改进的Snorkel DryBell框架在经过人工标注的测试集上的性能。评价性能有准确率、召回率、F1值等,可以看到Snorkel DryBell的性能整体上要超过原始的生成式模型。
实验还想验证分类器能否习得超出标签函数所包含的特征,也就是其泛化性能。实验结果表明,相较于在人工标注的数据集上训练得到的结果,在弱监督学习中生成的估计标签数据集上训练得到的结果在测试集上的F1分数更高,这表明使用若监督学习可以获得更好的泛化性能。同时也表明了Snorkel DryBell框架很好的将non-servable特征迁移为了servable特征。即Snorkel DryBell框架有较好的泛化性能和迁移性能。
接下来是考察应当如何折中的使用弱监督学习和人工标记数据集从而达到使得性价比最高。
下图分别是主题分类和产品分类在不同规模人工标签数据集和弱监督数据集上的性能表现。其中蓝色实现代表人工标签数据集,棕色虚线代表弱监督数据集,可以看到不同数据规模下弱监督数据集训练出来的结果的性能都较为稳定(这可能也隐含着更好的泛化性能?),而在人工标签数据集训练出来的结果则是随着数据规模的增大而提升,在数据规模较小时性能比弱监督数据集要查,当数据规模较大时性能比弱监督数据集要好,其中主题分类的临界值是85K,也就是极小的若监督数据集可以达到和85K人工标注数据集一样的效果,在产品分类中这一临界值是12K,可以看到主题分类的临界值几乎比产品分类临界值要大一个数量级,这可能由于之前提到过的主题分类涉及的特征数量比产品分类特征数量要多一个数量级。这个结果表明使用弱监督学习可以极大减少对于人工标记数据规模的要求,比方说在主题分类中相对F1的指标要求是不超过118%的,那么仅使用25K就可以达到85K数据集的性能,这就节省了大量的数据集要求,即使性能的要求高过120%一定要加入一些人工标记数据集,那么仍然可以用一部分弱监督数据集来替代大量的人工标注数据集,整合起来使用,在更小的数据规模上达到同样的效果。
为了研究使用那些non-servable特征数据的重要性,实验中去除了这些non-servable的数据,仅保留了基于模式的特征进行了实验与保留non-servable特征数据时的效果进行比较。下图所示实验结果表明,如果使用保留了non-servable的数据训练得到的分类器平均性能提升了52%,这说明2点:第一non-servable特征数据确实蕴含了能够提升效果的信息,第二这些有效的信息被成功迁移到为了servable的特征。
下图是在生成标签预测模型时对于标签函数不分配权重或说分配相等权重时训练出来分类器的性能,结论表明使用了生成式模型对标签函数进行权重分配后,分类器性能得到了提升。
为比较Snorkel DryBell在实时事件分类中的效果,实验中将其与逻辑或弱监督方法进行了对比,逻辑或弱监督方法是基于non-servable特征的弱监督数据,通过逻辑或整合,训练出一个基于servable特征的深度神经网络分类器,而另一面则是使用Snorkel DryBell给出预估标签数据,再用这些标签数据去训练出一个基于servable特征的深度神经网络分类器。结果表明使用了Snorkel DryBell框架生成数据的分类器能够多发现58%的事件,并且识别的准确率相比另一种要高4.5%。
下图两种方法生成结果的对比图,左图是没有基于Snorkel DryBell框架的,右图是基于Snorkel DryBell框架的,可以看到左图的比例分配非常失衡,表明其有过拟合的风险,而右图则要好许多。从中可以看出,Snorkel DryBell的拟合效果要更好。
以上实验结果证明了Snorkel DryBell的几点改进对于适应到实际应用中的重要作用:
(1)使用谷歌文件系统存储而不是原始Snorkel的关系型数据库存储数据集可以使得各种各样的数据来源都能以相同形式存储,最终这些各式各样的数据来源都使用标签函数进行封装表达
(2)Snorkel DryBell的标签函数机制使之可以被离线设计,随后将non-servable的特征迁移为servable的特征
(3)弱监督方法可以迅速的生成标签数据,比如说已经选定了一些特征,那么当面对一个新的主题分类时就可以自动生成对应的标签数据而不用人工标注;具体举例来说,谷歌打算为一个已经开发好的产品添加一个特征,那么在进行主题分类时就需要把这个新特征考虑在内,那么在重新训练主题分类器时就需要新的训练集,这个训练集需要将新特征考虑在内,如果是传统的有监督学习就需要完全人工再标注一遍,但是如果使用Snorkel DryBell则可以在代码层面进行更新,大大减少更新成本
(4)现今一个团队实际上在公司里会同时负责非常多的分类器,这些分类器性能目的各异,但是通过Snorkel DryBell框架甚至可以把这些形式内容各异的数据特征整合在一起,每次权重赋值产生不同从而高效的生成各式各样的分类器
(5)开发人员能够专心在设计标签函数上,省下许多代码开发的精力
(1)现在公开存在着大量的潜在弱监督数据集,虽然它们的形式、内容各不相同,数据集本身的收集目的可能也和目标任务不一致,但是通过一些整合方法是可以挖掘出这些数据的价值,另外云计算的发展也使得这些资源更容易被获取。
(2)将non-servable的特征迁移到servable特征的方法至关重要
弱监督机器学习会使用廉价的数据集(现成易获得的或充满噪音或无标签的)而非经过精心人工标注的数据集,对于希望使用十分有限的数据集训练出结果的系统是十分有吸引力的方法。
半监督学习会同时使用带标签数据和无标签数据 。
迁移学习会尝试复用以往相似任务的标签数据到新任务上。
本文主要展现了改进自开源弱监督机器学习框架Snorkel的Snorkel DryBell框架,该框架通过标签函数的方式可以整合大量不可直接使用的数据,通过权重分配生成预估标签,并以此训练出最终的模型,该框架很好的支持分布式处理,能够高效的在实际中使用。
https://github.com/HazyResearch/snorkel