页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

对于某些应用,估计器的性能(主要是预测时间的延迟和吞吐量)至关重要。考虑培训吞吐量也可能是值得关注的,但在生产设置(通常在脱机中进行)通常不太重要。

我们将在这里审查您可以从不同上下文中的一些Scikit学习估计器预期的数量级,并提供一些解决性能瓶颈的技巧和诀窍。

预测延迟是作为进行预测所需的经过时间(例如,以微秒为单位)来测量的。延迟通常被视为一种分布,运营工程师通常将注意力集中在该分配给定百分位数(例如90%)的延迟。

预测吞吐量被定义为软件可以在给定的时间量内(例如,每秒预测)可以传送的预测数量。

性能优化的一个重要方面也是它会损害预测精度。实际上,更简单的模型(例如线性的,而不是非线性的,或者具有较少的参数)通常运行得更快,但并不总是能够考虑与更复杂的数据相同的精确属性。

 

预测延迟

在使用/选择机器学习工具包时可能会遇到的最直接的问题之一是可以在生产环境中进行预测的延迟。

影响预测延迟的主要因素是功能数量输入数据表示和稀疏模型复杂性特征提取

最后一个主要参数也是以批量或一时一次模式进行预测的可能性。

批量与原子模式

通常,通过大量原因(分支可预测性,CPU缓存,线性代数库优化等),大量进行预测(同时许多情况)更有效。在这里,我们看到一些具有很少功能的设置,独立于估计器选择,批量模式总是更快,其中一些是1到2个数量级:

为了对您的案例进行基准测试,您可以n_features在此示例中简单地更改 参数: 预测延迟。这应该给你估计预测延迟的数量级。

特征数量的影响

显然,当功能的数量增加时,每个示例的内存消耗也会增加。实际上,对于中号具有ñ特征的实例的矩阵,空间复杂性在。从计算角度来看,这也意味着基本操作的数量(例如,线性模型中矢量矩阵乘积的乘法)也增加了。以下是预测延迟与特征数量的变化图:

总体来说,您可以预期预测时间至少与特征数量线性增加(非线性情况可能会发生,取决于全局内存占用和估计)。

输入数据表示的影响

Scipy提供针对存储稀疏数据进行优化的稀疏矩阵数据结构。稀疏格式的主要特点是您不存储零,所以如果您的数据稀疏,那么您使用的内存更少。稀疏(CSR或CSC)表示中的非零值将仅占用平均一个32位整数位置+ 64位浮点值+矩阵中每行或列的另外32位。在密集(或稀疏)线性模型上使用稀疏输入可以加速预测相当多的一点,因为只有非零值特征影响点积,从而影响模型预测。因此,如果在1e6维空间中有100个非零,则只需要100次乘法和加法操作而不是1e6。

然而,密集表示的计算可以利用BLAS中的高度优化的向量操作和多线程,并且倾向于导致更少的CPU高速缓存未命中。因此,稀疏输入表示的稀疏度应通常相当高(10%非零最大值,要根据硬件进行检查)比在具有多个CPU和优化的BLAS实现的机器上的密集输入表示更快。

以下是测试输入稀疏度的示例代码:

 

def  sparsity_ratio X ):
    return  1.0  -  np count_nonzero X  /  浮动X 塑造[ 0 ]  *  X 塑造[ 1 ])
的打印“输入稀疏度比:”  sparsity_ratio X ))

根据经验,您可以考虑如果稀疏比大于90%,您可能会从稀疏格式中受益。查看Scipy的稀疏矩阵格式文档 ,了解有关如何构建(或将数据转换为)稀疏矩阵格式的更多信息。大多数时候CSRCSC格式最好。

模型复杂性的影响

一般来说,当模型复杂度增加时,预测能力和潜伏期应该增加。增加预测能力通常很有意思,但对于许多应用,我们最好不要太多地增加预测延迟。我们现在将对不同家庭的监督模式回顾这一想法。

对于sklearn.linear_model(例如Lasso,ElasticNet,SGDClassifier / Regressor,Ridge&RidgeClassifier,PassiveAgressiveClassifier / Regressor,LinearSVC,LogisticRegression ...),在预测时间应用的决策函数是相同的(点积),因此延迟应该是等效的。

下面是使用的例子 sklearn.linear_model.stochastic_gradient.SGDClassifier与 elasticnet处罚。正则化强度由alpha参数全局控制。在足够高的情况下alpha,可以增加l1_ratio参数,elasticnet以在模型系数中强制执行各种稀疏程度。这里的较高稀疏度被解释为较少的模型复杂度,因为我们需要更少的系数来充分描述它。当然,稀疏性依次影响预测时间,因为稀疏点积乘以时间大致与非零系数的数目成比例。

对于sklearn.svm具有非线性内核的算法系列,延迟与支持向量的数量相关(越快越多)。随着SVC或SVR模型中的支持向量的数量,延迟和吞吐量应该渐近地增长。内核也将影响延迟,因为它用于计算每个支持向量一次输入向量的投影。在下图nusklearn.svm.classes.NuSVR,使用参数 来影响支持向量的数量。

对于sklearn.ensemble树木(例如RandomForest,GBT,ExtraTrees等)树木的数量及其深度起着最重要的作用。延迟和吞吐量应与树木数量呈线性关系。在这种情况下,我们直接使用n_estimators参数sklearn.ensemble.gradient_boosting.GradientBoostingRegressor

