问题
I have trained an XGBoostRegressor model. When I have to use this trained model for predicting for a new input, the predict() function throws a feature_names mismatch error, although the input feature vector has the same structure as the training data.
Also, in order to build the feature vector in the same structure as the training data, I am doing a lot inefficient processing such as adding new empty columns (if data does not exist) and then rearranging the data columns so that it matches with the training structure. Is there a better and cleaner way of formatting the input so that it matches the training structure?
回答1:
From what I could find, the predict function does not take the DataFrame (or a sparse matrix) as input. It is one of the bugs which can be found here https://github.com/dmlc/xgboost/issues/1238
In order to get around this issue, use as_matrix() function in case of a DataFrame or toarray() in case of a sparse matrix.
This is the only workaround till the bug is fixed or the feature is implemented in a different manner.
回答2:
I also had this problem when i used pandas DataFrame (non-sparse representation).
I converted training and testing data into numpy ndarray
.
`X_train = X_train.as_matrix()
X_test = X_test.as_matrix()`
This how i got rid of that Error!
回答3:
Try converting data into ndarray before passing it to fit/predict. For eg: if your train data is train_df and test data is test_df. Use below code:
train_x = train_df.values
test_x = test_df.values
Now fit the model:
xgb.fit(train_x,train_y)
Finally, predict:
pred = xgb.predict(test_x)
Hope this helps!
回答4:
I came across the same problem and it's been solved by adding passing the train dataframe column name to the test dataframe via adding the following code:
test_df = test_df[train_df.columns]
回答5:
This is the case where the order of column-names while model building is different from order of column-names while model scoring.
I have used the following steps to overcome this error
First load the pickle file
model = pickle.load(open("saved_model_file", "rb"))
extraxt all the columns with order in which they were used
cols_when_model_builds = model.get_booster().feature_names
reorder the pandas dataframe
pd_dataframe = pd_dataframe[cols_when_model_builds]
回答6:
Check the exception. What you should see are two arrays. One is the column names of the dataframe you’re passing in and the other is the XGBoost feature names. They should be the same length. If you put them side by side in an Excel spreadsheet you will see that they are not in the same order. My guess is that the XGBoost names were written to a dictionary so it would be a coincidence if the names in then two arrays were in the same order.
The fix is easy. Just reorder your dataframe columns to match the XGBoost names:
f_names = model.feature_names
df = df[f_names]
回答7:
I'm contributing an answer as I experienced this problem when putting a fitted XGBRegressor model into production. Thus, this is a solution for cases where you cannot select column names from a y training or testing DataFrame, though there may be cross-over which could be helpful.
The model had been fit on a Pandas DataFrame, and I was attempting to pass a single row of values as a np.array to the predict function. Processing the values of the array had already been performed (reverse label encoded, etc.), and the array was all numeric values.
I got the familiar error:
ValueError: feature_names mismatch
followed by a list of the features, followed by a list of the same length: ['f0', 'f1' ....]
While there are no doubt more direct solutions, I had little time and this fixed the problem:
- Make the input vector a Pandas Dataframe:
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)
- Get the feature names that the trained model knows:
names = model.get_booster().feature_names
- Select those feature from the input vector DataFrame (defined above), and perform iloc indexing:
result = model.predict(vector[names].iloc[[-1]])
The iloc transformation I found here.
Selecting the feature names – as models in the Scikit Learn implementation do not have a feature_names
attribute – using get_booster( ).feature_names
I found in @Athar post above.
Check out the the documentation to learn more.
Hope this helps.
回答8:
Do this while creating the DMatrix for XGB:
dtrain = xgb.DMatrix(np.asmatrix(X_train), label=y_train)
dtest = xgb.DMatrix(np.asmatrix(X_test), label=y_test)
Do not pass X_train and X_test directly.
来源:https://stackoverflow.com/questions/42338972/valueerror-feature-names-mismatch-in-xgboost-in-the-predict-function