You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLMNET中两种数学等价的自适应Lasso方法结果不一致的原因及解决办法咨询

GLMNET中两种数学等价的自适应Lasso方法结果不一致的原因及解决办法咨询

我最近在研究自适应Lasso的两种实现思路,理论上它们在数学上是完全等价的,而且我用Python的asgl库验证过,两种方法确实能得到完全相同的结果。但当我用R的glmnet包实现时,却得到了差异很大的结果,想请教大家这是为什么,以及该怎么调整才能让glmnet的两种实现也输出一致的结果?

两种等价的自适应Lasso实现方法

自适应Lasso的第一种实现思路是:

  1. 先训练一个无惩罚的回归模型,提取出系数betas
  2. 定义权重w=1/abs(beta)
  3. 将这些权重代入自适应Lasso模型中训练,得到最终系数beta2

另一种等价的实现思路是:

  1. 先训练无惩罚回归模型得到beta,然后计算X2 = X*beta(这里是按列逐个元素相乘)
  2. 用X2训练普通Lasso模型,得到系数beta3
  3. 对系数进行重新缩放:beta3 = beta3 * beta

这两种方法的数学等价性我已经通过Python的asgl库验证过,但用R的glmnet包实现时,两种方法的结果却相差很大。

下面是我分别用Python和R写的实现代码:

Python实现(两种方法结果一致)

from sklearn.datasets import make_regression
from asgl import Regressor
import numpy as np

X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, bias=10, noise=5, random_state=42)

# 第一种方法:先无惩罚回归,再用权重做自适应Lasso
model = Regressor(model='lm', penalization=None)
model.fit(X, y)
beta = model.coef_

# 第二种方法:构造X2后训练Lasso再缩放
X2 = X * beta
model = Regressor(model='lm', penalization='lasso', lambda1=0.1)
model.fit(X2, y)
beta2 = model.coef_ * beta

# 第一种方法的自适应Lasso实现
model = Regressor(model='lm', penalization='alasso', lambda1=0.1, individual_weights=1/np.abs(beta))
model.fit(X, y)
beta3 = model.coef_

# 此时beta2和beta3结果几乎完全一致

R的glmnet实现(两种方法结果差异大)

library(glmnet)

set.seed(42)
n <- 1000  # 样本数
p <- 10    # 特征数

# 生成模拟数据
X <- matrix(rnorm(n * p), nrow = n)
true_coef <- rep(0, p)
true_coef[1:5] <- rnorm(5)
y <- X %*% true_coef + 10 + rnorm(n, sd = 5) 

# 第一步:训练无惩罚模型提取系数
lm_model <- lm(y ~ X)
beta <- coef(lm_model)[-1]  # 去掉截距项

# 第二种方法:构造X2后训练Lasso再缩放
X2 <- sweep(X, 2, beta, "*") 
lambda1 = 0.1

lasso_model <- glmnet(X2, y, alpha = 1, lambda = lambda1, standardize = FALSE)
beta2 <- as.vector(coef(lasso_model, s = lambda1)[-1])
beta2 <- unname(beta2 * beta)

# 第一种方法:用penalty.factor实现自适应Lasso
weights <- 1/(abs(beta)+1e-8)  # 加小值避免除以0
adaptive_lasso_model <- glmnet(X, y, alpha = 1, lambda = lambda1, penalty.factor = weights, standardize = FALSE)
beta3 <- as.vector(coef(adaptive_lasso_model, s = lambda1)[-1])

# 此时beta2和beta3结果差异很大

我的问题是:

  • 为什么用glmnet实现时两种方法会得到不同的结果?
  • 该怎么调整R的代码,才能让两种方法也输出一致的结果?

备注:内容来源于stack exchange,提问作者Álvaro Méndez Civieta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 20:04:37