2016-07-25 28 views
3

在Ridge迴歸中,我們正在求解Ax=bL2正則化。直接計算由下式給出:嶺迴歸:Scikit學習與直接計算不匹配的alpha> 0

X =(A Ť A +阿爾法* I)-1Ť b

我已經看過的scikit學習代碼他們確實執行相同的計算。但是,我似乎無法得到相同的結果alpha > 0

重現此最小代碼。

import numpy as np 
A = np.asmatrix(np.c_[np.ones((10,1)),np.random.rand(10,3)]) 
b = np.asmatrix(np.random.rand(10,1)) 
I = np.identity(A.shape[1]) 
alpha = 1 
x = np.linalg.inv(A.T*A + alpha * I)*A.T*b 
print(x.T) 
>>> [[ 0.37371021 0.19558433 0.06065241 0.17030177]] 

from sklearn.linear_model import Ridge 
model = Ridge(alpha = alpha).fit(A[:,1:],b) 
print(np.c_[model.intercept_, model.coef_]) 
>>> [[ 0.61241566 0.02727579 -0.06363385 0.05303027]] 

對於我能做些什麼來解決這種差異有什麼建議嗎?

回答

0

這種修改似乎產生相同的結果的直接版本和numpy的版本:

import numpy as np 
A = np.asmatrix(np.random.rand(10,3)) 
b = np.asmatrix(np.random.rand(10,1)) 
I = np.identity(A.shape[1]) 
alpha = 1 
x = np.linalg.inv(A.T*A + alpha * I)*A.T*b 
print (x.T) 


from sklearn.linear_model import Ridge 
model = Ridge(alpha = alpha, tol=0.1, fit_intercept=False).fit(A ,b) 

print model.coef_ 
print model.intercept_ 

看來這種差異的主要原因是該類Ridge_BaseRidge類具有參數fit_intercept=True(通過繼承)(source

這是在將矩陣傳遞給_solve_cholesky函數之前應用數據居中過程。

下面是ridge.py,做它

 X, y, X_mean, y_mean, X_std = self._center_data(
     X, y, self.fit_intercept, self.normalize, self.copy_X, 
     sample_weight=sample_weight) 

而且,似乎您試圖暗中加1的中柱佔攔截線。如您所見,如果您指定fit_intercept=False

附錄:Ridge類是否實際實現直接公式?

它取決於參數solver的選擇。

實際上,如果您沒有在Ridge中指定solver參數,則默認採用solver='auto'(內部採用solver='cholesky')。這應該等同於直接計算。

嚴格地說,_solve_cholesky使用numpy.linalg.solve而不是numpy.inv。但它可以很容易地檢查了

np.linalg.solve(A.T*A + alpha * I, A.T*b) 

得到一樣

np.linalg.inv(A.T*A + alpha * I)*A.T*b 
+0

感謝您的詳細答覆。這確實解決了'fit_intercept = False'。然而,在我的例子中,我確實需要'intercept',因此我在直接計算中將1的列添加到我的'A'矩陣中。當我通過使用'A [:,1:]'傳遞給'Ridge'時,我放下1的列。所以即使我運行'model = Ridge(alpha = alpha,normalize = False,fit_intercept = True,solver =「cholesky」)。fit(A [:,1:],b)' - 我無法獲得相同的結果。什麼時候你想'fit_intercept = True'的澄清? – amitkaps

+0

我相信你仍然可以保持行'A = np.asmatrix(np。c_ [np.ones((10,1)),np.random.rand(10,3)])'並設置'fit_intercept = False'。第一個係數不應該是攔截嗎? – JARS

+0

是的 - 就是這樣!應該想到它。仍然想知道爲什麼'normalize = False,fit_intercept = True'的做法不一樣。感謝你的幫助。 – amitkaps