【问题标题】:How to fill missing value using pre-trained model?如何使用预训练模型填充缺失值?
【发布时间】:2020-08-24 13:19:06
【问题描述】:

我有一个时间序列索引,其中变量和湿度读数很少。我已经训练了一个 ML 模型来预测基于 X、Y 和 Z 的湿度值。现在,当我使用 pickle 加载保存的模型时,我想使用 X、Y 和 Z 填充湿度缺失值。但是,它应该考虑 X、Y 和 Z 本身不应该丢失的事实。

Time                    X        Y        Z       Humidity
1/2/2017 13:00          31       22       21           48
1/2/2017 14:00          NaN      12       NaN          NaN
1/2/2017 15:00          25       55       33           NaN

在此示例中,将使用模型填充最后一行湿度。而模型不应预测第二行,因为 X 和 Z 也缺失。

到目前为止我已经尝试过了:

with open('model_pickle','rb') as f:
    mp = pickle.load(f)

for i, value in enumerate(df['Humidity'].values):
    if np.isnan(value):
        df['Humidity'][i] = mp.predict(df['X'][i],df['Y'][i],df['Z'][i])

这给了我一个错误“predict() 需要 2 到 5 个位置参数,但给出了 6 个”,而且我没有考虑 X、Y 和 Z 列值。下面是我用来训练模型并将其保存到文件中的代码:

df = df.dropna()

dfTest = df.loc['2017-01-01':'2019-02-28']
dfTrain = df.loc['2019-03-01':'2019-03-18'] 
features = [ 'X', 'Y', 'Z'] 
train_X = dfTrain[features]
train_y = dfTrain.Humidity
test_X = dfTest[features]
test_y = dfTest.Humidity

model = xgb.XGBRegressor(max_depth=10,learning_rate=0.07)
model.fit(train_X,train_y)
predXGB = model.predict(test_X)
mae = mean_absolute_error(predXGB,test_y)
import pickle
with open('model_pickle','wb') as f:
    pickle.dump(model,f)

我在训练和保存模型的过程中没有出错。

【问题讨论】:

  • 您在什么数据集上训练模型?该数据集是否在 X、Y、Z 特征中也有缺失值?如果有,您是如何处理它们的?
  • 是的,在同一个数据集上,但使用的是其他年份的数据。该模型是使用完整数据(没有丢失)训练的,所以这不是问题。
  • 好的,如果您在训练集中有缺失值,那么您也必须在测试集中使用相同的插补方法。您必须使用现有的插补方法之一,没有其他方法可以解决。当然,与这种插补导致的交叉验证错误相比,您应该期望模型的准确度较低。
  • 请澄清:您加载的是什么型号?你确定使用.predict 有效吗?您向我们展示了有关您未提供的方法的错误,因此很难为您提供帮助。另外,请说明您在训练期间是否使用了任何插补方法
  • @Roim 我已经编辑了问题以增加清晰度。

标签: python dataframe machine-learning data-cleaning sklearn-pandas


【解决方案1】:

对于预测,既然你想确保你拥有所有的 X、Y、Z 值,你可以这样做,

df = df.dropna(subset = ["X", "Y", "Z"])

现在您可以将剩余有效示例的值预测为,

# where features = ["X", "Y", "Z"]
df['Humidity'] = mp.predict(df[features]) 

mp.predict 将返回所有行的预测,因此无需迭代预测。

编辑:。

对于推理,假设你有一个数据框df,你可以这样做,

# Get rows with missing Humidity where it can be predicted.
df_inference = df[df.Humidity.isnull()]

# remaining rows
df = df[df.Humidity.notnull()]

# This might still have rows with missing features.
# Since you cannot infer with missing features, Remove them too and add them to remaining rows
df = df.append(df_inference[df_inference[features].isnull().any(1)])

# and remove them from df_inference
df_inference = df_inference[~df_inference[features].isnull().any(1)]

#Now you can infer on these rows
df_inference['Humidity'] = mp.predict(df_inference[features])

# Now you can merge this back to the remaining rows to get the original number of rows and sort the rows by index
df = df.append(df_inference)
df.sort_index()

【讨论】:

  • 感谢@dumpPy 这有效并且没有给出任何错误。然而,现在所有的行都被模型预测了,即没有丢失的原始数据也被预测了。我知道这种没有循环的方法更快,但我也应该首先检查该行是否丢失。有什么建议吗?
  • 我希望您已将训练和测试数据与推理数据(缺少湿度值的数据)分开。将此添加到答案中
  • 让我再澄清一点。训练在这里无关紧要,因为我正在加载一个预先训练的模型。现在假设湿度列有 15% 的缺失值,我只想在这 15% 的行上运行预测。剩下的将保持不变,希望它有意义
  • 好的。我上面定义的df_inference 就是你所需要的。 df = df[df.Humidity.isnull()] 将为您提供数据帧,以便所有行的湿度为 NaN。您可以通过df['Humidity'] = mp.predict(df[features]) 获得预测
  • 更新了答案以反映您需要的一切。推断可推断的行并将其合并回原始行以取回所有行。
【解决方案2】:

试试

df['Humidity'][i] = mp.predict(df[['X', 'Y', 'Z']][i])  

通过这种方式,您可以将数据作为单个参数传递,正如函数所期望的那样。按照您的编写方式,您将数据拆分为 3 个参数。

【讨论】:

    【解决方案3】:

    可以报错吗?

    无论如何,如果您有缺失值,您有不同的选择来处理它们。您可以完全丢弃数据点,也可以尝试使用选择的方法推断缺失的部分:均值、插值等。

    Pandas 文档有一个很好的指南来说明如何处理它们: https://pandas.pydata.org/pandas-docs/stable/user_guide/missing_data.html

    【讨论】:

    • 我已经编辑了报告错误的问题。我知道使用 pandas 插值的各种缺失值,但在我的情况下,缺失的变量与其他变量密切相关,因此使用这种方法将给出准确的插值。
    • 你正在加载一个你没有指定的模型,所以我真的不知道它为什么要问 2-5 个参数。无论如何,如果您不处理缺失值,它将无法正常工作。同样,要么删除整行,要么将 X、Y、Z NaN 替换为其他内容(插值、均值、结转等)
    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2023-01-03
    • 2018-03-24
    • 1970-01-01
    相关资源
    最近更新 更多