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