如何加速随机梯度下降?

2 投票
1 回答
2550 浏览
提问于 2025-04-18 09:09

我正在尝试用L1惩罚来拟合一个回归模型,但在Python中找不到一个能在合理时间内完成的实现。我手头的数据大约有10万行和500列(顺便说一下,其中几个变量之间的相关性很高),但是在这个数据上运行sklearn的Lasso实现需要超过12个小时才能拟合一个模型(我其实不太确定确切的时间,我已经让它过夜运行好几次,但从来没有完成过)。

我在考虑使用随机梯度下降来加快这个过程。然而,sklearn中的SGDRegressor实现,在我使用10万次迭代时,也要花大约8个小时才能拟合。这看起来迭代次数相对较少(而且文档中甚至建议模型通常需要大约100万次迭代才能收敛)。

我在想是不是我哪里做错了,导致拟合时间这么长。我听说SGD通常因为效率高而被使用(大约是O(n_iter * n_samp * n_feat)的复杂度),但到目前为止,我还没有看到比Lasso有明显的改进。

为了加快速度,我尝试了:

  1. 减少迭代次数,但这通常会导致结果很糟糕,因为模型还没有收敛。
  2. 增加步长(同时减少迭代次数),但这通常会导致损失函数失控。
  3. 改变学习率的类型(从反比例缩放改为基于迭代次数的量),但这似乎也没有太大改善。

有没有什么建议可以加快这个过程?看起来partial_fit可能是答案的一部分,尽管关于这个的文档有点稀少。我希望能在不等三天的情况下拟合这些模型。

1 个回答

3

使用partial_fit并不是解决问题的方法。它不会加快任何速度,反而可能会让事情变得更慢。

这个实现方式其实已经很高效了,我很惊讶你会说收敛速度慢。我觉得你可能进行了太多次迭代。你有没有关注一下目标值是如何下降的?

通常调整初始学习率可以提高速度。你的数据集应该不会是个问题。我不确定SGDRegressor内部是否会这样处理,但把你的目标值调整到单位方差可能会有帮助。

你可以试试vopal wabbit,这是一个更快的实现,但其实不一定非得用它。

撰写回答