2016-03-17 18 views

Odpowiedz

17

skończyło się używając C API, patrz poniżej przykład:

// 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); 
+0

Czy wiesz jak zwolnić 'const float * f;', kiedy przewiduję dużą ilość danych, wydaje się ta pamięć nie jest wolna. Zajrzałem do kodu 'XGDMatrixFree (h_test)' powinien to zrobić, ale nadal przeciek pamięci rośnie wraz z rozmiarem h_test! – Khaledvic

+0

Wygląda na to, że wyciek jest gdzie indziej, czy potwierdziłeś z Valgrind? – Tomer

+1

podobno 'XGBoosterPredict' nie jest bezpieczny dla wątków, dzwoniłem do niego z dużej liczby wątków, https://github.com/dmlc/xgboost/issues/311 – Khaledvic

0

Nie ma na przykład takiego przykładu. istnieje plik c_api.h, który zawiera api C/C++ dla pakietu, i będziesz musiał znaleźć sposób, aby go użyć. Właśnie to zrobiłem. Zajęło mi kilka godzin czytanie kodu i wypróbowywanie kilku rzeczy. Ale ostatecznie udało mi się stworzyć działający przykład C++ xgboost.

0

Aby rozwiązać ten problem, że działa program xgboost z kodem źródłowym C++.

1

Użyj 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); 

Uwaga, jeśli chcesz załadować istniejący model (jak pokazuje powyższy kod), trzeba upewnić się, format danych w szkoleniu jest taka sama jak w przewidywaniu. Tak więc, jeśli przewidujesz z XGBoosterPredict, który akceptuje gęstą macierz jako parametr, musisz użyć gęstej matrycy w treningu.

Szkolenie z formatu libsvm i przewidzieć z gęstej matrycy może powodować błędne prognozy, jak XGBoost FAQ mówi:

„Rzadkie” elementy są traktowane tak, jakby były one „brakuje” przez wzmacniacz drzewa, a jako zera przez liniowy wzmacniacz. W przypadku modeli drzew ważne jest stosowanie spójnych formatów danych podczas treningu i punktacji.