web-dev-qa-db-ja.com

C ++でのXGBOOSTの使用

C++でXGBOOST https://github.com/dmlc/xgboost/ ライブラリを使用するにはどうすればよいですか? PythonおよびJava APIを設立しましたが、c ++用のAPIが見つかりません

18
V. Gai

最終的にC APIを使用しました。以下の例を参照してください。

// create the train data
int cols=3,rows=5;
float train[rows][cols];
for (int i=0;i<rows;i++)
    for (int j=0;j<cols;j++)
        train[i][j] = (i+1) * (j+1);

float train_labels[rows];
for (int i=0;i<rows;i++)
    train_labels[i] = 1+i*i*i;


// convert to DMatrix
DMatrixHandle h_train[1];
XGDMatrixCreateFromMat((float *) train, rows, cols, -1, &h_train[0]);

// load the labels
XGDMatrixSetFloatInfo(h_train[0], "label", train_labels, rows);

// read back the labels, just a sanity check
bst_ulong bst_result;
const float *out_floats;
XGDMatrixGetFloatInfo(h_train[0], "label" , &bst_result, &out_floats);
for (unsigned int i=0;i<bst_result;i++)
    std::cout << "label[" << i << "]=" << out_floats[i] << std::endl;

// create the booster and load some parameters
BoosterHandle h_booster;
XGBoosterCreate(h_train, 1, &h_booster);
XGBoosterSetParam(h_booster, "booster", "gbtree");
XGBoosterSetParam(h_booster, "objective", "reg:linear");
XGBoosterSetParam(h_booster, "max_depth", "5");
XGBoosterSetParam(h_booster, "eta", "0.1");
XGBoosterSetParam(h_booster, "min_child_weight", "1");
XGBoosterSetParam(h_booster, "subsample", "0.5");
XGBoosterSetParam(h_booster, "colsample_bytree", "1");
XGBoosterSetParam(h_booster, "num_parallel_tree", "1");

// perform 200 learning iterations
for (int iter=0; iter<200; iter++)
    XGBoosterUpdateOneIter(h_booster, iter, h_train[0]);

// predict
const int sample_rows = 5;
float test[sample_rows][cols];
for (int i=0;i<sample_rows;i++)
    for (int j=0;j<cols;j++)
        test[i][j] = (i+1) * (j+1);
DMatrixHandle h_test;
XGDMatrixCreateFromMat((float *) test, sample_rows, cols, -1, &h_test);
bst_ulong out_len;
const float *f;
XGBoosterPredict(h_booster, h_test, 0,0,&out_len,&f);

for (unsigned int i=0;i<out_len;i++)
    std::cout << "prediction[" << i << "]=" << f[i] << std::endl;


// free xgboost internal structures
XGDMatrixFree(h_train[0]);
XGDMatrixFree(h_test);
XGBoosterFree(h_booster);
28
Tomer

XGBoost C APIを使用します。

  BoosterHandle booster;
  const char *model_path = "/path/of/model";

  // create booster handle first
  XGBoosterCreate(NULL, 0, &booster);

  // by default, the seed will be set 0
  XGBoosterSetParam(booster, "seed", "0");

  // load model
  XGBoosterLoadModel(booster, model_path);

  const int feat_size = 100;
  const int num_row = 1;
  float feat[num_row][feat_size];

  // create some fake data for predicting
  for (int i = 0; i < num_row; ++i) {
    for(int j = 0; j < feat_size; ++j) {
      feat[i][j] = (i + 1) * (j + 1)
    }
  }

  // convert 2d array to DMatrix
  DMatrixHandle dtest;
  XGDMatrixCreateFromMat(reinterpret_cast<float*>(feat),
                         num_row, feat_size, NAN, &dtest);

  // predict
  bst_ulong out_len;
  const float *f;
  XGBoosterPredict(booster, dtest, 0, 0, &out_len, &f);
  assert(out_len == num_row);
  std::cout << f[0] << std::endl;

  // free memory
  XGDMatrixFree(dtest);
  XGBoosterFree(booster);

(上記のコードが示すように)既存のモデルをロードする場合は、トレーニングのデータ形式が予測と同じであることを確認する必要があります。したがって、密行列をパラメーターとして受け入れるXGBoosterPredictで予測する場合は、トレーニングで密行列を使用する必要があります。

XGBoost FAQ が言うように、libsvm形式でトレーニングし、密行列で予測すると、誤った予測が発生する可能性があります。

「スパース」要素は、ツリーブースターでは「欠落」しているかのように、線形ブースターではゼロとして扱われます。ツリーモデルの場合、トレーニングおよびスコアリング中に一貫したデータ形式を使用することが重要です。

4
Alan

この問題を解決するために、C++ソースコードからxgboostプログラムを実行します。

0
V. Gai

私が知っている例はありません。パッケージのC/C++ APIを含むc_api.hファイルがあり、それを使用する方法を見つける必要があります。私はちょうどそれをやった。数時間かけてコードを読み、いくつかのことを試しました。しかし、結局私はxgboostの実際のC++サンプルを作成することができました。

0
amit