【问题标题】:Getting correct shape for datapoint to predict with a Regression model after using One-Hot-Encoding in training在训练中使用 One-Hot-Encoding 后,使用回归模型获得正确的数据点形状以进行预测
【发布时间】:2017-12-14 04:49:50
【问题描述】:

我正在编写一个使用线性回归的应用程序。在我的情况下sklearn.linear_model.Ridge。我无法为Ridge 带来我喜欢预测的正确形状的数据点。我简要描述了我的两个应用程序以及问题是如何出现的:

第一次申请:

我的数据点每个只有 1 个特性,它们都是字符串,所以我使用 One-Hot-Encoding 以便能够将它们与 Ridge 一起使用。之后,每个数据点 (X_hotEncoded) 有 9 个特征:

import pandas as pd
X_hotEncoded = pd.get_dummies(X)

在将Ridge 拟合到X_hotEncoded 并标记y 后,我将训练好的模型保存为:

from sklearn.externals import joblib
joblib.dump(ridge, "ridge.pkl")

第二次申请:

现在我已经在磁盘上保存了一个经过训练的模型,我想在我的第二个应用程序中检索它并预测 y(标签)的一个数据点。这就是我遇到上述问题的地方:

# X = one datapoint I like to predict y for 
ridge= joblib.load("ridge.pkl")
X_hotEncoded = pd.get_dummies(X)
ridge.predict(X_hotEncoded) # this should give me the prediction

这在最后一行代码中给了我以下错误:

ValueError: shapes (1,1) and (9,) not aligned: 1 (dim 1) != 9 (dim 0)

Ridge 接受了 9 个特征的训练,因为我在所有数据点上使用了 One-Hot-Encoding。现在,当我只想预测一个数据点(只有 1 个功能)时,我很难将这个数据点调整为正确的形状,以便 Ridge 能够处理它。 One-Hot-Encoding 对仅具有一项功能的一个数据点没有影响。

有人知道这个问题的巧妙解决方案吗?

一个可能的解决方案可能是在第一个应用程序中将列名写入磁盘并在第二个应用程序中检索它,然后在那里重建数据点。 one-hot-encoded 数组的列名可以这样检索:Reversing 'one-hot' encoding in Pandas

【问题讨论】:

    标签: python python-3.x machine-learning scikit-learn one-hot-encoding


    【解决方案1】:

    这里发生的情况如下:

    在训练阶段,您决定采用一种编码方式将单个分类特征转换为 9 个数字特征(One Hot)。您在此编码上训练了回归算法。因此,为了将其用于未知(测试)数据,您必须以与训练期间完全相同的方式转换这些数据。

    很遗憾,我认为您无法保存pd.get_dummies 使用的编码并重复使用它。您应该改用sklearn.preprocessing.OneHotEncoder()。所以在训练期间:

    from sklearn.preprocessing import OneHotEncoder
    
    enc = OneHotEncoder()
    X_hotEncoded = enc.fit_transform(X)
    

    fit_transform() 首先使编码器适合您的训练数据,然后使用它来转换数据。与pd.get_dummies() 的不同之处在于,您现在有了一个编码器对象,您可以保存并在以后重复使用:

    joblib.dump(enc, "encoder.pkl")
    

    在测试期间,您可以像这样应用训练期间使用的相同编码:

    enc = joblib.load("encoder.pkl")
    X_hotEncoded = enc.transform(X)
    

    请注意,您不想再次拟合编码器(这是pd.get_dummies() 会做的),因为对训练和测试数据使用相同的编码至关重要。

    注意:

    如果测试数据包含训练数据中不存在的值,您将遇到问题(因为编码器不知道如何编码这些未知值)。为避免这种情况,您可以:

    • OneHotEncoder() 提供categories 参数,将所有类别的列表传递给它。
    • 提供OneHotEncoder(),并将handle_unknown 参数设置为ignore。这样可以避免错误并将所有列设置为零。
    • 将数据拆分为训练集和测试集之前执行一次热编码。
    • OneHotEncoder() 提供n_values 参数,告诉编码器每个输入特征预期有多少不同的类别[编辑:自0.20 版起已弃用]。

    【讨论】:

    • 谢谢!你的答案很完美。它有效。此外,我必须在我的Pandas DataFrame X 上使用X.apply(LabelEncoder().fit_transform) 将字符串作为属性值转换为整数,然后再使用OneHotEncoder
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 2020-06-29
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 2017-05-29
    相关资源
    最近更新 更多