SageMaker

xgboost モデルの推論を行う際に predict_fn に numpy の配列を渡すようにした

ローカルで学習したモデルをSageMakerにデプロイして、推論/エンドポイント呼び出しを行います。予測を行おうとすると、以下のような例外が発生します。

raise ValueError('Input numpy.ndarray must be 2 dimensional')
ValueError: Input numpy.ndarray must be 2 dimensional
    

私の model は、いくつかの前処理(変数エンコーディング)とハイパーパラメーター調整を備えたxgboostモデルです。 model オブジェクトは次のようになります。

XGBRegressor(colsample_bytree=xxx, gamma=xxx,
             learning_rate=xxx, max_depth=x, n_estimators=xxx,
             subsample=xxx)

私のテストデータはfloat値の文字列で、データはnumpyの配列として渡す必要があるため、配列に変換されます。

testdata = [........., 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 2000, 200, 85, 412412, 123, 41, 552, 50000, 512, 0.1, 10.0, 2.0, 0.05]

numpyの配列を1dから2dに整形してみましたが、テストデータと学習済みモデルの特徴数が一致しないため、うまくいきません。

質問ですが、学習済みモデルの特徴量の長さと同じnumpy配列を渡すにはどうしたらよいでしょうか?テストデータをローカルにリストとして渡すことで予測はできています。

推論スクリプトの詳細については、https ://github.com/aws-samples/amazon-sagemaker-local-mode/blob/main/xgboost_script_mode_local_training_and_serving/code/inference.pyをご覧ください。

Traceback (most recent call last):
File "/miniconda3/lib/python3.6/site-packages/sagemaker_containers/_functions.py", line 93, in wrapper
return fn(*args, **kwargs)
File "/opt/ml/code/inference.py", line 75, in predict_fn
prediction = model.predict(input_data)
File "/miniconda3/lib/python3.6/site-packages/xgboost/sklearn.py", line 448, in predict
test_dmatrix = DMatrix(data, missing=self.missing, nthread=self.n_jobs)
File "/miniconda3/lib/python3.6/site-packages/xgboost/core.py", line 404, in __init__
self._init_from_npy2d(data, missing, nthread)
File "/miniconda3/lib/python3.6/site-packages/xgboost/core.py", line 474, in _init_from_npy2d
raise ValueError('Input numpy.ndarray must be 2 dimensional')
ValueError: Input numpy.ndarray must be 2 dimensional




以下のように、リストをnumpyの2次元配列に変換してみてください。

a = np.array([1, 2, 3])

[1, 2, 3] をリストに置き換えます。




XGBoostはscikit-learnと同様、Xを2次元データ(n_samples,n_features)として想定しています。1つのサンプルを予測するために、リストや特徴ベクトルを2次元配列に整形する必要があります。

import numpy as np

lst = [1, 2, 3]
lst_reshaped = np.array(lst).reshape((1,-1))
clf.predict(lst_reshaped)