在任何情况下都应警告,如上所述,降低模型复杂性可能会损害精度。例如,可以用快速线性模型来处理非线性可分离问题,但是在该过程中预测能力将很可能受到影响。

特征提取延迟

大多数scikit学习模型通常非常快,因为它们可以通过编译的Cython扩展或优化的计算库实现。另一方面,在许多现实世界的应用中,特征提取过程(即将原始数据像数据库行或网络数据包转换为数字数组)控制整体预测时间。例如在路透社文本分类任务中,根据所选择的模型,整个准备(读取和解析SGML文件,将文本标记化并将其散列为公共向量空间)的时间比实际预测代码的时间长100到500倍。

因此,在许多情况下,建议您仔细地对特征提取代码进行时间和配置,因为当您的整体延迟对您的应用程序来说太慢时,可能是开始优化的好地方。

 

预测吞吐量

关于在生产系统上调整尺寸的另一个重要指标是吞吐量,即在一定时间内可以做出的预测数量。这是来自“ 预测延迟”示例的一个基准, 用于衡量合成数据的多个估计量的此数量:

这些吞吐量在单个进程中实现。增加应用程序吞吐量的一个显而易见的方法就是产生一些共享相同模型的附加实例(通常是由于GIL而在Python中的进程 )。还可能添加机器来传播负载。关于如何实现这一点的详细解释超出了本文档的范围。

 

提示和技巧

线性代数库

由于scikit学习在很大程度上依赖于Numpy / Scipy和线性代数,因此,对这些库的版本进行明确的保护是有意义的。基本上,您应该确保使用优化的BLAS / LAPACK库构建Numpy 。

并非所有型号都受益于优化的BLAS和Lapack实现。对于基于实例模型(随机)决策树通常不依赖BLAS在其内部循环调用,也不支持向量机的内核(SVCSVR, NuSVCNuSVR)。另一方面,使用BLAS DGEMM调用(via numpy.dot)实现的线性模型通常将从调优的BLAS实现中获益巨大,并导致非优化BLAS的数量级加速。

您可以使用以下命令显示您的NumPy / SciPy / scikit学习安装使用的BLAS / LAPACK实现:

from numpy.distutils.system_info import get_info
print(get_info('blas_opt'))
print(get_info('lapack_opt'))

优化的BLAS / LAPACK实现包括:Atlas(需要通过在目标机器上重建进行硬件特定调整)OpenBLASMKLApple Accelerate和vecLib框架(仅适用于OSX)

更多信息可以在Scipy安装页面 和 Daniel Nouri的博客文章中找到,该 文章对Debian / Ubuntu有一些很好的一步一步的安装说明。

 

警告: 多线程BLAS库有时与Python的冲突 multiprocessing模块,用于例如通过GridSearchCV和采取其他大多数估计n_jobs参数(以下除外SGDClassifierSGDRegressorPerceptron, PassiveAggressiveClassifier和基于树的方法,如随机森林)。在OpenMP支持的情况下,Apple的Accelerate和OpenBLAS也是如此。

除了scikit学习,NumPy和SciPy也在内部使用BLAS,如前所述。

如果您遇到挂起的子进程,n_jobs>1或者n_jobs=-1确保您具有单线程BLAS库,或设置n_jobs=1或升级到具有新版本的Python 3.4 multiprocessing ,则应免于此问题。

 

模型压缩

scikit学习中的模型压缩只关注线性模型。在这种情况下,这意味着我们要控制模型稀疏度(即模型向量中的非零坐标数)。将模型稀疏度与稀疏输入数据表示相结合是一个好主意。

这是示例使用该sparsify()方法的示例代码:

clf  =  SGDRegressor penalty = 'elasticnet'  l1_ratio = 0.25 
clf fit X_train  y_train sparsify ()
clf 预测X_test 

在这个例子中,我们更喜欢elasticnet惩罚,因为它通常是模型紧凑性和预测能力之间的一个很好的妥协。还可以进一步调整l1_ratio参数(结合正则化强度alpha)来控制这种权衡。

当模型和输入稀疏(分别为0.000024和0.027400非零系数比)时,合成数据的典型基准产生的延迟降低> 30%。您的里程可能会因您的数据和模型的稀疏性和大小而有所不同。此外,为了减少部署在生产服务器上的预测模型的内存使用,扩展可能非常有用。

模型重塑

模型重新组合在于仅选择一部分可用功能以适应模型。换句话说,如果模型在学习阶段丢弃特征,我们可以从输入中删除这些特征。这有几个好处。首先,它减少了模型本身的内存(因此是时间)的开销。一旦知道要从上一次运行中保留哪些功能,它也允许在流水线中丢弃显式的特征选择组件。最后,它可以通过不收集和构建模型丢弃的功能来帮助减少数据访问和特征提取层中上游的处理时间和I / O使用。例如,如果原始数据来自数据库,则可以通过使查询返回较轻的记录,从而可以编写更简单和更快速的查询或减少I / O使用。在这一刻,重塑需要在scikit学习中手动执行。CSR在稀疏输入(特别是格式)的情况下, 通常不能生成相关的特征,使其列为空。

  • 无标签