为什么在 R 的 optim 中添加 L1 惩罚会使事情变慢很多(相对于没有惩罚或 L2)?

机器算法验证 r 优化 套索
2022-03-27 09:26:02

我正在使用 optim 的 BFGS 实现进行一些优化。目标函数实际上是一种计算算法,而不仅仅是数学。我发现当我添加 L1 惩罚时,事情会慢很多。为什么会这样?L1有什么东西可以减慢速度吗?glmnet那么LASSO 是如何实现这么快的呢?

快速的谷歌搜索出现了一个名为“lbfgs”的包,它“找到目标的最优值加上问题参数的 L1 范数”,“这些优化例程的快速且内存有效的实现,特别适用于高-维度问题。” 我应该寻找这样的解决方案吗?

2个回答

我猜想添加 L1 惩罚会显着减慢速度的原因是 L1 惩罚不可微分(即绝对值),而 L2 惩罚是。这意味着函数的表面不会是光滑的,因此标准的拟牛顿法在处理这个问题时会遇到很多麻烦。回想一下,考虑准牛顿方法的一种方法是,它对函数进行二次逼近,然后初始提议将是该逼近的最大值。如果二次近似与目标函数匹配得相当好,我们应该期望提案接近最大值(或最小值,取决于您如何看待世界)。但是如果你的目标函数是不可微分的,这个二次近似可能会很糟糕,

如果你找到了一个为 L1 惩罚实现 BFGS 的 R 包,一定要试试。一般来说,BFGS 是一种非常通用的优化算法。与任何通用算法一样,会有很多特殊情况表现不佳。专门针对您的问题量身定制的算法显然应该做得更好(假设该软件包与作者声称的一样好:我还没有听说过 lbfgs,但是我还没有听说过很多很棒的东西。更新:我已经使用了R的lbfgs包,他们的L-BFGS实现非常好!我还没有使用它的OWL-QN算法,这就是OP所指的)。

如果它不适合您,您可能想尝试使用 R 的 optim 的“Nelder-Mead”方法。它不使用导数进行优化。因此,在平滑函数上它通常会更慢,但在像你这样的不平滑函数上会更稳定。

我不知道为什么当你添加一个问题时你的问题变慢了L1惩罚。这可能取决于(1)问题是什么;(2) 你是如何编码的;(3) 您正在使用的优化方法。

我认为您的问题有一个“不言而喻的答案”:数值问题的最有效解决方案通常是量身定制的。通用算法就是这样:通用。针对特定问题的专门解决方案往往会更好地工作,因为我们可以对特定问题的呈现方式及其分析师已知的特定属性进行观察。对于您关于 的具体问题glmnet,它有许多“技巧”,使其高效 - 对于它试图解决的特定问题!Journal of Statistical Software 论文提供了详细信息

  1. 它对所有模型(弹性网络、岭回归而不仅仅是 LASSO)的优化使用循环坐标下降,这是解决这个问题的一个很好的方法。
  2. 系数是沿路径计算的,范围为λ价值观。因此,不要在响应面上徘徊以获取正则化参数的单个值λ,它从最大值移动到最小值,使用先前解的系数估计作为起点。这利用了系数估计值从较小值上升到较大值的事实λ减少;它不必从随机初始化的开始一遍又一遍地重新解决相同的问题,就像使用标准优化例程的幼稚实现那样。

它是用 FORTRAN 编码的。

L-BFGS 是一种内存有限的 BFGS 算法。虽然它有一些技巧可以使其在某些问题上比标准 BFGS 更有效,但尚不清楚它解决的问题是否与手头的特定问题有任何关系。L-BFGS 也是其中的一种选择optim,所以我不确定您为什么需要额外的软件包。

请注意,BFGS 取决于导数,当未提供解析形式时,这些导数由有限差分计算。这可能是您遇到问题的地方,因为L1惩罚不是处处可微的。这不仅意味着您可能不会将 LASSO 系数精确估计为 0,而且它可能会对从迭代到迭代的更新造成严重破坏。