【问题标题】:How to adjust scaled scikit-learn Logicistic Regression coeffs to score a non-scaled dataset?如何调整 scale scikit-learn Logistic Regression coeffs 以对非缩放数据集进行评分?
【发布时间】:2015-09-10 19:40:42
【问题描述】:

我目前正在使用 Scikit-Learn 的 LogisticRegression 来构建模型。我用过

from sklearn import preprocessing
scaler=preprocessing.StandardScaler().fit(build)
build_scaled = scaler.transform(build)

在训练模型之前缩放我的所有输入变量。一切正常并产生了一个不错的模型,但我的理解是 LogisticRegression.coeff_ 产生的系数是基于缩放变量的。是否对这些系数进行了转换,可用于调整它们以产生可应用于非缩放数据的系数?

我正在考虑在生产化系统中实现模型,并尝试确定是否所有变量都需要在生产中以某种方式进行预处理以对模型进行评分。

注意:模型可能必须在生产环境中重新编码,并且该环境不使用 python。

【问题讨论】:

    标签: python scikit-learn preprocessor logistic-regression coefficients


    【解决方案1】:

    您必须除以用于标准化特征的缩放比例,还要乘以您应用于目标的缩放比例。

    假设

    • 每个特征变量 x_i 都被 scale_x_i 缩放(除)

    • 目标变量被 scale_y 缩放(除)

    然后

    orig_coef_i = coef_i_found_on_scaled_data / scale_x_i * scale_y
    

    这是一个使用 pandas 和 sklearn LinearRegression 的示例

    from sklearn.datasets import load_boston
    from sklearn.linear_model import LinearRegression
    from sklearn.preprocessing import StandardScaler
    
    import numpy as np
    import pandas as pd
    
    boston = load_boston()
    # Looking at the description of the data tells us the target variable name
    # print boston.DESCR
    data = pd.DataFrame(
        data = np.c_[boston.data, boston.target],
        columns = list(boston.feature_names) + ['MVAL'],
    )
    data.head()
    
    X = boston.data
    y = boston.target
    
    lr = LinearRegression()
    lr.fit(X,y)
    
    orig_coefs = lr.coef_
    
    coefs1 = pd.DataFrame(
        data={
            'feature': boston.feature_names, 
            'orig_coef' : orig_coefs, 
        }
    )
    coefs1
    

    这向我们展示了未应用缩放的线性回归的系数。

    #  | feature| orig_coef
    # 0| CRIM   | -0.107171
    # 1| ZN     |  0.046395
    # 2| INDUS  |  0.020860
    # etc
    

    我们现在对所有变量进行归一化

    # Now we normalise the data
    scalerX = StandardScaler().fit(X)
    scalery = StandardScaler().fit(y.reshape(-1,1)) # Have to reshape to avoid warnings
    
    normed_X = scalerX.transform(X)
    normed_y = scalery.transform(y.reshape(-1,1)) # Have to reshape to avoid warnings
    
    normed_y = normed_y.ravel() # Turn y back into a vector again
    
    # Check it's worked
    # print np.mean(X, axis=0), np.mean(y, axis=0) # Should be 0s
    # print np.std(X, axis=0), np.std(y, axis=0)   # Should be 1s
    

    我们可以对这个标准化数据再次进行回归...

    # Now we redo our regression
    lr = LinearRegression()
    lr.fit(normed_X, normed_y)
    
    coefs2 = pd.DataFrame(
        data={
            'feature' : boston.feature_names,
            'orig_coef' : orig_coefs,
            'norm_coef' : lr.coef_,
            'scaleX' : scalerX.scale_,
            'scaley' : scalery.scale_[0],
        },
        columns=['feature', 'orig_coef', 'norm_coef', 'scaleX', 'scaley']
    )
    coefs2
    

    ...并应用缩放来取回我们的原始系数

    # We can recreate our original coefficients by dividing by the
    # scale of the feature (scaleX) and multiplying by the scale
    # of the target (scaleY)
    coefs2['rescaled_coef'] = coefs2.norm_coef / coefs2.scaleX * coefs2.scaley
    coefs2
    

    当我们这样做时,我们看到我们已经重新创建了原始系数。

    #  | feature| orig_coef| norm_coef|    scaleX|   scaley| rescaled_coef
    # 0| CRIM   | -0.107171| -0.100175|  8.588284| 9.188012| -0.107171
    # 1| ZN     |  0.046395|  0.117651| 23.299396| 9.188012|  0.046395
    # 2| INDUS  |  0.020860|  0.015560|  6.853571| 9.188012|  0.020860
    # 3| CHAS   |  2.688561|  0.074249|  0.253743| 9.188012|  2.688561
    

    对于某些机器学习方法,目标变量 y 必须与特征变量 x 一样进行归一化。如果你已经这样做了,你需要包括这个“乘以 y 的比例”步骤以及“除以 X_i 的比例”来取回原始回归系数。

    希望有帮助

    【讨论】:

    • 这是否意味着,我们也可以比较对应的“y”值?
    【解决方案2】:

    简短的回答,获取 LogisticRegression 系数并截取未缩放的数据(假设二进制分类,并且 lr 是经过训练的 LogisticRegression 对象):

    1. 您必须将系数数组元素除以(自 v0.17 起)scaler.scale_ 数组:coefficients = np.true_divide(lr.coeff_, scaler.scale_)

    2. 您必须从截距中减去结果系数(除法结果)数组与 scaler.mean_ 数组的内积:intercept = lr.intercept_ - np.dot(coefficients, scaler.mean_)

    如果你认为每个特征都通过减去它的平均值(存储在 scaler.mean_ 数组中)然后除以它的标准差(存储在 scaler .scale_ 数组)。

    【讨论】:

      【解决方案3】:

      您可以通过两个步骤使用pipeline:缩放和回归。它将原始数据作为输入并产生所需的回归。

      或者,如果您明确想要获取系数,您可以手动将 LogisticRegression 系数与 scaler.mean_ 和 scaler.std_ 的缩放器参数相结合。

      为此,请注意标准缩放器以这种方式对数据进行归一化:v_norm = (v - M(v))/sigma(v)。这里 M(v) 是原始变量 v 的平均值,sigma(v) 是它的标准差,分别存储在 scaler.mean_ 和 scaler.std_ 数组中。

      然后 LogisticRegression 将这个归一化的变量乘以 LogisticRegression.coef_ 并加上 intercept_。

      【讨论】:

        猜你喜欢
        • 2015-10-12
        • 2019-08-27
        • 1970-01-01
        • 2015-04-14
        • 1970-01-01
        • 2020-06-19
        • 2012-10-30
        • 2017-06-23
        • 2019-10-08
        相关资源
        最近更新 更多