在 scikit-learn 中拟合分类器之前进行特征缩放的必要性

Posted

技术标签:

【中文标题】在 scikit-learn 中拟合分类器之前进行特征缩放的必要性【英文标题】:The necessity of feature scaling before fitting a classifier in scikit-learn 【发布时间】:2016-09-24 03:14:01 【问题描述】:

我曾经相信scikit-learn 的Logistic Regression 分类器(以及SVM)会在训练之前自动对我的数据进行标准化。我曾经相信它的原因是因为传递给LogisticRegression 构造函数的正则化参数C:如果没有特征缩放,应用正则化(据我所知)没有意义。为了使正则化正常工作,所有特征都应该具有可比性。因此,我曾经假设在训练数据X上调用LogisticRegression.fit(X)时,fit方法首先进行特征缩放,然后开始训练。为了测试我的假设,我决定手动缩放X 的功能,如下所示:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X)
X_std = scaler.transform(X)

然后我用正则化参数C初始化了一个LogisticRegression对象:

from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression(C=10.0, random_state=0)

我发现在X 上训练模型并不等同于在X_std 上训练模型。也就是说,由

制作的模型
log_reg.fit(X_std, y)

与制作的模型不相似

log_reg.fit(X, y)

这是否意味着scikit-learn 在训练之前没有对特征进行标准化?或者也许它确实可以扩展但通过应用不同的程序?如果scikit-learn 不进行特征缩放,它与要求正则化参数C 的一致性如何?为了使正则化有意义,我是否应该每次在拟合模型之前手动标准化我的数据?

【问题讨论】:

您在这两种情况下都没有设置random_state 参数,请尝试将random_state=0 传递给LogisticRegression ctor,默认情况下它是None,所以您看到的任何差异都可能是由于这个原因,请参阅docs @EdChum:很好,谢谢。但是我实际上在测试上面的时候已经传递了random_state=0参数。我忘记在我的问题中说明这一点,所以我现在正在编辑问题。 【参考方案1】:

来自以下注释:http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html

我假设您需要自己预处理数据(例如,使用来自 sklearn.preprocessing 的缩放器。)

求解器:‘newton-cg’、‘lbfgs’、‘liblinear’、‘sag’

用于优化问题的算法。 对于小型数据集,“liblinear”是一个不错的选择,而“sag”对于大型数据集更快。

对于多类问题,只有“newton-cg”和“lbfgs”处理多项损失; ‘sag’ 和 ‘liblinear’ 仅限于 one-versus-rest 方案。

‘newton-cg’、‘lbfgs’和‘sag’只处理L2惩罚。

请注意,“sag”快速收敛仅在具有大致相同规模的特征上得到保证。您可以使用 sklearn.preprocessing 中的缩放器对数据进行预处理。

【讨论】:

以上是关于在 scikit-learn 中拟合分类器之前进行特征缩放的必要性的主要内容,如果未能解决你的问题,请参考以下文章

多标签分类器中的拟合概率

scikit-learn 拟合函数分类

scikit-learn:将数据拟合成块与一次拟合

如何克隆包括其数据的 scikit-learn 估计器?

Logistic Regression Scikit-Learn 获取分类的系数

如何检查sklearn模型是分类器还是回归器