资讯专栏INFORMATION COLUMN

如何在C++程序中调用lightgbm (How to use lightgbm in C++ pr

xavier / 3645人阅读

摘要:本文作者为,有任何问题请联系以轻量著称,所以在实际的程序中,常常需要使用。但是官方文档并没有介绍如何在中调用接口,也没有任何例子可供参考,网上的文档也基本没有。这篇文章中我介绍下如何在中调用。调用的代码片段如下。

本文作者为tieying zhang,有任何问题请联系zhangtiey@gmail.com

Lightgbm以轻量著称,所以在实际的C++程序中,常常需要使用。但是官方文档并没有介绍如何在C++中调用lightgbm接口,也没有任何例子可供参考,网上的文档也基本没有。这篇文章中我介绍下如何在C++中调用lightgbm。有任何问题请联系zhangtiey@gmail.com

具体步骤如下:

首先需要下载lightgbm的源码包,从官网下载即可。官网也给出了如何编译,但是最后一定要sudo make install(这个官网没有给出)。

C++调用的代码片段如下。首先load已经train好的model(以txt的形式存在磁盘上),之后用该模型进行inference,需要预测的数据可以是文件形式直接指定目录,也可以直接多行数据塞给模型。

编译C++文件:g++ -g -Wall -std=c++11 test.cpp -l_lightgbm 注意,用到了l_lightgbm,这个.so库是上面make install直接放入到了/usr/local/lib下。如果找不到该库,需要whereis查看一下,把相应目录加入到lib path里如:export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib

#include 
#include 
#include 

std::string predict(std::string data)
{
    std::string pred_result = "";
    int temp;
    int p = 1;
    BoosterHandle handle;  
    
    // load model 
    temp = LGBM_BoosterCreateFromModelfile("test_model1.txt", &p, &handle);    
    std::cout <<"load result value is "< row(40, 0);
    void* in_p = static_cast(row.data());
    
    std::vector out(1, 0);
    double* out_result = static_cast(out.data());
    
    int64_t out_len;
    res = LGBM_BoosterPredictForMat(handle, in_p, C_API_DTYPE_FLOAT32, 1, 40, 1, C_API_PREDICT_NORMAL, 50, "None", &out_len, out_result);
    std::cout << "row predict return is " << res << std::endl;
    std::cout << "row predict result size is " << out.size() << " value is " << out[0] << std::endl;
   
    return pred_result; 
    /*I know the above return statement is completely insignificant. But i wanted to use the loaded model to predict the data points further.*/
}

int main() {
  predict("hahaha"); 
   
  std::cout << "Ok complete!"<< std::endl;
  return 0;
}

遇到的问题汇总:

lib_lightgbm.so: cannot open shared object file: No such file or directory

export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib

代码参照

data_size_t定义在include/LightGBM/meta.h

typedef int32_t data_size_t;

用C++解析输入file可以借鉴已有code:在application/predictor.hpp中。注意比较重要的是TextReader predict_data_reader(data_filename, header)使用了utils下面的utils/text_reader.h

真正的predict函数在application/predictor.cpp里:

/*!

brief predicting on data, then saving result to disk

param data_filename Filename of data

param result_filename Filename of output result

  */
  void Predict(const char* data_filename, const char* result_filename, bool header) {
    auto writer = VirtualFileWriter::Make(result_filename);
    if (!writer->Init()) {
      Log::Fatal("Prediction results file %s cannot be found", result_filename);
    }
    auto parser = std::unique_ptr(Parser::CreateParser(data_filename, header, boosting_->MaxFeatureIdx() + 1, boosting_->LabelIdx()));

    if (parser == nullptr) {
      Log::Fatal("Could not recognize the data format of data file %s", data_filename);
    }

    TextReader predict_data_reader(data_filename, header);
    std::unordered_map feature_names_map_;
    bool need_adjust = false;
    if (header) {
      std::string first_line = predict_data_reader.first_line();
      std::vector header_words = Common::Split(first_line.c_str(), "	,");
      header_words.erase(header_words.begin() + boosting_->LabelIdx());
      for (int i = 0; i < static_cast(header_words.size()); ++i) {
        for (int j = 0; j < static_cast(boosting_->FeatureNames().size()); ++j) {
          if (header_words[i] == boosting_->FeatureNames()[j]) {
            feature_names_map_[i] = j;
            break;
          }
        }
      }
      for (auto s : feature_names_map_) {
        if (s.first != s.second) {
          need_adjust = true;
          break;
        }
      }
    }
    // function for parse data
    std::function>*)> parser_fun;
    double tmp_label;
    parser_fun = [&]
    (const char* buffer, std::vector>* feature) {
      parser->ParseOneLine(buffer, feature, &tmp_label);
      if (need_adjust) {
        int i = 0, j = static_cast(feature->size());
        while (i < j) {
          if (feature_names_map_.find((*feature)[i].first) != feature_names_map_.end()) {
            (*feature)[i].first = feature_names_map_[(*feature)[i].first];
            ++i;
          } else {
            //move the non-used features to the end of the feature vector
            std::swap((*feature)[i], (*feature)[--j]);
          }
        }
        feature->resize(i);
      }
    };

    std::function&)> process_fun = [&]
    (data_size_t, const std::vector& lines) {
      std::vector> oneline_features;
      std::vector result_to_write(lines.size());
      OMP_INIT_EX();
      #pragma omp parallel for schedule(static) firstprivate(oneline_features)
      for (data_size_t i = 0; i < static_cast(lines.size()); ++i) {
        OMP_LOOP_EX_BEGIN();
        oneline_features.clear();
        // parser
        parser_fun(lines[i].c_str(), &oneline_features);
        // predict
        std::vector result(num_pred_one_row_);
        predict_fun_(oneline_features, result.data());
        auto str_result = Common::Join(result, "	");
        result_to_write[i] = str_result;
        OMP_LOOP_EX_END();
      }
      OMP_THROW_EX();
      for (data_size_t i = 0; i < static_cast(result_to_write.size()); ++i) {
        writer->Write(result_to_write[i].c_str(), result_to_write[i].size());
        writer->Write("
", 1);
      }
    };
    predict_data_reader.ReadAllAndProcessParallel(process_fun);
  }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/48368.html

