我必须在某些编程语言(Golang 和 Python)中使用 Catboost 模型。最好的选择(为了性能和兼容性)是使用评估库,它可以是 C 或 C++ API。我关注了official documentation编译C API,但它有很多问题需要解决才能工作。
这些是我们在尝试用 C 语言创建评估库时遇到的问题:
1.
error: variable has incomplete type 'ModelCalcerHandle' (aka 'void')
ModelCalcerHandle modelHandle;
c_wrapper.c:16:13: warning: incompatible pointer types passing 'float (*)[3]' to parameter of type 'const float **' [-Wincompatible-pointer-types]
&floatFeatures, 3,
^~~~~~~~~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:151:19: note: passing argument to parameter 'floatFeatures' here
const float** floatFeatures, size_t floatFeaturesSize,
^
c_wrapper.c:17:13: warning: incompatible pointer types passing 'char *(*)[4]' to parameter of type 'const char ***' [-Wincompatible-pointer-types]
&catFeatures, 4,
^~~~~~~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:152:19: note: passing argument to parameter 'catFeatures' here
const char*** catFeatures, size_t catFeaturesSize,
^
c_wrapper.c:18:13: warning: incompatible pointer types passing 'double (*)[1]' to parameter of type 'double *' [-Wincompatible-pointer-types]
&result, 1
^~~~~~~
/Users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:153:13: note: passing argument to parameter 'result' here
double* result, size_t resultSize);
解决方案:
- 我们通过将
modelHandle
变量重新定义为以下方式解决了问题 #1:
ModelCalcerHandle *modelHandle = ModelCalcerCreate();
进行此更改后,可以编译 C 程序,但我们收到了一个新错误:
[1] 6489 segmentation fault ./program
- 段错误与问题 #2 中列出的警告有关。我们必须重新定义变量来解决它:
float floatFeaturesRaw[100];
const float *floatFeatures = floatFeaturesRaw;
const char *catFeaturesRaw[2] = {"1", "2"};
const char **catFeatures = catFeaturesRaw;
double resultRaw[1];
double *result = resultRaw;
和
if (!CalcModelPredictionSingle(
modelHandle,
&floatFeatures, 3,
&catFeatures, 4,
result, 1)) //We remove `&`
{
printf("CalcModelPrediction error message: %s\n", GetErrorString());
}
我将在评论中添加完整的解决方案,从代码修复到如何编译 C 代码。
最佳答案
这是完整的解决方案:
- 克隆 catboost 存储库:
git 克隆 https://github.com/catboost/catboost.git
从 CatBoost 存储库的本地副本中打开 catboost 目录。
构建评估库(我选择了共享库,但您可以选择您需要的库)。就我而言,我必须更改
--target-platform
参数,我使用的是 Mac M1 和 macOS Ventura 13.1,clang 版本是 14.0.0:
./ya make -r catboost/libs/model_interface --target-platform CLANG14-DARWIN-ARM64
- 创建 C 文件。修复了 C 示例代码:
#include <stdio.h>
#include <c_api.h>
int main()
{
float floatFeaturesRaw[3] = {0, 89, 1};
const float *floatFeatures = floatFeaturesRaw;
const char *catFeaturesRaw[4] = {"Others", "443_HTTPS", "6", "24"};
const char **catFeatures = catFeaturesRaw;
double resultRaw[4];
double *result = resultRaw;
ModelCalcerHandle *modelHandle = ModelCalcerCreate();
if (!LoadFullModelFromFile(modelHandle, "catboost_model"))
{
printf("LoadFullModelFromFile error message: %s\n", GetErrorString());
}
SetPredictionType(modelHandle, 3);
if (!CalcModelPredictionSingle(
modelHandle,
floatFeatures, 3,
catFeatures, 4,
result, 4))
{
printf("CalcModelPrediction error message: %s\n", GetErrorString());
}
printf("%f\n", result[0]);
printf("%f\n", result[1]);
printf("%f\n", result[2]);
printf("%f\n", result[3]);
ModelCalcerDelete(modelHandle);
}
考虑:
- 我已将
SetPredictionType
设置为 APT_PROBABILITY - 我们的模型预测多个类别,因此
结果[4]
。 - 我们一次只需要预测一条记录,因此我们使用
CalcModelPredictionSingle
方法。
- 编译 C 代码:
gcc -v -o program.out c_code.c -l catboostmodel -I /path/to/catboost/repo/catboost/catboost/libs/model_interface/ -L /path/to/catboost/repo/catboost/catboost/libs/model_interface/
重要提示:确保未显示任何警告或错误消息。
- 现在您可以运行它:
重要提示:确保 catboost 模型文件与 program.out
位于同一路径。
./program.out
关于c - 如何构建Catboost C评估库API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74962479/