2016-03-17 18 views

risposta

17

ho finito per usare l'API C, vedi sotto un esempio:

// 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

Hai saputo come liberare 'const float * f;', quando prevedo grandi quantità di dati, sembra quella memoria non è stata liberata. Ho esaminato il codice 'XGDMatrixFree (h_test)' dovrebbe farlo, ma comunque la perdita di memoria aumenta con la dimensione h_test! – Khaledvic

+0

Sembra che la perdita sia altrove, hai confermato con Valgrind? – Tomer

+1

a quanto pare 'XGBoosterPredict' non è thread-safe, lo stavo chiamando da un gran numero di thread, https://github.com/dmlc/xgboost/issues/311 – Khaledvic

0

Non c'è alcun esempio di cui sono a conoscenza. c'è un file c_api.h che contiene un C/C++ api per il pacchetto, e dovrete trovare il modo di usarlo. L'ho appena fatto. Mi ci sono volute un paio d'ore per leggere il codice e provare alcune cose. Ma alla fine sono riuscito a creare un esempio C++ funzionante di xgboost.

0

per risolvere questo problema che esegue il programma xgboost dal codice sorgente C++.

1

Utilizzare l'API C XGBoost.

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); 

Nota quando si desidera caricare un modello esistente (come il codice sopra mostra), si deve garantire il formato dei dati nel campo della formazione è lo stesso che nel predire. Quindi, se prevedi con XGBoosterPredict, che accetta una matrice densa come parametro, devi usare la matrice densa in allenamento.

formazione con il formato libsvm e prevedere con matrice densa possono causare previsioni sbagliate, come XGBoost FAQ dice:

elementi “sparse” sono trattati come se fossero “Missing” dal richiamo albero, e come zeri da il ripetitore lineare. Per i modelli ad albero, è importante utilizzare formati di dati coerenti durante l'allenamento e il punteggio.