c++中的Xgboost负载模型(python ->c++预测分数不匹配)
xgboost load model in c++ (python -> c++ prediction scores mismatch)
我正在联系所有的c++天才。
我已经在python中训练(并成功测试)了xgboost模型,如下所示:
dtrain
=xgb.DMatrix(np.asmatrix(X_train),label=np.asarray(y_train,dtype=np.int), feature_names=feat_names)
optimal_model = xgb.train(plst, dtrain)
dtest = xgb.DMatrix(np.asmatrix(X_test),feature_names=feat_names)
optimal_model.save_model('sigdet.model')
我已经关注了一篇关于XgBoost的文章(见链接),它解释了在c++中加载和应用预测的正确方法:
// Load Model
g_learner = std::make_unique<Learner>(Learner::Create({}));
std::unique_ptr<dmlc::Stream> fi(
dmlc::Stream::Create(filename, "r"));
g_learner->Load(fi.get());
// Predict
DMatrixHandle h_test;
XGDMatrixCreateFromMat((float *)features, 1, numFeatures , -999.9f, &h_test);
xgboost::bst_ulong out_len;
std::vector<float> preds;
g_learner->Predict((DMatrix*)h_test,true, &preds);
我的问题(1):我需要创建一个DMatrix*,但是我只有一个DMatrixHandle。我如何正确地创建一个DMatrix与我的数据?
我的问题(2):当我尝试以下预测方法时:
DMatrixHandle h_test;
XGDMatrixCreateFromMat((float *)features, 1, numFeatures , -999.9f, &h_test);
xgboost::bst_ulong out_len;
int res = XGBoosterPredict(g_modelHandle, h_test, 1, 0, &out_len, (const float**)&scores);
我得到的分数与加载完全相同的模型并使用它进行预测(在python中)完全不同。
谁能帮助我在c++和python之间实现一致的结果,谁就可能上天堂。顺便说一句,我需要在c++中为实时应用程序应用预测,否则我会使用不同的语言。
要获取DMatrix,您可以这样做:
g_learner->Predict(static_cast<std::shared_ptr<xgboost::DMatrix>*>(h_test)->get(), true, &pred);
对于问题(2),我没有答案。这其实和我遇到的问题一样。我在python中有一个XGBRegression,我在c++中使用相同的功能获得了不同的结果。
所以你用来序列化你的模型的方法:
optimal_model.save_model('sigdet.model')
此方法剥离模型的所有特征名称(参见https://github.com/dmlc/xgboost/issues/3089)。
当您将模型加载到c++中进行预测时,不一定要维护列特征的顺序。您可以通过调用.dump_model()方法验证这一点。
此外,在Python和c++模型对象上调用.dump_model()将产生相同的决策树,但Python将具有所有特性名称,而c++可能具有f0, f1, f2, ....您可以比较这两种方法以获得实际的列排序,然后您的预测将跨语言匹配(不完全匹配,b/c四舍五入)。
我不知道列是如何排序的,但它似乎是一个稳定的过程,即使你在滑动数据窗口上重新训练相同的模型,也能保持排序。我不是百分之百有信心,也希望你能说清楚。
这个问题存在于许多Python训练的,其他语言预测的XGBoost模型中。我在Java中遇到过这个问题,似乎没有办法在XGBoost的不同绑定之间持久保存特性列的顺序。
下面是一个例子,但是程序的预测是相同的:
const int cols=3,rows=100;
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<50;i++)
train_labels[i] = 0;
for (int i=50;i<rows;i++)
train_labels[i] = 1;
// 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, "objective", "binary:logistic");
XGBoosterSetParam(h_booster, "eval_metric", "error");
XGBoosterSetParam(h_booster, "silent", "0");
XGBoosterSetParam(h_booster, "max_depth", "9");
XGBoosterSetParam(h_booster, "eta", "0.1");
XGBoosterSetParam(h_booster, "min_child_weight", "3");
XGBoosterSetParam(h_booster, "gamma", "0.6");
XGBoosterSetParam(h_booster, "colsample_bytree", "1");
XGBoosterSetParam(h_booster, "subsample", "1");
XGBoosterSetParam(h_booster, "reg_alpha", "10");
// perform 200 learning iterations
for (int iter=0; iter<10; iter++)
XGBoosterUpdateOneIter(h_booster, iter, h_train[0]);
// predict
const int sample_rows = 100;
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);
在问题(2)中,使用python训练模型,使用c++进行预测。特征向量为float*数组。
DMatrixHandle h_test;
XGDMatrixCreateFromMat((float *)features, 1, numFeatures , -999.9f, &h_test);
xgboost::bst_ulong out_len;
int res = XGBoosterPredict(g_modelHandle, h_test, 1, 0, &out_len, (const
float**)&scores);
所以你的模型需要使用密集矩阵格式(numpy数组)进行训练。以下是官方文档中的python代码片段。
data = np.random.rand(5, 10) # 5 entities, each contains 10 features
label = np.random.randint(2, size=5) # binary target
dtrain = xgb.DMatrix(data, label=label)
- Qt SQLite没有查询或参数计数不匹配
- 模板参数推导失败,函数参数/参数不匹配
- 在使用累加时,C++中的运算符+不匹配
- C++ 与操作员不匹配<<
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 与'operator='不匹配(操作数类型'String'且"void")
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- C4018:类内有符号、无符号不匹配
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 为什么我收到错误:"运算符<<不匹配?
- RE2 不匹配非 ASCII 字符
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 模板推导:为什么函数指针模板定义在常量和/或引用时不匹配?
- 错误:"模板<类_Tp,类_Dp>类 std::unique_ptr"的模板参数列表中参数 1 的类型/值不匹配
- OpenSSL fips in C++ wrapper Library 如何?错误:指纹不匹配
- 为什么我的数组值与此处的全局变量不匹配?
- 引号之间匹配/不匹配,带有不可避免的引号和多行
- 映射迭代器与运算符不匹配
- C++调用和定义不匹配
- 模板专用化与派生类不匹配