Don*_*beo 2 python machine-learning lasso-regression scikit-learn
我有一个矩阵,每列的平均值为0,标准为1
In [67]: x_val.std(axis=0).min()
Out[70]: 0.99999999999999922
In [71]: x_val.std(axis=0).max()
Out[71]: 1.0000000000000007
In [72]: x_val.mean(axis=0).max()
Out[72]: 1.1990408665951691e-16
In [73]: x_val.mean(axis=0).min()
Out[73]: -9.7144514654701197e-17
Run Code Online (Sandbox Code Playgroud)
如果我使用normalize选项,则非0系数的数量会发生变化
In [74]: l = Lasso(alpha=alpha_perc70).fit(x_val, y_val)
In [81]: sum(l.coef_!=0)
Out[83]: 47
In [84]: l2 = Lasso(alpha=alpha_perc70, normalize=True).fit(x_val, y_val)
In [93]: sum(l2.coef_!=0)
Out[95]: 3
Run Code Online (Sandbox Code Playgroud)
在我看来,规范化只是将每列的方差设置为1.奇怪的是,结果变化如此之大.我的数据已经变异= 1.
那么normalize = T究竟做了什么呢?
这是由于缩放概念中的(或潜在的[1])不一致性sklearn.linear_model.base.center_data:如果normalize=True,那么它将除以设计矩阵的每列的范数,而不是标准偏差.对于它的价值,该关键字normalize=True将从sklearn版本0.17弃用.
解决方法:不要不使用standardize=True.相反,构建一个sklearn.pipeline.Pipeline并sklearn.preprocessing.StandardScaler在您的Lasso对象前面添加一个.这样你甚至不需要执行初始缩放.
请注意,Lasso的sklearn实现中的数据丢失项是按比例缩放的n_samples.因此,产生零解的最小罚分是alpha_max = np.abs(X.T.dot(y)).max() / n_samples(for normalize=False).
[1]我说潜在的不一致,因为规范化与单词norm相关,因此至少在语言上是一致的:)
[如果你不想要细节,请在这里停止阅读]
这是一些复制和粘贴代码重现问题
import numpy as np
rng = np.random.RandomState(42)
n_samples, n_features, n_active_vars = 20, 10, 5
X = rng.randn(n_samples, n_features)
X = ((X - X.mean(0)) / X.std(0))
beta = rng.randn(n_features)
beta[rng.permutation(n_features)[:n_active_vars]] = 0.
y = X.dot(beta)
print X.std(0)
print X.mean(0)
from sklearn.linear_model import Lasso
lasso1 = Lasso(alpha=.1)
print lasso1.fit(X, y).coef_
lasso2 = Lasso(alpha=.1, normalize=True)
print lasso2.fit(X, y).coef_
Run Code Online (Sandbox Code Playgroud)
为了理解发生了什么,现在观察一下
lasso1.fit(X / np.sqrt(n_samples), y).coef_ / np.sqrt(n_samples)
Run Code Online (Sandbox Code Playgroud)
等于
lasso2.fit(X, y).coef_
Run Code Online (Sandbox Code Playgroud)
因此,缩放设计矩阵并通过np.sqrt(n_samples)将一个模型转换为另一个模型来适当地重新缩放系数.这也可以通过对惩罚采取行动来实现:一个套索估计器,normalize=True其惩罚通过np.sqrt(n_samples)像套索估计器这样的行为按比例缩小normalize=False(在您的数据类型上,即已经标准化为std=1).
lasso3 = Lasso(alpha=.1 / np.sqrt(n_samples), normalize=True)
print lasso3.fit(X, y).coef_ # yields the same coefficients as lasso1.fit(X, y).coef_
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4276 次 |
| 最近记录: |