【问题标题】:Speeding up sklearn logistic regression加速 sklearn 逻辑回归
【发布时间】:2014-01-20 14:13:50
【问题描述】:

我正在尝试使用sklearn 中的LogisticRegression 构建一个模型,该模型具有几千个特征和大约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 个观察结果

【问题讨论】:

  • 令人惊讶的是它花了这么长时间。你确定你的模型设置正确吗?
  • 你的特征向量的大小是多少?
  • 在您的机器上发布一些真实的统计数据? 1 GB 和 8 GB RAM 之间的差异非常大,2 核和 8 核之间的差异也是如此。更不用说在谈论单核小于 1 GB 的进程时,这些都不是很相关。
  • 我添加了一些编辑来解决其中一些 cmets。我展示了 RAM 的最高输出只是因为我不是唯一一个使用这台机器的人,所以我并不总是可以访问所有的物理内存,但看起来我应该有足够的

标签: python logistic-regression scikit-learn


【解决方案1】:

尝试更改您的求解器。 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):

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

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

【讨论】:

  • 多大是多大?大在什么意义上,特征数量或观察数量?文档似乎没有指定。
  • 虽然这可能不是一个有用的答案,但我认为如果训练时间太长的话会很重要。即使对于本博客 (towardsdatascience.com/…) 中带有 liblinear 的 MNIST,它也需要 2893.1 秒才能以 91.45% 的准确率运行。当solver = lbfgs时,运行时间为52.86秒,准确率为91.3%。
【解决方案2】:

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

model = LogisticRegression(solver='sag')

【讨论】:

  • newton-sq 怎么样,是不是更快?
【解决方案3】:

2017 年更新:

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

但是,用户指南的实际文本表明,多核仍仅在计算的后半部分使用。截至本次更新,LogisticRegression 的修订用户指南现在说njobs 选择“交叉验证循环期间使用的 CPU 内核数”,而原始响应中引用的其他两项 RandomForestClassifier() 和 @ 987654331@,两者都声明njobs 指定“适合和预测并行运行的作业数”。换句话说,这里措辞的有意对比似乎是在指出LogisticRegression() 中的njobs 参数虽然现在已实现,但并没有像其他两种情况那样完全或以相同的方式真正实现。

因此,虽然现在可以通过使用多个内核来稍微加快LogisticRegression(),但我的猜测是它可能不会与使用的内核数量成比例,因为这听起来像最初的“拟合”步骤(算法的前半部分)可能不适合并行化。


原答案:

在我看来,这里的主要问题似乎不是内存,而是您只使用一个内核。根据顶部,您正在以 4.34% 的速度加载系统。如果您的逻辑回归过程垄断了 24 个核心中的 1 个,那么结果为 100/24 = 4.167%。大概剩下的 0.17% 占您也在机器上运行的任何其他进程,并且它们被允许占用额外的 0.17%,因为它们被系统安排在第二个不同的核心上并行运行。

如果您点击下面的链接并查看 scikit-learn API,您会看到一些 ensemble 方法,例如 RandomForestClassifier()RandomForestRegressor() 有一个名为 n_jobs 的输入参数,它直接控制数字包将尝试在其上并行运行的内核数。您正在使用的类LogisticRegression() 没有定义此输入。 scikit-learn 的设计者似乎已经创建了一个在类之间通常非常一致的接口,所以如果没有为给定的类定义特定的输入参数,这可能意味着开发人员根本无法找到实现以对该类有意义的方式选择。逻辑回归算法可能根本不适合并行化。即,可能已经实现的潜在 speedup 还不足以证明使用并行架构实现它是合理的。

假设是这种情况,那么不,您无法做太多事情来使您的代码运行得更快。如果底层库函数根本无法利用它们,那么 24 核对您没有帮助。

【讨论】:

  • 我想我希望有一种方法可以并行化,但看起来你是正确的,因为没有好的方法可以做到这一点。我会研究其他形式的分类
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    尝试减小数据集大小并更改容差参数。比如你可以试试classifier = LogisticRegression(tol = 0.1)

    【讨论】:

      猜你喜欢
      • 2015-05-04
      • 2016-03-06
      • 2021-03-11
      • 2013-12-24
      • 2019-07-26
      • 1970-01-01
      • 2014-01-19
      • 2020-07-04
      • 2014-09-16
      相关资源
      最近更新 更多