加快sklearn逻辑回归

时间:2014-01-03 00:53:05

标签: python logistic-regression scikit-learn

我正在尝试使用LogisticRegression中的sklearn构建一个模型,该模型具有几千个要素和大约60,000个样本。我正在尝试适应模型,它现在已经运行了大约10分钟。我正在运行它的机器有几千兆字节的RAM和几个核心可供使用,我想知道是否有任何方法可以加快这个过程

修改 这台机器有24个核心,这里是top的输出,以便了解内存

Processes: 94 total, 8 running, 3 stuck, 83 sleeping, 583 threads      20:10:19
Load Avg: 1.49, 1.25, 1.19  CPU usage: 4.34% user, 0.68% sys, 94.96% idle
SharedLibs: 1552K resident, 0B data, 0B linkedit.
MemRegions: 51959 total, 53G resident, 46M private, 676M shared.
PhysMem: 3804M wired, 57G active, 1042M inactive, 62G used, 34G free.
VM: 350G vsize, 1092M framework vsize, 52556024(0) pageins, 85585722(0) pageouts
Networks: packets: 172806918/25G in, 27748484/7668M out.
Disks: 14763149/306G read, 26390627/1017G written.

我正在尝试使用以下

训练模型
classifier = LogisticRegression(C=1.0, class_weight = 'auto')
classifier.fit(train, response)

train的行数大约为3000(所有浮点数),response中的每一行都是01。我有大约50,000个观察结果

5 个答案:

答案 0 :(得分:13)

更新 - 2017年:

在当前版本的scikit-learn中,LogisticRegression()现在有n_jobs参数来使用多个核心。

但是,用户指南的实际文本表明,在计算的后半部分仍然只使用多个核心。自本次更新起,修订后的LogisticRegression用户指南现在表示njobs选择了交叉验证循环中使用的" CPU内核数量"而原始回复中引用的其他两个项目RandomForestClassifier()RandomForestRegressor()都表明njobs指定"并行运行的作业数量为适合和预测&# 34 ;.换句话说,这里的措辞中的故意对比似乎指出njobs中的LogisticRegression()参数,虽然现在已经实现,但并未真正完全或以同样的方式实现,如同其他两个案例。

因此,尽管现在可以通过使用多个内核来加速LogisticRegression(),但我猜测它可能与所使用的内核数量成比例地非常线性,因为它听起来像最初" fit"步骤(算法的前半部分)可能不适合并行化。


原始答案:

在我看来,看起来这里的主要问题不是记忆,而是你只使用一个核心。根据top,您正在以4.34%的负载加载系统。如果您的逻辑回归过程垄断了24个中的1个核心,则结果为100/24 = 4.167%。据推测,剩下的0.17%会影响您在机器上运行的其他任何进程,并且允许它们占用额外的0.17%,因为它们被系统安排在第二个不同核心上并行运行。

如果您按照以下链接查看scikit-learn API,您会发现某些整体方法(例如RandomForestClassifier()RandomForestRegressor())有一个名为{{的输入参数1}}直接控制包将尝试并行运行的核心数。您正在使用的课程LogisticRegression()没有定义此输入。 scikit-learn的设计者似乎创建了一个通常在类之间非常一致的接口,因此如果没有为给定的类定义特定的输入参数,则可能意味着开发人员根本无法找到实现为该类提供有意义的选项。情况可能是逻辑回归算法不能很好地适用于并行化;也就是说,本来可能实现的潜在speedup并不足以证明用并行架构来实现它。

假设是这种情况,那么不,你可以做的不是让你的代码变得更快。如果底层库函数没有被设计为能够利用它们,那么24个核心对您没有帮助。

答案 1 :(得分:9)

尝试减少数据集大小和更改容差参数。例如,您可以尝试classifier = LogisticRegression(tol = 0.1)

答案 2 :(得分:6)

值得注意的是,现在LogisticRegression()接受num_jobs作为输入,默认为1。

会对已接受的答案发表评论,但还不够。

答案 3 :(得分:5)

sklearn中LogisticRegressin的默认解算器是liblinear,它是普通数据集的合适解算器。对于大型数据集,请尝试随机梯度下降求解器,例如sag

model = LogisticRegression(solver='sag')

答案 4 :(得分:2)

尝试更改您的求解器。 documentation 表示 scikit-learn 有 5 种不同的求解器可供您使用('liblinear'、'sag'、'saga'、'newton-cg'、'lbfgs')

对于小型数据集,“liblinear”(曾经是默认值)是一个不错的选择,而对于大型数据集,“sag”和“saga”更快。

对于多类问题,只有‘newton-cg’、‘sag’、‘saga’和‘lbfgs’处理多项式损失; “liblinear”仅限于一对休息方案。

import time
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

# Set training and validation sets
X, y = make_classification(n_samples=1000000, n_features=1000, n_classes = 2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=10000)

# Solvers
solvers = ['liblinear', 'newton-cg', 'sag', 'saga', 'lbfgs']

for sol in solvers: 
    start = time.time()
    logreg = LogisticRegression(solver=sol)
    logreg.fit(X_train, y_train)
    end = time.time()
    print(sol + " Fit Time: ",end-start)

输出(来自 16GB 4 核 MacBook):

enter image description here

为问题选择合适的求解器可以节省大量时间(代码改编自 here)。要确定哪种求解器适合您的问题,您可以查看 documentation 中的表格了解更多。

solver table

此外,由于您没有进行多类分类,您的模型可能无法很好地并行化。根据 scikit-learn 文档,n_jobs 是在 multi_class=’ovr’ 时并行化类时使用的 CPU 内核数。