机器学习_XGBoost模型_用C++推理示例Demo

1. 需求

将 python 训练好的 xgboost 模型, 使用C++ 进行加载并进行推理(预测)

2. 代码实现

cpp 复制代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <xgboost/c_api.h>

const char *model_path = "my_xgb.model";

// 预测单条数据
void test_xgboost_one_item(std::vector<float> features)
{
    // load confidence prediction model
    BoosterHandle booster;
    XGBoosterCreate(NULL, 0, &booster);
    XGBoosterLoadModel(booster, model_path);

    DMatrixHandle dtest;
    XGDMatrixCreateFromMat(reinterpret_cast<float*>(&features[0]), 1, features.size(), 0, &dtest);

    // 进行预测
    const float *out_result;
    unsigned long out_len;
    XGBoosterPredict(booster, dtest, 0, 0, 0, &out_len, &out_result);

    // 输出预测结果
    std::cout << "Prediction result: ";
    for (unsigned long i = 0; i < out_len; ++i) {
        std::cout << out_result[i] << " ";
    }
    std::cout << std::endl;

    // 释放资源
    XGDMatrixFree(dtest);
    XGBoosterFree(booster);

}

// 预测多条数据(来自文件.txt)
void test_xgboost_from_file(std::string file_name)
{
    BoosterHandle booster;
    XGBoosterCreate(NULL, 0, &booster);
    XGBoosterLoadModel(booster, model_path);

    // 打开文件
    std::ifstream datasets_file(file_name);
    if (!datasets_file.is_open()) {
        std::cerr << "Failed to open the file: " << file_name << std::endl;
    }

    // 读取文件内容并存储到二维vector数组中
    std::vector<std::vector<float>> test_data_src;

    std::string line;

    while (std::getline(datasets_file, line))
    {
        std::istringstream iss(line);
        std::vector<float> row_src;
        std::string token;
        
        //仅读取一行中的前7个数据,举例.
        for (int i = 0; i < 7; ++i)
        {
            // 读取每行的前7个元素
            std::getline(iss, token, ',');
            float value = std::stof(token);
            row_src.push_back(value);
        }
        test_data_src.push_back(row_src);
    }

    // 关闭文件
    datasets_file.close();
    
    std::cout << "====== test_data_src ========" << std::endl;
    // 输出二维vector数组中的数据(可选)
    for (const auto& row : test_data_src) {
        for (const auto& value : row) {
            std::cout << value << " ";
        }
        std::cout << std::endl;
    }

    //注意: test data 需要 和训练模型时的数据保持一致, 即经过相同的预处理(若有)
    
    //注意: 重要操作, 为了通过第一个数据地址,访问到所有数据.
    // 将二维vector数组转换为一维的连续内存块
    std::vector<float> flatData;
    for (const auto& row : test_data_src) {
        flatData.insert(flatData.end(), row.begin(), row.end());
    }

    // 将测试数据转换为DMatrix格式
    DMatrixHandle dtest;
    bst_ulong nrow = test_data_src.size();
    bst_ulong ncol = test_data_src[0].size();
    XGDMatrixCreateFromMat(flatData.data(), nrow, ncol, 0, &dtest);

    // 进行预测
    const float *out_result;
    unsigned long out_len;
    XGBoosterPredict(booster, dtest, 0, 0, 0, &out_len, &out_result);

    // 输出预测结果
    std::cout << "Prediction result: " << std::endl;;
    for (unsigned long i = 0; i < out_len; ++i) {
        std::cout << out_result[i] << " "<< std::endl;
    }
    std::cout << std::endl;

    // 保存预测结果到文件(可选)
    std::ofstream file_prediction("predict_result.txt", std::ofstream::trunc);
    if (!file_prediction.is_open()) {
        std::cerr << "Failed to open the file." << std::endl;
    }

    for (unsigned long i = 0; i < out_len; ++i) {
        file_prediction << out_result[i] << " "<< std::endl;
    }
    // 关闭文件
    file_prediction.close();

    // 释放资源
    XGDMatrixFree(dtest);
    XGBoosterFree(booster);

}
int main(int argc, char **argv) {
    
    // 测试1: 仅预测一条数据 (使用7个feture,预测输出一个output数据)
    std::vector<float> features = {0.562000, 0.739818, 0.917457, 0.943217, 0.055662, 0.994000, 0.995506};
    test_xgboost_one_item(features);

    // 测试2: 预测存储在文件中的多条数据 (使用7个feture,预测输出一个output数据)
    std::string test_data_normalsets = "test_data.txt";
    // test_data.txt 内容:
        // 0.562000 0.739818 0.917457 0.943217 0.055662 0.994000 0.995506
        // 0.548000 0.737632 0.910190 0.943415 0.000000 0.994591 0.997773
        // 0.544000 0.738136 0.924542 0.944812 0.563753 0.994729 0.996054
        // 0.556000 0.740211 0.919053 0.945792 0.000000 0.999281 0.990547
    test_xgboost_from_file(test_data_normalsets);
    
    std::cout << "==== Done ====" << std::endl;
    return 0;
}

