web-dev-qa-db-ja.com

ValueError:feature_namesの不一致:xgboostのpredict()関数

XGBoostRegressorモデルをトレーニングしました。このトレーニング済みモデルを新しい入力の予測に使用する必要がある場合、入力特徴ベクトルはトレーニングデータと同じ構造ですが、predict()関数はfeature_names不一致エラーをスローします。

また、トレーニングデータと同じ構造で特徴ベクトルを構築するために、新しい空の列を追加し(データが存在しない場合)、次に一致するようにデータ列を再配置するなど、多くの非効率的な処理を行っていますトレーニング構造。トレーニング構造と一致するように入力をフォーマットするより良い、よりクリーンな方法はありますか?

15
Sujay S Kumar

pandas DataFrame(非スパース表現))を使用したときにも、この問題が発生しました。

トレーニングとテストのデータをnumpy ndarrayに変換しました。

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

これは私がそのエラーを取り除く方法です!

6
Abhishek Sharma

私が見つけたものから、予測関数はDataFrame(またはスパース行列)を入力として取りません。これはここで見つけることができるバグの1つです https://github.com/dmlc/xgboost/issues/1238

この問題を回避するには、DataFrameの場合はas_matrix()関数を使用し、疎行列の場合はtoarray()を使用します。

これは、バグが修正されるか、機能が別の方法で実装されるまでの唯一の回避策です。

6
Sujay S Kumar

フィット/予測に渡す前に、データを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
saurabh kumar

同じ問題に遭遇しましたが、次のコードを追加して、train dataframe列名をテストデータフレームに渡すことで解決されています。

test_df = test_df[train_df.columns]
4
CathyQian

例外を確認してください。表示されるのは2つの配列です。 1つは渡すデータフレームの列名で、もう1つはXGBoost機能名です。それらは同じ長さでなければなりません。それらをExcelスプレッドシートに並べて配置すると、同じ順序になっていないことがわかります。私の推測では、XGBoostの名前は辞書に書き込まれたため、2つの配列の名前が同じ順序であった場合は偶然でしょう。

修正は簡単です。 XGBoost名と一致するようにデータフレーム列を並べ替えるだけです。

f_names = model.feature_names
df = df[f_names]
2
GDB

これは、モデル作成時の列名の順序が、モデルスコアリング時の列名の順序と異なる場合です。

このエラーを克服するために次の手順を使用しました

最初に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]
1
Athar

適合したXGBRegressorモデルを本番環境に配置するときにこの問題が発生したので、私は回答を提供しています。したがって、これは役立つ可能性があるクロスオーバーがあるかもしれないが、yトレーニングまたはテストDataFrameから列名を選択できない場合の解決策です。

モデルはPandas DataFrameに適合しており、単一行の値をnp.arrayとして予測関数に渡そうとしました。配列の値の処理はすでに実行されていました(逆ラベルエンコードなど)、配列はすべて数値でした。

私はおなじみのエラーを受け取りました:

_ValueError: feature_names mismatch_の後に機能のリストが続き、同じ長さのリストが続く:_['f0', 'f1' ....]_

間違いなくもっと直接的な解決策があることは間違いありませんが、私には時間がほとんどなく、これで問題が解決しました。

  1. 入力ベクトルを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)
_
  1. トレーニング済みモデルが知っている機能名を取得します。

names = model.get_booster().feature_names

  1. 入力ベクトルDataFrame(上記で定義)からこれらの特徴を選択し、ilocインデックスを実行します。

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


私が見つけたiloc変換 here

機能名の選択– Scikit Learn実装のモデルには_feature_names_属性がないため– get_booster( ).feature_namesを使用する上記の@Atharの投稿で見つけました。

詳細は ドキュメント をご覧ください。

お役に立てれば。

0
David1592

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を直接渡さないでください。

0
Saurabh