相关文章

  • 使用机器学习识别出拍卖场作弊的机器人用户(二)

    摘要:本文承接上一篇文章使用机器学习识别出拍卖场中作弊的机器人用户本项目为上举行的一次比赛,地址见数据来源,完整代码见我的欢迎来玩代码数据探索数据预处理特征工程模型设计及评测项目数据来源项目所需额外工具包含有聚和算法项目整体运行时间预估为左右,在 本文承接上一篇文章:使用机器学习识别出拍卖场中作弊的机器人用户 本项目为kaggle上Facebook举行的一次比赛,地址见数据来源,完整代码见我...

    YanceyOfficial 评论0 收藏0
  • 使用机器学习识别出拍卖场作弊的机器人用户(二)

    摘要:本文承接上一篇文章使用机器学习识别出拍卖场中作弊的机器人用户本项目为上举行的一次比赛,地址见数据来源,完整代码见我的欢迎来玩代码数据探索数据预处理特征工程模型设计及评测项目数据来源项目所需额外工具包含有聚和算法项目整体运行时间预估为左右,在 本文承接上一篇文章:使用机器学习识别出拍卖场中作弊的机器人用户 本项目为kaggle上Facebook举行的一次比赛,地址见数据来源,完整代码见我...

    3fuyu 评论0 收藏0
  • mac 安装 lightgbm 无法导入(以及解决cmake命令无法编译)

    摘要:一般的包在用上述命令安装后,就可正常使用,但是编译依赖,不支持。给出如下图的错误官网也有给出在上安装的方法,但我在执行命令时,总是无法成功,跳过这个坑花了好久,下面给出成功安装的方法。系统包首先保证你的电脑装了,下面用到命令。 最近在看数据分析,用到 python 的 lightgbm 包,直接用 pip install lightgbm 命令安装后,在 import lightgbm...

    BetaRabbit 评论0 收藏0
  • V8 从 JavaScript 到 C++ 的类型转换

    摘要:本文转载自众成翻译译者乱发小生链接原文学习怎样传递信息从到是一个非常难的事情。原因在于和两种语言类型之间的巨大差异。你可以在这里查看所有的类型。这两个组件松散和严格的表明一系列函数接收不同类型的参数,,,和和它们的返回值。 本文转载自:众成翻译译者:乱发小生链接:http://www.zcfy.cc/article/3360原文:https://nodeaddons.com/type-...

    betacat 评论0 收藏0
  • [CS101] Programming Languages and OOP 编程语言及面向对象基础题

    摘要:编程语言及面向对象基础题 编程语言及面向对象基础题 Design Pattern What is singleton? Whats its cons and pros? How to implement it?Definition: Singleton pattern is a design pattern that ensure that only one instance of a...

    Drinkey 评论0 收藏0

发表评论

0条评论

xavier

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<