Evan Harris作者

将sklearn训练速度提升100多倍,美国「返利网」开源sk-dist框架

在本文中,Ibotta(美国版「返利网」)机器学习数据科学经理 Evan Harris 介绍了他们的开源项目 sk-dist。这是一个分配 scikit-learn 元估计器的 Spark 通用框架,它结合了 Spark 和 scikit-learn 中的元素,可以将 sklearn 的训练速度提升 100 多倍。

在 Ibotta,我们训练了许多机器学习模型。这些模型为我们的推荐系统、搜索引擎、定价优化引擎、数据质量等提供了支持,在与我们的移动 app 互动的同时为数百万用户做出预测。

虽然我们使用 Spark 进行大量的数据处理,但我们首选的机器学习框架是 scikit-learn。随着计算成本越来越低以及机器学习解决方案的上市时间越来越重要,我们已经踏出了加速模型训练的一步。其中一个解决方案是将 Spark 和 scikit-learn 中的元素组合,变成我们自己的融合解决方案。

  • 项目地址:https://github.com/Ibotta/sk-dist

何为 sk-dist

我们很高兴推出我们的开源项目 sk-dist。该项目的目标是提供一个分配 scikit-learn 元估计器的 Spark 通用框架。元估计器的应用包括决策树集合(随机森林和 extra randomized trees)、参数调优(网格搜索随机搜索)和多类技术(一对多和一对一)。

我们的主要目的是填补传统机器学习模型分布选择空间的空白。在神经网络深度学习的空间之外,我们发现训练模型的大部分计算时间并未花在单个数据集上的单个模型训练上,而是花在用网格搜索或集成等元估计器在数据集的多次迭代中训练模型的多次迭代上。

实例

以手写数字数据集为例。我们编码了手写数字的图像以便于分类。我们可以利用一台机器在有 1797 条记录的数据集上快速训练一个支持向量机,只需不到一秒。但是,参数调优需要在训练数据的不同子集上进行大量训练。

如下图所示,我们已经构建了一个参数网格,总共需要 1050 个训练项。在一个拥有 100 多个核心的 Spark 集群上使用 sk-dist 仅需 3.4 秒。这项工作的总任务时间是 7.2 分钟,这意味着在一台没有并行化的机器上训练需要这么长的时间。

import timefrom sklearn import datasets, svm
from skdist.distribute.search import DistGridSearchCV
from pyspark.sql import SparkSession # instantiate spark session
spark = (   
    SparkSession    
    .builder    
    .getOrCreate()    
    )
sc = spark.sparkContext 

# the digits dataset
digits = datasets.load_digits()
X = digits["data"]
y = digits["target"]

# create a classifier: a support vector classifier
classifier = svm.SVC()
param_grid = {
    "C": [0.01, 0.01, 0.1, 1.0, 10.0, 20.0, 50.0], 
    "gamma": ["scale", "auto", 0.001, 0.01, 0.1], 
    "kernel": ["rbf", "poly", "sigmoid"]
    }
scoring = "f1_weighted"
cv = 10

# hyperparameter optimization
start = time.time()
model = DistGridSearchCV(    
    classifier, param_grid,     
    sc=sc, cv=cv, scoring=scoring,
    verbose=True    
    )
model.fit(X,y)
print("Train time: {0}".format(time.time() - start))
print("Best score: {0}".format(model.best_score_))


------------------------------
Spark context found; running with spark
Fitting 10 folds for each of 105 candidates, totalling 1050 fits
Train time: 3.380601406097412
Best score: 0.981450024203508

该示例说明了一个常见情况,其中将数据拟合到内存中并训练单个分类器并不重要,但参数调整所需的拟合数量很快就会增加。以下是运行网格搜索问题的内在机制,如上例中的 sk-dist:

使用 sk-dist 进行网格搜索

对于 Ibotta 传统机器学习的实际应用,我们经常发现自己处于类似情况:中小型数据(100k 到 1M 记录),其中包括多次迭代的简单分类器,适合于参数调优、集合和多类解决方案。

现有解决方案

对于传统机器学习元估计训练,现有解决方案是分布式的。第一个是最简单的:scikit-learn 使用 joblib 内置元估计器的并行化。这与 sk-dist 非常相似,除了一个主要限制因素:性能受限。即使对于具有数百个内核的理论单台机器,Spark 仍然具有如执行器的内存调优规范、容错等优点,以及成本控制选项,例如为工作节点使用 Spot 实例。

