为什么sklearn(python)和matlab统计包中的LASSO不同?
我使用为什么sklearn(python)和matlab统计包中的LASSO不同?,python,matlab,linear-regression,scikit-learn,statistics,Python,Matlab,Linear Regression,Scikit Learn,Statistics,我使用LaasoCV从sklearn中选择最佳模型,并通过交叉验证进行选择。我发现如果我使用sklearn或matlab统计工具箱,交叉验证会给出不同的结果 我使用了matlab并复制了中给出的示例 得到这样的数字 然后我保存了matlab数据,并尝试从sklearn复制带有laaso_路径的图形,得到 虽然这两个数字有一些相似之处,但也有一些不同之处。据我所知,matlab中的参数lambda和sklearn中的alpha是相同的,但是在这个图中似乎有一些不同。有人能指出哪个是正确的还是我
LaasoCV
从sklearn
中选择最佳模型,并通过交叉验证进行选择。我发现如果我使用sklearn或matlab统计工具箱,交叉验证会给出不同的结果
我使用了matlab
并复制了中给出的示例
得到这样的数字
然后我保存了matlab
数据,并尝试从sklearn
复制带有laaso_路径的图形,得到
虽然这两个数字有一些相似之处,但也有一些不同之处。据我所知,matlab
中的参数lambda
和sklearn
中的alpha
是相同的,但是在这个图中似乎有一些不同。有人能指出哪个是正确的还是我遗漏了什么?此外,得到的系数也不同(这是我主要关心的)
Matlab代码:
rng(3,'twister') % for reproducibility
X = zeros(200,5);
for ii = 1:5
X(:,ii) = exprnd(ii,200,1);
end
r = [0;2;0;-3;0];
Y = X*r + randn(200,1)*.1;
save randomData.mat % To be used in python code
[b fitinfo] = lasso(X,Y,'cv',10);
lassoPlot(b,fitinfo,'plottype','lambda','xscale','log');
disp('Lambda with min MSE')
fitinfo.LambdaMinMSE
disp('Lambda with 1SE')
fitinfo.Lambda1SE
disp('Quality of Fit')
lambdaindex = fitinfo.Index1SE;
fitinfo.MSE(lambdaindex)
disp('Number of non zero predictos')
fitinfo.DF(lambdaindex)
disp('Coefficient of fit at that lambda')
b(:,lambdaindex)
import scipy.io
import numpy as np
import pylab as pl
from sklearn.linear_model import lasso_path, LassoCV
data=scipy.io.loadmat('randomData.mat')
X=data['X']
Y=data['Y'].flatten()
model = LassoCV(cv=10,max_iter=1000).fit(X, Y)
print 'alpha', model.alpha_
print 'coef', model.coef_
eps = 1e-2 # the smaller it is the longer is the path
models = lasso_path(X, Y, eps=eps)
alphas_lasso = np.array([model.alpha for model in models])
coefs_lasso = np.array([model.coef_ for model in models])
pl.figure(1)
ax = pl.gca()
ax.set_color_cycle(2 * ['b', 'r', 'g', 'c', 'k'])
l1 = pl.semilogx(alphas_lasso,coefs_lasso)
pl.gca().invert_xaxis()
pl.xlabel('alpha')
pl.show()
Python代码:
rng(3,'twister') % for reproducibility
X = zeros(200,5);
for ii = 1:5
X(:,ii) = exprnd(ii,200,1);
end
r = [0;2;0;-3;0];
Y = X*r + randn(200,1)*.1;
save randomData.mat % To be used in python code
[b fitinfo] = lasso(X,Y,'cv',10);
lassoPlot(b,fitinfo,'plottype','lambda','xscale','log');
disp('Lambda with min MSE')
fitinfo.LambdaMinMSE
disp('Lambda with 1SE')
fitinfo.Lambda1SE
disp('Quality of Fit')
lambdaindex = fitinfo.Index1SE;
fitinfo.MSE(lambdaindex)
disp('Number of non zero predictos')
fitinfo.DF(lambdaindex)
disp('Coefficient of fit at that lambda')
b(:,lambdaindex)
import scipy.io
import numpy as np
import pylab as pl
from sklearn.linear_model import lasso_path, LassoCV
data=scipy.io.loadmat('randomData.mat')
X=data['X']
Y=data['Y'].flatten()
model = LassoCV(cv=10,max_iter=1000).fit(X, Y)
print 'alpha', model.alpha_
print 'coef', model.coef_
eps = 1e-2 # the smaller it is the longer is the path
models = lasso_path(X, Y, eps=eps)
alphas_lasso = np.array([model.alpha for model in models])
coefs_lasso = np.array([model.coef_ for model in models])
pl.figure(1)
ax = pl.gca()
ax.set_color_cycle(2 * ['b', 'r', 'g', 'c', 'k'])
l1 = pl.semilogx(alphas_lasso,coefs_lasso)
pl.gca().invert_xaxis()
pl.xlabel('alpha')
pl.show()
有可能alpha=lambda/n\u样本
其中,scikit学习中的n_samples=X.shape[0]
另一点是,您的路径并不像它可能/应该的那样是非常分段线性的。考虑减少ToL和增加Max ITER。< /P>
希望这能有所帮助虽然我无法找出导致问题的原因,但有一个合理的方向可以继续
事实如下:
- Mathworks选择了一个示例,并决定将其包含在文档中
- 您的matlab代码生成的结果与示例完全相同李>
- 替代方案与结果不匹配,并且在过去提供了不准确的结果
这是我的假设:
- mathworks选择在其文档中添加错误示例的可能性是可以忽略的,而以另一种方式复制该示例不会给出正确结果的可能性则是可以忽略的李>
逻辑结论:这个例子的matlab实现是可靠的,而另一个不是。
这可能是代码中的一个问题,也可能是您如何使用它的问题,但无论如何,唯一合乎逻辑的结论是您应该继续使用Matlab来选择您的模型。我没有Matlab,但请注意交叉验证获得的值可能不稳定。这是因为它受您细分样本的方式的影响
即使在python中运行两次交叉验证,也可以获得两个不同的结果。
考虑这个例子:
kf=sklearn.cross_validation.KFold(len(y),n_folds=10,shuffle=True)
cv=sklearn.linear_model.LassoCV(cv=kf,normalize=True).fit(x,y)
print cv.alpha_
kf=sklearn.cross_validation.KFold(len(y),n_folds=10,shuffle=True)
cv=sklearn.linear_model.LassoCV(cv=kf,normalize=True).fit(x,y)
print cv.alpha_
0.00645093258722
0.00691712356467
我知道这是一条旧线,但是:
实际上,我正在从glmnet
(在R中)将管道连接到LassoCV
,我发现LassoCV
首先对X矩阵进行规范化并不太好(即使指定参数normalize=True
)
使用LassoCV时,首先尝试规范化X矩阵
如果它是一个物体
(X - X.mean())/X.std()
似乎你还需要将alpha乘以2我可以说,在处理真实数据时,我想起了类似的发现。Matlab的结果不同,并且明显更好。不过,我并没有深入探讨这个问题的根源。我想问题不仅仅在于规范化。我尝试了上面的一个,但仍然得到了不同的曲线。此外,通过交叉验证获得的系数非常不同。这在我看来仍然像是一个参数化问题:两条曲线看起来相似,但在X轴上移动。在日志空间中对scikit learn中的alpha进行重新缩放可能会导致这种情况。scikit学习中使用的参数化在中给出。您还可以从同一分布中生成更多数据,并计算回归分数(例如,确定系数r^2或RMSE),并检查阿尔法的最佳值是否接近交叉验证的阿尔法值。@imsc您是否尝试过使用alpha=lambda/(2*X.shape[0])
?宣传一种技术胜过另一种技术的论据非常薄弱。sklearn还提供了示例。matlab代码是否可以重现?实际上,套索更像是一类解算器,而不是一个精确定义的算法。因此,更可能的情况是算法略有不同。根据你的论点,说scikit learn不可靠是相当苛刻的。我不想暗示这一点,我已经稍微重新表述了我的回答,以便更清楚。谢谢你的回答<代码>scikit学习
确实是一个实施良好的模块。然而,仍然缺乏导致上述问题的文档和示例。我可以通过适当的规范化来解决这个问题。