对于某些应用程序来说,实例的数量、特征的数量(或两者兼有)以及处理它们的速度对传统方法来说都是一个挑战。在这些情况下,scikit-learn 提供了一些选项,可以帮助系统实现规模化。
unset
unset
流式与增量训练
unset
unset
外部记忆(或“外存”)学习是一种从不能完全装入计算机主存(RAM)中的数据进行学习的技术。下面是一个设计来实现这一目标的系统概要:
-
-
-
增量学习在 scikit-learn 中有许多选择。虽然并非所有算法都能增量学习(即在不一次性看到所有实例的情况下学习),但所有实现了
partial_fit
API 的估计器都是候选项。
从小批量实例中增量学习(有时称为“在线学习”)的能力是外部记忆学习的关键,因为它保证了任何时候主存中只会有少量实例。
分类
sklearn.naive_bayes.MultinomialNB
sklearn.naive_bayes.BernoulliNB
sklearn.linear_model.Perceptron
sklearn.linear_model.SGDClassifier
sklearn.linear_model.PassiveAggressiveClassifier
sklearn.neural_network.MLPClassifier
回归
sklearn.linear_model.SGDRegressor
sklearn.linear_model.PassiveAggressiveRegressor
sklearn.neural_network.MLPRegressor
聚类
sklearn.cluster.MiniBatchKMeans
sklearn.cluster.Birch
分解 / 特征提取
sklearn.decomposition.MiniBatchDictionaryLearning
sklearn.decomposition.IncrementalPCA
sklearn.decomposition.LatentDirichletAllocation
sklearn.decomposition.MiniBatchNMF
预处理
sklearn.preprocessing.StandardScaler
sklearn.preprocessing.MinMaxScaler
sklearn.preprocessing.MaxAbsScaler
unset
unset
模型计算性能
unset
unset
对于某些应用程序来说,估计器的性能(主要是预测时的延迟和吞吐量)至关重要。尽管训练吞吐量也可能是一个关注点,但在生产环境中通常不如预测性能重要,因为训练通常是离线进行的。
-
预测延迟是指进行一次预测所需的时间(例如,以微秒为单位)。延迟通常被视为一个分布,运维工程师通常关注该分布在某一百分位数上的延迟(例如,第90百分位数)。
-
预测吞吐量是指在给定时间内软件能够进行的预测次数(例如,以每秒预测数为单位)。
性能优化的一个重要方面是它可能会影响预测精度。较简单的模型(例如,线性模型而非非线性模型,或参数较少的模型)通常运行更快,但不总是能够像更复杂的模型那样精确地考虑数据的特性。
批量模式与逐一模式
通常来说,批量进行预测(同时处理多个实例)效率更高,原因包括分支预测性、CPU缓存、线性代数库优化等。在特征较少的设置中,无论估计器的选择如何,批量模式总是更快,对于某些估计器,速度提升可达1到2个数量级:
特征数量的影响
显然,当特征数量增加时,每个实例的内存消耗也会增加。实际上,对于一个包含 𝑀 个实例和 𝑁 个特征的矩阵,其空间复杂度为 𝑂(𝑁𝑀)。从计算的角度来看,这也意味着基本操作的数量(例如,线性模型中的向量矩阵乘积的乘法)也会增加。以下是特征数量对预测延迟影响的图表:
总体而言,预测时间预计至少会随特征数量线性增加(非线性情况可能会发生,取决于全局内存占用和估计器)。
输入数据表示形式的影响
Scipy 提供了优化用于存储稀疏数据的稀疏矩阵数据结构。稀疏格式的主要特点是不存储零值,因此如果数据是稀疏的,则使用的内存会少得多。稀疏(CSR 或 CSC)表示中的非零值平均只占用一个32位整数位置+64位浮点值+每行或每列的额外32位。使用稀疏输入对密集(或稀疏)线性模型进行预测可以显著加快速度,因为只有非零值特征会影响点积,从而影响模型预测。
因此,如果在100万个维度空间中有100个非零值,则只需进行100次乘法和加法运算,而不是100万次。
然而,对于密集表示的计算,可以利用高度优化的向量操作和 BLAS 中的多线程,并且往往会导致更少的 CPU 缓存未命中。因此,在具有许多 CPU 和优化 BLAS 实现的机器上,稀疏输入表示要比密集输入表示更快,通常稀疏度需要相当高(非零值最多10%,具体取决于硬件)。
模型复杂度的影响
一般来说,当模型复杂度增加时,预测能力和延迟都会增加。提高预测能力通常是有趣的,但对于许多应用程序,我们不希望预测延迟过高。我们将针对不同类别的监督模型审查这一观点。
对于
sklearn.linear_model
(例如 Lasso、ElasticNet、SGDClassifier/Regressor、Ridge & RidgeClassifier、PassiveAggressiveClassifier/Regressor、LinearSVC、LogisticRegression…),在预测时应用的决策函数相同(一个点积),所以延迟应该是等效的。
以下是使用带有
elasticnet
惩罚的
SGDClassifier
的示例。正则化强度由
alpha
参数全局控制。在
alpha
充分高的情况下,可以通过增加
elasticnet
的
l1_ratio
参数来实施不同程度的模型系数稀疏性。更高的稀疏性被解释为模型复杂度更低,因为我们需要更少的系数来完全描述它。当然,稀疏性反过来影响预测时间,因为稀疏点积的时间大致与非零系数的数量成正比。
对于具有非线性核的
sklearn.svm
家族算法,延迟与支持向量的数量有关(越少越快)。延迟和吞吐量应该(渐近地)与 SVC 或 SVR 模型中的支持向量数量线性增长。核也会影响延迟,因为它用于对输入向量进行投影,每个支持向量都需要进行一次计算。在下图中,使用了
NuSVR
的
nu
参数来影响支持向量的数量。
对于树的
sklearn.ensemble
(例如 RandomForest、GBT、ExtraTrees 等),树的数量和深度起着最重要的作用。延迟和吞吐量应与树的数量线性缩放。在这种情况下,直接使用了
GradientBoostingRegressor
的
n_estimators
参数。
无论哪种情况,请注意,减少模型复杂度可能会影响准确性。比如,线性模型虽然预测速度快,但在处理非线性可分问题时,预测能力可能会显著下降。
特征提取延迟
大多数 scikit-learn 模型通常非常快,因为它们使用了编译的 Cython 扩展或优化的计算库。然而,在许多实际应用中,特征提取过程(即将原始数据如数据库行或网络包转换为 numpy 数组)决定了总体预测时间。
因此,在许多情况下,建议仔细计时和剖析您的特征提取代码,因为当总体延迟对于您的应用程序来说太慢时,特征提取代码可能是一个好的优化起点。
与
40000+
来自竞赛爱好者一起交流~