本文作者为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 <

// file data

const char* para = "None";

int res = LGBM_BoosterPredictForFile(handle, "test_data.csv", 0, C_API_PREDICT_NORMAL, 0, para, "result");

std::cout << "file predict result is " << res << std::endl;

// row data

std::vector 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<:string> header_words = Common::Split(first_line.c_str(), "\t,");

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<:pair double>>* 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<:string>& lines) {

std::vector<:pair double>> oneline_features;

std::vector<:string> 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, "\t");

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("\n", 1);

}

};

predict_data_reader.ReadAllAndProcessParallel(process_fun);

}

lightgbm java_如何在C++程序中调用lightgbm (How to use lightgbm in C++ program)相关推荐

  1. 如何在Java程序中调用Python算法脚本,重点讲Demo,不墨迹理论

    原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重. 前言 通过本篇,你将初步认识在Java程序中简单调用.py脚本文件的方法,附带入门的Demo实例讲解,更深入的理解还需要进一步学习. 最近 ...

  2. 本地方法(JNI)——从java 程序中调用C函数

    [0]README 1) 本文部分文字描述 转自 core java volume 2 , 旨在理解 本地方法--从java 程序中调用C函数 的基础知识 : 2) for source code, ...

  3. 在VB应用程序中调用Excel2000

    Visual Basic简称(VB)是设计Windows应用程序强有力的开发工具,"全球绝大多数Windows应用程序都是用VB开发的": Excel是目前使用最广泛的办公应用软件 ...

  4. EFR32--如何在EFR32程序中修改UUID

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/MemsanGZmInG/article ...

  5. php防止文件盗链,如何在PHP程序中防止盗链

    如何在PHP程序中防止盗链 example: 页面: dl.php ------------------------------------------------------------------ ...

  6. Golang cgo:如何在Go代码中调用C语言代码?

    如何在Go代码中调用C语言代码? Go语言是通过自带的一个叫CGO的工具来支持C语言函数调用,同时我们可以用Go语言导出C动态库接口给其它语言使用. 方式一.直接在 Go 代码中写入 C 代码 检查是 ...

  7. 如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样)

    如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样) python标准库中的subprocess可以解决这个问题. from subprocess ...

  8. php变量在html调用函数调用,PHP_如何在html标记中调用的函数里传递对象,最近使用jquery结合Ajax开发一个 - phpStudy...

    如何在html标记中调用的函数里传递对象 最近使用jquery结合Ajax开发一个中小型网站应用.在后台管理中要使用Ajax调用系统功能,根据Ajax的返回结果,使用jQuery对前台页面进行操作. ...

  9. Linux jsp php集成环境,ImageMagick在程序中调用(linux环境,jsp,php)

    最近发现图片格式为cmyk时,图片上传浏览器不能正常显示,图片缩放会变成黑屏, 后来通过google发现imagemagick的功能很强大,安装可以采用两种方法,1)直接与php编译安装,在程序中调用 ...

最新文章

  1. echarts X轴 或者 Y轴 添加标识线
  2. RocksDB线程局部缓存
  3. SQL Case When Then 条件判断
  4. 随机取6位数字或字母方法
  5. 【2】HashMap
  6. nagios利用pyfetion报警最新
  7. Google今日更新PR值,帆船书会由1升到了3
  8. 学完java学swift_前言最近学完Swift之后一直没有机会实战,发现由于Swift发展历史原因,目前网上大部分的算法都是使用C、Java或其他语言实现的,几乎没有使用Swift实...
  9. 前端学习(2584):ant design pro
  10. mysql 默认page大小_MySQL innodb_page_size
  11. C语言和设计模式(之组合模式)
  12. 智能寻迹(循迹)小车项目思路 + 代码
  13. 长沙理工大学数据结构2013-2014学年二学期末数据结构期末考试试卷(B卷)
  14. H3C交换机s5500Web登录配置
  15. java纸牌_Java纸牌拖拉机简单模拟
  16. 衷心感谢各位给我投的票!
  17. Prometheus源码系列:指标缓存(scrapeCache)
  18. pr中导出视频的应用,快速制作竖版短视频
  19. android百度天气接口api接口,百度天气接口api
  20. 在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)”

热门文章

  1. Log4j2漏洞修复
  2. elastic search,又一个基于lucene的nosql好项目
  3. MySQL中tinytext、text、mediumtext和longtext详解
  4. 智慧养老:一套完整的养老院人员定位解决方案,全面解决养老院人员管理的弊端-新导智能
  5. 运动圈(运动社交)App
  6. 基于ISO 21448和STPA方法的自动驾驶安全性和可靠性设计
  7. Python自动化开发【5】:Python常用模块
  8. 大数据学习资料和书籍推荐
  9. Oracle通过imp导入dmp文件相关
  10. 女人要自立,男人要自强