ValueError: feature_names mismatch: in xgboost in the predict() function

Posted

技术标签:

【中文标题】ValueError: feature_names mismatch: in xgboost in the predict() function【英文标题】: 【发布时间】:2017-07-09 09:39:25 【问题描述】:

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

另外,为了构建与训练数据结构相同的特征向量,我做了很多低效的处理,例如添加新的空列(如果数据不存在),然后重新排列数据列,使其与训练结构相匹配。有没有更好更简洁的方法来格式化输入,使其与训练结构相匹配?

【问题讨论】:

【参考方案1】:

问题实际上只是命名,因为 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

【讨论】:

【参考方案2】:

我也面临同样的问题,尝试了所有技术都失败了。我使用的是 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])

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

现在会有一个问题,然后我每次都需要尝试这种复杂的方法来预测一些。所以答案是否定的。腌制模型后,您可以轻松通过 model.predict([[test]]) 就没有问题了

你可以看到完整的代码here

【讨论】:

【参考方案3】:

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

试试

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

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

【讨论】:

【参考方案4】:

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

该模型适合 Pandas DataFrame,我试图将单行值作为 np.array 传递给 predict 函数。已经对数组的值进行了处理(反向标签编码等),数组都是数值。

我得到了熟悉的错误:

ValueError: feature_names mismatch后跟特征列表,后跟相同长度的列表:['f0', 'f1' ....]

虽然毫无疑问有更直接的解决方案,但我没有多少时间,这解决了问题:

    将输入向量设为 Pandas 数据框:
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)
    获取训练模型知道的特征名称:

names = model.get_booster().feature_names

    从输入向量 DataFrame(如上定义)中选择那些特征,并执行 iloc 索引:

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


我找到的iloc转换here。

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

查看the documentation 了解更多信息。

希望这会有所帮助。

【讨论】:

【参考方案5】:

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

我已使用以下步骤来克服此错误

首先加载pickle文件

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

按照使用顺序提取所有列

cols_when_model_builds = model.get_booster().feature_names

重新排序 pandas 数据框

pd_dataframe = pd_dataframe[cols_when_model_builds]

【讨论】:

我试图检查我的推理数据的特征名称,这是一个 numpy 数组,但我没有。 @spacedustpi 如果在训练时使用 pandas.Dataframe 拟合模型,则列名将保留在序列化模型 (pkl) 中。如果你用 numpy 数组拟合你的模型,那么 xgboost 就没有列名可供使用。【参考方案6】:

在将数据传递给 fit/predict 之前尝试将其转换为 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)

希望这会有所帮助!

【讨论】:

谢谢。就我而言,该错误仅使用 xgboost 回归器重现,其他回归运行良好。【参考方案7】:

在为 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。

【讨论】:

【参考方案8】:

我遇到了同样的问题,通过添加以下代码将训练数据帧列名添加到测试数据帧已解决:

test_df = test_df[train_df.columns]

【讨论】:

【参考方案9】:

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

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

f_names = model.feature_names
df = df[f_names]

【讨论】:

AttributeError: 'XGBRegressor' 对象没有属性 'feature_names' @Keith 你可以试试这个:model.get_booster().feature_names【参考方案10】:

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

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

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

这就是我摆脱那个错误的方法!

【讨论】:

as_matrix() 方法现在似乎已经贬值了。建议使用.values,这对我不起作用,但文档是here。【参考方案11】:

据我所知,预测函数不会将 DataFrame(或稀疏矩阵)作为输入。这是可以在这里找到的错误之一https://github.com/dmlc/xgboost/issues/1238

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

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

【讨论】:

以上是关于ValueError: feature_names mismatch: in xgboost in the predict() function的主要内容,如果未能解决你的问题,请参考以下文章

feature_names 必须是唯一的 - Xgboost

多类文本分类期间 xgboost sklearn 中的 feature_names 不匹配

可视化特征的重要性

可视化特征的重要性

决策树可视化Graphviz中文乱码

ValueError:未知标签类型