在训练中使用一键编码后,获得正确的数据点形状以使用回归模型进行预测

moo*_*obi 4 python machine-learning python-3.x scikit-learn one-hot-encoding

我正在编写一个使用线性回归的应用程序。就我而言sklearn.linear_model.Ridge。我难以将自己喜欢的数据点带到的正确形状中Ridge。我简要描述了我的两个应用程序以及问题如何出现:

第一次应用:

我的数据点每个只有1个功能,都是字符串,因此我正在使用One-Hot-Encoding来将它们与结合使用Ridge。之后,每个数据点(X_hotEncoded)具有9个功能:

import pandas as pd
X_hotEncoded = pd.get_dummies(X)
Run Code Online (Sandbox Code Playgroud)

安装后Ridge,以X_hotEncoded和标签y我保存训练的模型:

from sklearn.externals import joblib
joblib.dump(ridge, "ridge.pkl")
Run Code Online (Sandbox Code Playgroud)

第二次应用:

现在,我已经在磁盘上保存了训练有素的模型,我希望在第二个应用程序中检索它,并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
Run Code Online (Sandbox Code Playgroud)

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

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

Ridge由于使用了我在所有数据点上使用的“一键编码”功能,因此接受了9种功能的培训。现在,当我只想预测一个数据点(仅具有1个功能)时,我很难将这个数据点设置为正确的形状以使Ridge能够处理它。一键编码仅对一个数据点产生影响,而仅具有一项功能。

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

可能的解决方案是将列名称写入第一个应用程序中的磁盘,然后在第二个应用程序中检索它,然后在该处重建数据点。可以按如下所示的方式检索单热编码数组的列名:反转熊猫中的“单热”编码

Tot*_*ich 5

以下是发生的情况:

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

不幸的是,我认为您无法保存使用的编码pd.get_dummies并重新使用它。您应该sklearn.preprocessing.OneHotEncoder()改用。因此,在训练期间:

from sklearn.preprocessing import OneHotEncoder

enc = OneHotEncoder()
X_hotEncoded = enc.fit_transform(X)
Run Code Online (Sandbox Code Playgroud)

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

joblib.dump(enc, "encoder.pkl")
Run Code Online (Sandbox Code Playgroud)

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

enc = joblib.load("encoder.pkl")
X_hotEncoded = enc.transform(X)
Run Code Online (Sandbox Code Playgroud)

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

小心:

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

  • 提供参数,并向OneHotEncoder()categories传递所有类别的列表。
  • 提供设置为OneHotEncoder()handle_unknown参数ignore。这样可以避免错误,只需将所有列设置为零即可。
  • 将数据分为训练和测试集之前执行一次热编码。
  • 提供OneHotEncoder()一个n_values参数,告诉编码器每个输入功能需要多少个不同的类别[编辑:自0.20版起不推荐使用]。