2017-11-18 157 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