ValueError:feature_names mismatch:在predict()函数的xgboost中

时间:2017-02-20 07:43:25

标签: python pandas machine-learning regression xgboost

我已经训练了一个XGBoostRegressor模型。当我必须使用这个训练模型来预测新输入时,predict()函数会抛出一个feature_names不匹配错误,尽管输入特征向量与训练数据具有相同的结构。

另外,为了在与训练数据相同的结构中构建特征向量,我正在进行大量低效的处理,例如添加新的空列(如果数据不存在),然后重新排列数据列以便它与训练结构相匹配。是否有更好,更清晰的方式来格式化输入,使其与训练结构相匹配?

11 个答案:

答案 0 :(得分:5)

根据我的发现,预测函数不会将DataFrame(或稀疏矩阵)作为输入。这是可以在https://github.com/dmlc/xgboost/issues/1238

找到的错误之一

为了解决这个问题,在DataFrame的情况下使用as_matrix()函数,或者在稀疏矩阵的情况下使用toarray()。

在修复错误或以不同方式实现功能之前,这是唯一的解决方法。

答案 1 :(得分:3)

我遇到了同样的问题,它通过添加以下代码添加将火车数据帧列名称传递给测试数据帧来解决:

        var web = new HtmlWeb();
        var doc = web.Load(url);
        System.Threading.Thread.Sleep(21000);
        string adress = doc.DocumentNode
              .SelectSingleNode("//td/span#myId")
              .Attributes["value"].Value;

答案 2 :(得分:3)

当我使用pandas DataFrame(非稀疏表示)时,我也遇到了这个问题。

我将培训和测试数据转换为numpy ndarray

          `X_train = X_train.as_matrix()
           X_test = X_test.as_matrix()` 

这是我如何摆脱那个错误!

答案 3 :(得分:2)

检查异常。您应该看到的是两个数组。一个是您传入的数据帧的列名称,另一个是XGBoost功能名称。它们的长度应该相同。如果将它们并排放在Excel电子表格中,您将看到它们的顺序不同。我的猜测是,XGBoost名称被写入字典,因此如果两个数组中的名称的顺序相同,那将是巧合。

修复很简单。只需重新排序数据帧列以匹配XGBoost名称:

f_names = model.feature_names
df = df[f_names]

答案 4 :(得分:2)

在将数据传递到适合/预测之前,尝试将其转换为ndarray。 例如: 如果您的火车数据是train_df而测试数据是test_df。使用以下代码:

train_x = train_df.values
test_x = test_df.values

现在拟合模型:

xgb.fit(train_x,train_y)

最后,预测:

pred = xgb.predict(test_x)

希望这会有所帮助!

答案 5 :(得分:1)

当我将合适的XGBRegressor模型投入生产时遇到此问题时,我正在提供一个答案。因此,这是针对无法从y训练或测试DataFrame中选择列名的情况的解决方案,尽管可能会有交叉,这可能会有所帮助。

该模型已安装在Pandas DataFrame上,并且我试图将值的单行作为np.array传递给预测函数。已经对数组的值进行了处理(反向标签编码等),并且数组都是数字值。

我遇到了熟悉的错误:

ValueError: feature_names mismatch,然后是功能列表,然后是长度相同的列表:['f0', 'f1' ....]

虽然毫无疑问有更直接的解决方案,但我花的时间很少,而且可以解决问题:

  1. 使输入向量成为熊猫数据框:
series = {'feature1': [value],
          'feature2': [value],
          'feature3': [value],
          'feature4': [value],
          'feature5': [value],
          'feature6': [value],
          'feature7': [value],
          'feature8': [value],
          'feature9': [value],
          'feature10': [value]
           }

self.vector = pd.DataFrame(series)
  1. 获取经过训练的模型知道的特征名称:

names = model.get_booster().feature_names

  1. 从输入矢量DataFrame(如上定义)中选择那些功能,然后执行iloc索引:

result = model.predict(vector[names].iloc[[-1]])


我发现here的iloc转换。

使用我在上面@Athar帖子中找到的feature_names,选择功能名称-因为Scikit Learn实现中的模型没有get_booster( ).feature_names属性。

查看the documentation了解更多信息。

希望这会有所帮助。

答案 6 :(得分:1)

XGBoostRegressor 需要列(特征)的顺序相同。

试试

DataFrama = DataFrame.reindex(sorted(DataFrame.columns), axis = 1)

将其应用于训练和测试特征数据集。

答案 7 :(得分:1)

我也遇到了同样的问题,尝试了所有技术都失败了。我使用的是 Pima 糖尿病数据集模型。 fit() 很好,但是在使用 predict 进行手动测试时,它会在缺少的功能名称中抛出错误。然后我尝试了一些对我有用的东西。

test1=[[6,148,72,35,0,33,0.8,54]]
test2= pd.DataFrame(test1,columns= 
['Pregnancies','Glucose','BloodPressure','SkinThickness',
'Insulin','BMI','DiabetesPedigreeFunction','Age'],dtype=float)
p=classifier.predict(test2)
print("Diabetes [0 - No Yes - 1] :\n Result : ",p[0])

列基本上是我数据集中的自变量列。

现在会有一个问题,那么每次我都需要尝试这种复杂的方法来预测一些。所以答案是否定的。在你pickle模型之后,你可以很容易地通过model.predict([[test]])就不会有问题

可以看到完整的代码here

答案 8 :(得分:0)

在为XGB创建DMatrix时执行以下操作:

dtrain = xgb.DMatrix(np.asmatrix(X_train), label=y_train)
dtest = xgb.DMatrix(np.asmatrix(X_test), label=y_test)

请勿直接通过X_train和X_test。

答案 9 :(得分:0)

在这种情况下,模型构建时的列名顺序与模型评分时的列名顺序不同。

我已按照以下步骤解决了该错误

首先加载泡菜文件

model = pickle.load(open("saved_model_file", "rb"))

按使用顺序排除所有列

cols_when_model_builds = model.get_booster().feature_names

重新排列熊猫数据框

pd_dataframe = pd_dataframe[cols_when_model_builds]

答案 10 :(得分:0)

问题实际上只是命名问题,因为 xgboost 在内部将 pd.DataFrame.columns 转换为 ctypes 并且不会还原该步骤。

您可以通过在训练后将“错误”的特征名称替换为正确的特征名称来手动重置状态:

# Your training/test-data
data = pd.DataFrame( your_data )

# Your classifier/regressor
model = XGBClassifier().fit( data )

# Do the renaming
# Note: Don't forget to remove the target-column if its in data!
model.get_booster().feature_names = data.columns