【问题标题】:How to inverse transform regression predictions after pipeline?管道后如何逆变换回归预测?
【发布时间】:2020-12-19 03:32:50
【问题描述】:

我正在尝试弄清楚如何在使用管道时对数据进行缩放(可能使用 inverse_transform)以进行预测。下面的数据只是一个例子。我的实际数据更大更复杂,但我希望使用 RobustScaler(因为我的数据有异常值)和 Lasso(因为我的数据有几十个无用的特征)。一般来说,我对管道很陌生。

基本上,如果我尝试使用此模型来预测任何事情,我希望以未缩放的术语进行预测。这可以通过管道实现吗?如何使用 inverse_transform 做到这一点?

import pandas as pd
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import RobustScaler

data = [[100, 1, 50],[500 , 3, 25],[1000 , 10, 100]]
df = pd.DataFrame(data,columns=['Cost','People', 'Supplies'])

X = df[['People', 'Supplies']]
y = df[['Cost']]

#Split
X_train,X_test,y_train,y_test = train_test_split(X,y)

#Pipeline
pipeline = Pipeline([('scale', RobustScaler()),
            ('alg', Lasso())])

clf = pipeline.fit(X_train,y_train)

train_score = clf.score(X_train,y_train)
test_score = clf.score(X_test,y_test)

print ("training score:", train_score)
print ("test score:", test_score)

#Predict example 
example = [[10,100]]
clf.predict(example)

【问题讨论】:

  • 您的数据是否按输出缩放?我没有在代码中看到您在输入上调用.transform() 以使用robustscaler,无论是用于您的训练还是测试
  • 也许那是我的问题之一。同样,对管道来说非常新。我应该在管道中的某处调用 fit_transform() 吗?
  • 典型的工作流是pipeline.fit(train),pipeline.transform(train),pipeline.transform(test),那么你应该可以使用内置的inverse_transform在预测后反转转换
  • 所以当我尝试做 pipeline.transform(X_train,y_train) 时,我得到一个错误:AttributeError: 'Lasso' object has no attribute 'transform'。
  • 看起来像管道无法转换的问题,除非转换器是最后一步。解决方法在this question 中讨论

标签: python python-3.x machine-learning pipeline lasso-regression


【解决方案1】:

简单说明

您的管道仅转换 X 中的值,而不是 y。您在 y 中看到的预测差异与使用缩放数据和未缩放数据拟合的两个模型之间的系数值差异有关。

因此,如果您“希望以未缩放的方式进行预测”,则将缩放器从管道中取出。如果您希望以 缩放 术语进行预测,则需要在将新预测数据传递给 .predict() 函数之前对其进行缩放。如果您在其中包含缩放步骤,管道实际上会自动为您执行此操作。

缩放和回归

此处缩放的实际目的是当人员和用品具有不同的动态范围时。使用 RobustScaler() 删除中位数并根据分位数范围缩放数据。通常,只有当您认为您的人员或供应数据存在异常值会对样本均值/方差产生负面影响时,您才会这样做。如果不是这种情况,您可能会使用 StandardScaler() 来移除均值并缩放到单位方差。

对数据进行缩放后,您可以比较回归系数以更好地了解模型是如何进行预测的。这一点很重要,因为未缩放数据的系数可能会产生很大的误导性。

使用您的代码的示例

下面的例子显示:

  1. 在有和没有管道的情况下使用缩放和未缩放的数据进行预测。

  2. 预测在两种情况下都匹配。

  3. 您可以通过查看非管道示例来了解管道在后台执行的操作。

  4. 我还包括了两种情况下的模型系数。请注意,缩放和未缩放拟合模型的系数或权重非常不同。

  5. 这些系数用于为变量example生成每个预测值。

    import pandas as pd
    from sklearn.linear_model import Lasso
    from sklearn.model_selection import train_test_split
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import RobustScaler
    
    data = [[100, 1, 50],[500 , 3, 25],[1000 , 10, 100]]
    df = pd.DataFrame(data,columns=['Cost','People', 'Supplies'])
    
    X = df[['People', 'Supplies']]
    y = df[['Cost']]
    
    #Split
    X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
    
    #Pipeline
    pipeline_scaled = Pipeline([('scale', RobustScaler()),
                         ('alg', Lasso(random_state=0))])
    
    pipeline_unscaled = Pipeline([('alg', Lasso(random_state=0))])
    
    clf1 = pipeline_scaled.fit(X_train,y_train)
    clf2 = pipeline_unscaled.fit(X_train,y_train)
    
    
    #Pipeline predict example 
    example = [[10,100]]
    print('Pipe Scaled: ', clf1.predict(example))
    print('Pipe Unscaled: ',clf2.predict(example))
    
    #------------------------------------------------
    
    rs = RobustScaler()
    reg = Lasso(random_state=0)
    # Scale the taining data 
    X_train_scaled = rs.fit_transform(X_train)
    reg.fit(X_train_scaled, y_train)
    # Scale the example
    example_scaled = rs.transform(example)
    # Predict using the scaled data
    print('----------------------')
    print('Reg Scaled: ', reg.predict(example_scaled))
    print('Scaled Coefficents:',reg.coef_)
    
    #------------------------------------------------
    reg.fit(X_train, y_train)
    print('Reg Unscaled: ', reg.predict(example))
    print('Unscaled Coefficents:',reg.coef_)
    

输出:

Pipe Scaled:  [1892.]
Pipe Unscaled:  [-699.6]
----------------------
Reg Scaled:  [1892.]
Scaled Coefficents: [199.  -0.]
Reg Unscaled:  [-699.6]
Unscaled Coefficents: [  0.     -15.9936]

为了完整性

您最初的问题是关于“取消缩放”您的数据。我认为这不是您真正需要的,因为 X_train 是您的未缩放数据。但是,以下示例显示了如何使用管道中的缩放器对象来执行此操作。

#------------------------------------------------
pipeline_scaled['scale'].inverse_transform(X_train_scaled)

输出

array([[ 3., 25.],
       [ 1., 50.]])

【讨论】:

    猜你喜欢
    • 2018-11-29
    • 2021-02-09
    • 2020-03-24
    • 2022-01-09
    • 2021-10-21
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多