另一个现有的解决方案是 Spark ML。这是 Spark 的本机机器学习库,支持许多与 scikit-learn 相同的算法,用于分类和回归问题。它还具有树集合和网格搜索等元估计器,以及对多类问题的支持。虽然这听起来可能是分配 scikit-learn 模式机器学习工作负载的优秀解决方案,但它的分布式训练并不能解决我们感兴趣的并行性问题。

分布在不同维度

如上所示,Spark ML 将针对分布在多个执行器上的数据训练单个模型。当数据很大且无法将内存放在一台机器上时,这种方法非常有效。但是,当数据很小时,它在单台计算机上的表现可能还不如 scikit-learn。此外,当训练随机森林时,Spark ML 按顺序训练每个决策树。无论分配给任务的资源如何,此任务的挂起时间都将与决策树的数量成线性比例。

对于网格搜索,Spark ML 确实实现了并行性参数,将并行训练单个模型。但是,每个单独的模型仍在对分布在执行器中的数据进行训练。如果按照模型的维度而非数据进行分布,那么任务的总并行度可能是它的一小部分。

最终,我们希望将我们的训练分布在与 Spark ML 不同的维度上。使用小型或中型数据时,将数据拟合到内存中不是问题。对于随机森林的例子,我们希望将训练数据完整地广播给每个执行器,在每个执行器上拟合一个独立的决策树,并将那些拟合的决策树返回驱动程序以构建随机森林。沿着这个维度分布比串行分布数据和训练决策树快几个数量级。这种行为与网格搜索和多类等其他元估计器技术类似。

特征

鉴于这些现有解决方案在我们的问题空间中的局限性,我们决定在内部开发 sk-dist。最重要的是我们要「分配模型,而非数据」。

sk-dist 的重点是关注元估计器的分布式训练,还包括使用 Spark 进行 scikit-learn 模型分布式预测的模块、用于无 Spark 的几个预处理/后处理的 scikit-learn 转换器以及用于有/无 Spark 的灵活特征编码器。

分布式训练:使用 Spark 分配元估计器训练。支持以下算法:参数调优(网格搜索随机搜索)、决策树集合(随机森林、额外随机树和随机树嵌入)以及多类技术(一对多和一对一)。

分布式预测:使用 Spark DataFrames 分布拟合 scikit-learn 估算器的预测方法。可以通过便携式 scikit-learn 估计器实现大规模分布式预测,这些估计器可以使用或不使用 Spark。

特征编码:使用名为 Encoderizer 的灵活特征转换器分布特征编码。它可以使用或不使用 Spark 并行化。它将推断数据类型和形状,自动应用默认的特征转换器作为标准特征编码技术的最佳预测实现。它还可以作为完全可定制的特征联合编码器使用,同时具有与 Spark 分布式转换器配合的附加优势。

用例

以下是判断 sk-dist 是否适合你的机器学习问题空间的一些指导原则:

  1. 传统机器学习广义线性模型随机梯度下降、最近邻算法、决策树和朴素贝叶斯适用于 sk-dist。这些都可在 scikit-learn 中实现,可以使用 sk-dist 元估计器直接实现。

  2. 中小型数据 :大数据不适用于 sk-dist。请记住,训练分布的维度是沿着模型变化,而不是数据。数据不仅需要适合每个执行器的内存,还要小到可以广播。根据 Spark 配置,最大广播大小可能会受到限制。

  3. Spark 定位与访问:sk-dist 的核心功能需要运行 Spark。对于个人或小型数据科学团队而言,这并不总是可行的。此外,为了利用 sk-dist 获得最大成本效益,需要进行一些 Spark 调整和配置,这需要对 Spark 基础知识进行一些训练。

这里一个重要的注意事项是,虽然神经网络深度学习在技术上可以与 sk-dist 一起使用,但这些技术需要大量的训练数据,有时需要专门的基础设施才能有效。深度学习不是 sk-dist 的预期用例,因为它违反了上面的 (1) 和 (2)。在 Ibotta,我们一直在使用 Amazon SageMaker 这些技术,我们发现这些技术对这些工作负载的计算比使用 Spark 更有效。

原文地址:https://medium.com/building-ibotta/train-sklearn-100x-faster-bec530fc1f45

工程SparkSciKit-Learn
4
相关数据
深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

