为何statsmodels和sklearn返回的Lasso估计结果存在差异
Lasso跨库估计结果不一致成因分析
核心成因
- 收敛终止阈值差异
你仅为scikit-learn的Lasso显式设置了tol=1e-12的严格收敛阈值,但statsmodels的fit_regularized默认收敛阈值为1e-4,精度远低于前者。在多重共线性、小样本、p>n三类场景下,Lasso的损失平面在最优解附近非常平缓,收敛阈值的微小差异会导致迭代停止时点不同,最终参数结果出现偏差,尤其会影响绝对值接近正则化阈值的系数是否被判定为0。你给出的示例中最后一个系数在sklearn输出为0.0065、statsmodels输出为0,就属于这类情况。 - 坐标下降迭代规则差异
两个库的坐标下降法实现的特征更新顺序、迭代逻辑存在区别:scikit-learn默认按固定顺序循环更新所有特征,statsmodels的实现会根据特征梯度大小动态调整更新顺序。在损失平面存在平坦区域的场景下,不同更新顺序会使迭代停在平坦区域的不同位置,产生数值层面的有效解差异,这和Tibshirani证明的“几乎必然唯一”理论不冲突——理论唯一的前提是无限精度计算,实际浮点运算的误差会使合法解落在极小的平坦区间内。 - 正则化参数定义与截断规则差异
- 两个库的损失函数缩放规则存在细微区别:scikit-learn的Lasso损失为
(1/(2n))||y-Xw||² + alpha*||w||₁,statsmodels的fit_regularized损失为(1/n)||y-Xw||² + alpha*L1_wt*||w||₁,你需要确认alpha的换算是否完全匹配两边的损失定义。 - 两个库的后置零截断规则不同:scikit-learn会默认将绝对值小于
1e-4 * alpha的系数强制置零,statsmodels的截断阈值更宽松,进一步放大了小系数的输出差异。
- 两个库的损失函数缩放规则存在细微区别:scikit-learn的Lasso损失为
p>n场景下未达到预期稀疏性的原因
不存在“p=25、n=20时Lasso必然将5个系数置零”的结论,Lasso的稀疏性完全由正则化强度、数据信噪比、特征相关性共同决定:如果你的正则化强度设置偏低,或者特征之间存在强相关性,就会出现非零系数数量超过n的情况。此外收敛精度不足也会导致部分应该被置零的系数保留极小的非零值。
修复方案
- 调用statsmodels的
fit_regularized时显式设置tol=1e-12、L1_wt=1.0,和scikit-learn的配置完全对齐 - 显式对两个库的输出做统一截断:将绝对值小于
1e-6的系数强制置零后再做对比 - 重新核对alpha的换算逻辑,确保两边的正则化强度完全等价
内容的提问来源于stack exchange,提问作者buffalo
相关产品推荐
相关产品推荐

