【问题标题】:Inverse scale of predicted data in KerasKeras 中预测数据的反比例
【发布时间】:2019-10-29 00:02:18
【问题描述】:

我正在尝试使用 NN 模型来预测新数据。然而,预测数据的比例不正确(当它应该是 0.3 时获得的值是 1e-10 等)。

在我的模型中,我在 x 和 y 数据上使用了 minmaxscaler。使用测试列车拆分方法时,该模型给我的 R2 值为 0.9,使用管道方法和交叉验证方法时,MSE 为 0.01%。所以我相信我创建的模型是好的。

这是我制作的模型。

data=pd.read_csv(r'''F:\DataforANNfromIESFebAugPowerValues.csv''')
data.dropna(axis=0,how='all')

x=data[['Dry-bulb_temperature_C','Wind_speed_m/s','Cloud_cover_oktas','External_relative_humidity_%','Starrag1250','StarragEcospeed2538','StarragS191','StarragLX051','DoosanCNC6700','MakinoG7','HermleC52MT','WFL_Millturn','Hofler1350','MoriNT4250','MoriNT5400','NMV8000','MoriNT6600','MoriNVL1350','HermleC42','CFV550','MoriDura635','DMGUltrasonic10']]
y=data[['Process_heat_output_waste_kW','Heating_plant_sensible_load_kW','Cooling_plant_sensible_load_kW','Relative_humidity_%','Air_temperature_C','Total_electricity_kW','Chillers_energy_kW','Boilers_energy_kW']]

epochs=150
learning_rate=0.001
decay_rate=learning_rate/epochs
optimiser=keras.optimizers.Nadam(lr=learning_rate, schedule_decay=decay_rate)

def create_model():
    model=Sequential()
    model.add(Dense(21, input_dim=22, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(19, activation='relu')) #hidden layer 2
    model.add(Dropout(0.2))
    model.add(Dense(8, activation='sigmoid')) #output layer
    model.compile(loss='mean_squared_error', optimizer=optimiser,metrics=['accuracy','mse'])
    return model

scaler=MinMaxScaler()


x=MinMaxScaler().fit_transform(x)
print(x)
y=MinMaxScaler().fit_transform(y)
model=KerasRegressor(build_fn=create_model, verbose=0,epochs=150, batch_size=70)
model.fit(x, y, epochs=150, batch_size=70)


##SET UP NEW DATA FOR PREDICTIONS

xnewdata=pd.read_csv(r'''F:\newdatapowervalues.csv''')
xnewdata.dropna(axis=0,how='all')
xnew=xnewdata[['Dry-bulb_temperature_C','Wind_speed_m/s','Cloud_cover_oktas','External_relative_humidity_%','Starrag1250','StarragEcospeed2538','StarragS191','StarragLX051','DoosanCNC6700','MakinoG7','HermleC52MT','WFL_Millturn','Hofler1350','MoriNT4250','MoriNT5400','NMV8000','MoriNT6600','MoriNVL1350','HermleC42','CFV550','MoriDura635','DMGUltrasonic10']]

xnew=MinMaxScaler().fit_transform(xnew)
ynew=model.predict(xnew)

ynewdata=pd.DataFrame(data=ynew)
ynewdata.to_csv(r'''F:\KerasIESPowerYPredict.csv''',header=['Process_heat_output_waste_kW','Heating_plant_sensible_load_kW','Cooling_plant_sensible_load_kW','Relative_humidity_%','Air_temperature_C','Total_electricity_kW','Chillers_energy_kW','Boilers_energy_kW'])

看到我在初始训练模型上使用了缩放器,我想我也需要对新数据执行此操作。我试过做 scaler.inverse_transform(ynew) 在 model.predict(ynew) 但是我得到 minmaxscaler 实例还没有适合 y 的错误。 因此,我尝试使用管道方法。

estimators = []
estimators.append(('standardize', MinMaxScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=create_model, epochs=150, batch_size=70, verbose=0)))
pipeline = Pipeline(estimators)
pipeline.fit(x,y)

用于初始训练模型而不是

x=MinMaxScaler().fit_transform(x)
y=MinMaxScaler().fit_transform(y)
model=KerasRegressor(build_fn=create_model, verbose=0,epochs=150, batch_size=70)
model.fit(x, y, epochs=150, batch_size=70)

然后我用了 ynew=pipeline.predict(xnew) 然而,这给了我主要由 1 组成的数据!

关于如何正确预测这些新数据的任何想法?我不确定要缩放哪些数据,哪些不是,因为我相信使用 pipeline.predict 将包括缩放 x 和 y。因此,在做出这些预测之后,我是否需要某种逆流水线标量? 非常感谢您的帮助。

【问题讨论】:

    标签: python machine-learning keras scikit-learn neural-network


    【解决方案1】:

    你的方法有一个小问题和一个大问题。

    1. 次要一:不需要对目标变量进行缩放,它不会影响您的优化功能。
    2. 主要问题:您再次将缩放器拟合到要运行预测的数据上。通过这样做,您完全扭曲了数据中的关系,因此预测的输出具有非常不同的规模。此外,您定义了scaler,然后不使用它。让我们修复它。

    (...)

    scaler=MinMaxScaler()
    
    x=scaler.fit_transform(x)
    model=KerasRegressor(build_fn=create_model, verbose=0,epochs=150, batch_size=70)
    model.fit(x, y, epochs=150, batch_size=70)
    
    
    ##SET UP NEW DATA FOR PREDICTIONS
    
    xnewdata=pd.read_csv(r'''F:\newdatapowervalues.csv''')
    xnewdata.dropna(axis=0,how='all')
    xnew=xnewdata[['Dry-bulb_temperature_C','Wind_speed_m/s','Cloud_cover_oktas','External_relative_humidity_%','Starrag1250','StarragEcospeed2538','StarragS191','StarragLX051','DoosanCNC6700','MakinoG7','HermleC52MT','WFL_Millturn','Hofler1350','MoriNT4250','MoriNT5400','NMV8000','MoriNT6600','MoriNVL1350','HermleC42','CFV550','MoriDura635','DMGUltrasonic10']]
    
    xnew=scaler.transform(xnew)
    ynew=model.predict(xnew)
    
    ynewdata=pd.DataFrame(data=ynew)
    

    如您所见,我们首先使用 scaler 来学习正确的归一化因子,然后在我们运行 predict 的新数据上使用它 (transform)。

    【讨论】:

    • 感谢您的帮助。当我在不缩放 y 数据的情况下运行模型时,我会得到一个糟糕的模型,其精度随着时代的推移而降低,并且损失增加。我不需要缩放 y 数据,使其在激活函数的范围内吗?感谢您的帮助
    • 对不起,我没有注意到你在那里使用sigmoid。将其替换为linear
    • 说不需要缩放目标是不对的,它确实改变了优化问题,你可以很容易地在神经网络的边界框回归中看到这一点。
    • @MatiasValdenegro 它如何改变优化?您能否从数学或算法的角度说明它如何影响优化问题?这是它如何不影响它的一种解释:stats.stackexchange.com/questions/111467/…
    • @LukaszTracewski 对于神经网络,它确实会改变它,因为您规范化目标在输出中放置适当的激活,因此范围匹配,例如,规范化目标到 [0, 1] 并在网络的输出处放置一个 sigmoid 激活。您链接的答案不适用于复杂的非线性模型,您还可以在其中进行小的架构更改。另一个原因是,如果你不扩展,网络必须学习规模,因此规范化和强制网络使用确定的规模会消除一个学习问题。它不仅仅是一个线性变换。
    猜你喜欢
    • 2021-08-25
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    相关资源
    最近更新 更多