网格搜索技术

网格搜索是一项模型超参数优化技术,常用于优化三个或者更少数量的超参数,本质是一种穷举法。对于每个超参数,使用者选择一个较小的有限集去探索。然后,这些超参数笛卡尔乘积得到若干组超参数。网格搜索使用每组超参数训练模型,挑选验证集误差最小的超参数作为最好的超参数。

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

数据科学技术

数据科学,又称资料科学,是一门利用数据学习知识的学科,其目标是通过从数据中提取出有价值的部分来生产数据产品。它结合了诸多领域中的理论和技术,包括应用数学、统计、模式识别、机器学习、数据可视化、数据仓库以及高性能计算。数据科学通过运用各种相关的数据来帮助非专业人士理解问题。

超参数技术

在机器学习中,超参数是在学习过程开始之前设置其值的参数。 相反,其他参数的值是通过训练得出的。 不同的模型训练算法需要不同的超参数,一些简单的算法(如普通最小二乘回归)不需要。 给定这些超参数,训练算法从数据中学习参数。相同种类的机器学习模型可能需要不同的超参数来适应不同的数据模式,并且必须对其进行调整以便模型能够最优地解决机器学习问题。 在实际应用中一般需要对超参数进行优化,以找到一个超参数元组(tuple),由这些超参数元组形成一个最优化模型,该模型可以将在给定的独立数据上预定义的损失函数最小化。

推荐系统技术

推荐系统(RS)主要是指应用协同智能(collaborative intelligence)做推荐的技术。推荐系统的两大主流类型是基于内容的推荐系统和协同过滤(Collaborative Filtering)。另外还有基于知识的推荐系统(包括基于本体和基于案例的推荐系统)是一类特殊的推荐系统,这类系统更加注重知识表征和推理。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

随机森林技术

在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。 Leo Breiman和Adele Cutler发展出推论出随机森林的算法。而"Random Forests"是他们的商标。这个术语是1995年由贝尔实验室的Tin Kam Ho所提出的随机决策森林(random decision forests)而来的。这个方法则是结合Breimans的"Bootstrap aggregating"想法和Ho的"random subspace method" 以建造决策树的集合。

朴素贝叶斯技术

朴素贝叶斯是一种构建分类器的简单方法。该分类器模型会给问题实例分配用特征值表示的类标签,类标签取自有限集合。它不是训练这种分类器的单一算法,而是一系列基于相同原理的算法:所有朴素贝叶斯分类器都假定样本每个特征与其他特征都不相关。举个例子,如果一种水果其具有红,圆,直径大概3英寸等特征,该水果可以被判定为是苹果。尽管这些特征相互依赖或者有些特征由其他特征决定,然而朴素贝叶斯分类器认为这些属性在判定该水果是否为苹果的概率分布上独立的。

随机梯度下降技术

梯度下降(Gradient Descent)是遵循成本函数的梯度来最小化一个函数的过程。这个过程涉及到对成本形式以及其衍生形式的认知,使得我们可以从已知的给定点朝既定方向移动。比如向下朝最小值移动。 在机器学习中,我们可以利用随机梯度下降的方法来最小化训练模型中的误差,即每次迭代时完成一次评估和更新。 这种优化算法的工作原理是模型每看到一个训练实例,就对其作出预测,并重复迭代该过程到一定的次数。这个流程可以用于找出能导致训练数据最小误差的模型的系数。

支持向量机技术

在机器学习中,支持向量机是在分类与回归分析中分析数据的监督式学习模型与相关的学习算法。给定一组训练实例,每个训练实例被标记为属于两个类别中的一个或另一个,SVM训练算法创建一个将新的实例分配给两个类别之一的模型,使其成为非概率二元线性分类器。SVM模型是将实例表示为空间中的点,这样映射就使得单独类别的实例被尽可能宽的明显的间隔分开。然后,将新的实例映射到同一空间,并基于它们落在间隔的哪一侧来预测所属类别。

广义线性模型技术

在统计学上, 广义线性模型 (Generalized linear model) 是一种应用灵活的线性回归模型,简称GLM。该模型允许因变量的偏差分布有除了正态分布之外的其它分布。此模型假设实验者所量测的随机变量的分布函数与实验中系统性效应(即非随机的效应)可经由一链接函数(link function)建立起可资解释其相关性的函数。

随机搜索技术

推荐文章
暂无评论
暂无评论~