2017-11-18 246 views
0

所以弹性网应该是岭回归(L2正则化)和套索(L1正则化)之间的混合。但是,即使l1_ratio是0,我也没有得到和脊一样的结果。我知道山脊使用梯度下降和弹性网使用坐标下降,但最优方法应该是相同的,不是吗?此外,我发现弹性网通常会引发ConvergenceWarnings,原因不明,而套索和脊线则不会。这里有一个片段:scikit学习:弹性网接近山脊

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不会)。增加α(如警告所示)也没有效果。

回答

1

只需阅读文档。这时你会发现,这些都不是使用梯度下降,更重要的是:

Ridge

enter image description here

enter image description here

Elastic Net

enter image description here enter image description here

其示出,用a=1, p=0时,即:

  • ElasticNet具有岭未发现对损失的顶部的一个更依赖采样因子
  • ElasticNet具有在L2-术语多一个1/2因子

为什么不同型号?可能是因为sklearn遵循规范/原创R-based implementation glmnet

此外我不会惊讶地看到数值问题时做混合范数优化,而我强迫像l1 = 0这样的非混合范数,特别是当有非混合优化问题的专用求解器时。

幸运的是,即使sklearn has to say something about it

目前,l1_ratio < = 0.01是不可靠的,除非你提供你自己的阿尔法序列。

+0

您的文章意味着,当l1_ratio = 0,则弹性净阿尔法应通过N_SAMPLES次划分,以匹配相同的优化问题看成岭侧。事实确实如此,在这种情况下,弹性网和脊导致相同的系数。 但是,弹性网仍然存在ConvergenceWarning。我不明白为什么:系数与脊线相同(所以它们会聚),脊线不会给出警告。你还提到,除非你提供你自己的alpha序列(?),否则l1_ratio <= 0.01是不可靠的。 – wouterdobbels

+0

而且我确实提供了我自己的alpha(如果您不使用ElasticnetCV,只能传递一个),但它仍然像l1_ratio = 0那样无法正常工作。从ElasticnetCV的文档中,我看到他们建议使用[.1,.5,.7,...的l1_ratio序列。9,.95,.99,1],显然避免了l1_ratio = 0 ... – wouterdobbels

+0

不同的优化器,不同的假设,不同的数值问题。使用'''l1_ratio = 0'''被特殊的优化器覆盖(优化问题更容易),所以不推荐使用elasticnet。 – sascha