3. 注意

注意: test data 需要 和训练模型时的数据保持一致, 即经过相同的预处理(若有)

XGBoosterPredict() / 参数说明:

cpp 复制代码
int XGBoosterPredict	(	
    BoosterHandle 	handle,
    DMatrixHandle 	dmat,
    int 	option_mask,
    unsigned 	ntree_limit,    
    int 	training,
    bst_ulong * 	out_len,
    const float ** 	out_result 
)	
  • handle:句柄
  • dmat:数据矩阵
  • option_mask:选项的位掩码,用于预测,可能的取值为 0: 正常预测 1: 输出边缘值而不是转换后的值 2: 输出树的叶子索引而不是叶子值,注意,叶子索引在每棵树中是唯一的 4: 输出单个预测的特征贡献
  • ntree_limit:限制用于预测的树的数量,这仅适用于提升树,当参数设置为0时,我们将使用所有树 training:预测函数是否用作训练循环的一部分。
    • 可以在两种情况下运行预测: 给定数据矩阵 X,从模型中获取预测 y_pred。 获取用于计算梯度的预测。例如,DART 提升器在训练期间执行了 dropout,由于被舍弃的树,预测结果与正常推断步骤获取的结果不同。
    • 对于第一个场景,设置 training=false。对于第二个场景,设置 training=true。第二个场景适用于定义自定义目标函数时。
  • out_len:用于存储返回结果的长度
  • out_result:用于设置指向数组的指针

参考:

相关推荐
zozowind几秒前
OpenManus系列(5):3月11日更新分支分拆,MCP闪亮登场
人工智能
Baihai_IDP2 分钟前
为什么说JSON不一定是LLM结构化输出的最佳选择?
人工智能·llm·aigc
cdut_suye4 分钟前
全面剖析 Linux 进程管理与 PCB 机制
java·linux·运维·服务器·c++·人工智能·python
新加坡内哥谈技术4 分钟前
CoreWeave:从“微软专供”到OpenAI的座上宾
人工智能
@心都10 分钟前
机器学习数学基础:45.多重响应分析
人工智能·机器学习
进阶的小蜉蝣11 分钟前
[machine learning] DP(Data Parallel) vs DDP(Distributed Data Parallel)
人工智能·机器学习
YuhsiHu26 分钟前
【论文精读】ACE-Zero
人工智能·深度学习·计算机视觉·3d·机器人
声网29 分钟前
Tavus 发布对话轮次控制模型:能理解对话节奏和意图;百度推出 AI 情感陪伴应用月匣,整合 MiniMax 等模型丨日报
人工智能
晴空对晚照31 分钟前
[动手学习深度学习]12.权重衰退
人工智能·深度学习·学习
蹦蹦跳跳真可爱5891 小时前
Python----计算机视觉处理(opencv:图片灰度化)
人工智能·python·opencv·计算机视觉