Scikit-learn:弹性网络接近岭回归

3

弹性网络被认为是岭回归(L2正则化)和套索(L1正则化)之间的混合体。然而,即使l1_ratio为0,我得到的结果也不同于岭回归。我知道岭回归使用梯度下降,而弹性网络使用坐标下降,但最优解应该是相同的,不是吗?此外,我发现弹性网络经常无明显原因地出现收敛警告,而lasso和ridge则没有。以下是代码片段:

from sklearn.datasets import load_boston
from sklearn.utils import shuffle
from sklearn.linear_model import ElasticNet, Ridge, Lasso
from sklearn.model_selection import train_test_split

data = load_boston()
X, y = shuffle(data.data, data.target, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=43)
alpha = 1

en = ElasticNet(alpha=alpha, l1_ratio=0)
en.fit(X_train, y_train)
print('en train score: ', en.score(X_train, y_train))

rr = Ridge(alpha=alpha)
rr.fit(X_train, y_train)
print('rr train score: ', rr.score(X_train, y_train))

lr = Lasso(alpha=alpha)
lr.fit(X_train, y_train)
print('lr train score: ', lr.score(X_train, y_train))
print('---')
print('en test score: ', en.score(X_test, y_test))
print('rr test score: ', rr.score(X_test, y_test))
print('lr test score: ', lr.score(X_test, y_test))
print('---')
print('en coef: ', en.coef_)
print('rr coef: ', rr.coef_)
print('lr coef: ', lr.coef_)

即使l1_ratio为0,弹性网的训练和测试得分也接近套索得分(而不是岭回归得分,这可能出乎你的意料)。此外,弹性网似乎会抛出一个ConvergenceWarning警告,即使我增加max_iter(甚至增加到1000000也没有效果)和tol(0.1仍然会出错,但0.2不会)。增加alpha(如警告建议)也没有效果。

2个回答

4

根据@sascha的答案,我们可以将两个模型的结果进行匹配:

import sklearn
print(sklearn.__version__)

from sklearn.linear_model import Ridge, ElasticNet
from sklearn.datasets import load_boston

dataset = load_boston()
X = dataset.data
y = dataset.target

f = Ridge(alpha=1, 
          fit_intercept=True, normalize=False, 
          copy_X=True, max_iter=1000, tol=1e-4, random_state=42, 
          solver='auto')
g = ElasticNet(alpha=1/X.shape[0], l1_ratio=1e-16, 
               fit_intercept=True, normalize=False, 
               copy_X=True, max_iter=1000, tol=1e-4, random_state=42, 
               precompute=False, warm_start=False, 
               positive=False, selection='cyclic')

f.fit(X, y)
g.fit(X, y)

print(abs(f.coef_ - g.coef_) / abs(f.coef_))

输出:

0.19.2
[1.19195623e-14 1.17076625e-15 3.25973465e-13 1.61694280e-14
 4.77274767e-15 4.15332538e-15 6.15640568e-14 1.61772832e-15
 4.56125088e-14 5.44320605e-14 8.99189018e-15 2.31213025e-15
 3.74181954e-15]

为了进一步推广对于任何非零的alpha=a,Ridge(alpha=a, ...)和ElasticNet(alpha=a/X.shape[0], ...)。 - hermidalc

3

请阅读文档。然后您会发现这些都没有使用梯度下降算法,更重要的是:

岭回归

enter image description here

enter image description here

弹性网络

enter image description here enter image description here

当替换 a=1, p=0 时,可以看出:

  • ElasticNet 比 Ridge 多了一个与样本相关的因子
  • ElasticNet 在 l2-term 中多了一个 1/2 的因子

为什么会有不同的模型?可能是因为 sklearn 遵循了典型的 基于 R 实现的 glmnet

此外,当进行混合范数优化时,如果我强制使用非混合范数(例如 l1=0),那么在专门针对两种非混合优化问题的求解器存在时,可能会出现数值问题。

幸运的是,sklearn 还 对此做出了说明:

目前,除非您提供自己的 alpha 序列,否则 l1_ratio <= 0.01 不可靠。


你的帖子意味着当 l1_ratio=0 时,弹性网络 alpha 应该除以 n_samples,以匹配岭回归相同的优化问题。这确实是这种情况,此时弹性网络和岭回归会导致相同的系数。然而,弹性网络仍然会出现收敛警告。我不知道为什么:系数与岭回归相同(所以已经收敛),而岭回归没有出现此警告。你还提到 l1_ratio <= 0.01 不可靠,除非你提供自己的 alpha 序列 (?)。 - wouterdobbels
我已经提供了自己的alpha(如果您不使用ElasticnetCV,则只能传递一个),但似乎l1_ratio = 0的某些内容仍然无法按预期工作。从ElasticnetCV的文档中,我看到他们建议使用l1_ratio序列[.1,.5,.7,.9,.95,.99,1],明显避免l1_ratio = 0... - wouterdobbels
不同的优化器,不同的假设,不同的数值问题。使用l1_ratio=0由特殊的优化器进行处理(优化问题更加简单),因此不建议使用elasticnet。 - sascha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接