win11下c++/msvc使用动态运行时库编译机器学习库LightGBM
win11下c++/msvc使用动态运行时库编译的操作见我写的文章
https://blog.csdn.net/hyl20012/article/details/153516758?spm=1011.2124.3001.6209
操作过程大致相同。
配置条件:win11、clion c++、LightGBM、以及LightGBM的依赖库eigen和fmt。
eigen的配置见我写的文章 https://blog.csdn.net/hyl20012/article/details/147638951?spm=1001.2014.3001.5502
本文操作过程如下:先到官网( https://github.com/microsoft/LightGBM/releases )下载LightGBM的源代码Source code(zip)。解压到硬盘,我的路径是 G:\software\LightGBM460
上面这个目录下有个文件CMakeLists。这个文件需要修改,直接替换成如下的内容
option(USE_MPI "Enable MPI-based distributed learning" OFF)
option(USE_OPENMP "Enable OpenMP" ON)
option(USE_GPU "Enable GPU-accelerated training" OFF)
option(USE_SWIG "Enable SWIG to generate Java API" OFF)
option(USE_TIMETAG "Set to ON to output time costs" OFF)
option(USE_CUDA "Enable CUDA-accelerated training " OFF)
option(USE_DEBUG "Set to ON for Debug mode" OFF)
option(USE_SANITIZER "Use sanitizer flags" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(
ENABLED_SANITIZERS
"address" "leak" "undefined"
CACHE
STRING
"Semicolon separated list of sanitizer names, e.g., 'address;leak'. \
Supported sanitizers are address, leak, undefined and thread."
)
option(USE_HOMEBREW_FALLBACK "(macOS-only) also look in 'brew --prefix' for libraries (e.g. OpenMP)" ON)
option(BUILD_CLI "Build the 'lightgbm' command-line interface in addition to lib_lightgbm" ON)
option(BUILD_CPP_TEST "Build C++ tests with Google Test" OFF)
#option(BUILD_STATIC_LIB "Build static library" OFF)
option(INSTALL_HEADERS "Install headers to CMAKE_INSTALL_PREFIX (e.g. '/usr/local/include')" ON)
option(__BUILD_FOR_PYTHON "Set to ON if building lib_lightgbm for use with the Python-package" OFF)
option(__BUILD_FOR_R "Set to ON if building lib_lightgbm for use with the R-package" OFF)
option(__INTEGRATE_OPENCL "Set to ON if building LightGBM with the OpenCL ICD Loader and its dependencies included" OFF)
cmake_minimum_required(VERSION 3.28)
# If using Visual Studio generators, always target v10.x of the Windows SDK.
# Doing this avoids lookups that could fall back to very old versions, e.g. by finding
# outdated registry entries.
# ref: https://cmake.org/cmake/help/latest/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.html
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(CMAKE_SYSTEM_VERSION 10.0 CACHE INTERNAL "target Windows SDK version" FORCE)
endif()
project(lightgbm LANGUAGES C CXX)
# ========== 添加动态运行时库配置 ==========
# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置动态运行时库
if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
#-- Sanitizer
if(USE_SANITIZER)
if(MSVC)
message(FATAL_ERROR "Sanitizers are not supported with MSVC.")
endif()
include(cmake/Sanitizer.cmake)
enable_sanitizers("${ENABLED_SANITIZERS}")
endif()
if(__INTEGRATE_OPENCL)
set(__INTEGRATE_OPENCL ON CACHE BOOL "" FORCE)
set(USE_GPU OFF CACHE BOOL "" FORCE)
message(STATUS "Building library with integrated OpenCL components")
endif()
if(__BUILD_FOR_PYTHON OR __BUILD_FOR_R OR USE_SWIG)
# the SWIG wrapper, the Python and R packages don't require the CLI
set(BUILD_CLI OFF)
# installing the SWIG wrapper, the R and Python packages shouldn't place LightGBM's headers
# outside of where the package is installed
set(INSTALL_HEADERS OFF)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.2")
message(FATAL_ERROR "Insufficient gcc version")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.8")
message(FATAL_ERROR "Insufficient Clang version")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.1.0")
message(FATAL_ERROR "Insufficient AppleClang version")
endif()
elseif(MSVC)
if(MSVC_VERSION LESS 1900)
message(
FATAL_ERROR
"The compiler ${CMAKE_CXX_COMPILER} doesn't support required C++11 features. Please use a newer MSVC."
)
endif()
endif()
if(USE_SWIG)
find_package(SWIG REQUIRED)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)
include(UseSWIG)
set(SWIG_CXX_EXTENSION "cxx")
set(SWIG_EXTRA_LIBRARIES "")
set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")
set(SWIG_MODULE_JAVA_LANGUAGE "JAVA")
set(SWIG_MODULE_JAVA_SWIG_LANGUAGE_FLAG "java")
set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
include_directories(Java_INCLUDE_DIRS)
include_directories(JNI_INCLUDE_DIRS)
include_directories($ENV{JAVA_HOME}/include)
if(WIN32)
set(LGBM_SWIG_DESTINATION_DIR "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/windows/x86_64")
include_directories($ENV{JAVA_HOME}/include/win32)
elseif(APPLE)
set(LGBM_SWIG_DESTINATION_DIR "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/osx/x86_64")
include_directories($ENV{JAVA_HOME}/include/darwin)
else()
set(LGBM_SWIG_DESTINATION_DIR "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/linux/x86_64")
include_directories($ENV{JAVA_HOME}/include/linux)
endif()
file(MAKE_DIRECTORY "${LGBM_SWIG_DESTINATION_DIR}")
endif()
set(EIGEN_DIR "${PROJECT_SOURCE_DIR}/external_libs/eigen")
include_directories(${EIGEN_DIR})
# See https://gitlab.com/libeigen/eigen/-/blob/master/COPYING.README
add_definitions(-DEIGEN_MPL2_ONLY)
add_definitions(-DEIGEN_DONT_PARALLELIZE)
set(FAST_DOUBLE_PARSER_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/external_libs/fast_double_parser/include")
include_directories(${FAST_DOUBLE_PARSER_INCLUDE_DIR})
set(FMT_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/external_libs/fmt/include")
include_directories(${FMT_INCLUDE_DIR})
if(__BUILD_FOR_R)
find_package(LibR REQUIRED)
message(STATUS "LIBR_EXECUTABLE: ${LIBR_EXECUTABLE}")
message(STATUS "LIBR_INCLUDE_DIRS: ${LIBR_INCLUDE_DIRS}")
message(STATUS "LIBR_LIBS_DIR: ${LIBR_LIBS_DIR}")
message(STATUS "LIBR_CORE_LIBRARY: ${LIBR_CORE_LIBRARY}")
include_directories(${LIBR_INCLUDE_DIRS})
add_definitions(-DLGB_R_BUILD)
endif()
if(USE_TIMETAG)
add_definitions(-DTIMETAG)
endif()
if(USE_DEBUG)
add_definitions(-DDEBUG)
endif()
if(USE_MPI)
find_package(MPI REQUIRED)
add_definitions(-DUSE_MPI)
else()
add_definitions(-DUSE_SOCKET)
endif()
if(USE_CUDA)
set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}")
enable_language(CUDA)
set(USE_OPENMP ON CACHE BOOL "CUDA requires OpenMP" FORCE)
endif()
if(USE_OPENMP)
if(APPLE)
find_package(OpenMP)
if(NOT OpenMP_FOUND)
if(USE_HOMEBREW_FALLBACK)
# libomp 15.0+ from brew is keg-only, so have to search in other locations.
# See https://github.com/Homebrew/homebrew-core/issues/112107#issuecomment-1278042927.
execute_process(COMMAND brew --prefix libomp
OUTPUT_VARIABLE HOMEBREW_LIBOMP_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
set(OpenMP_C_LIB_NAMES omp)
set(OpenMP_CXX_LIB_NAMES omp)
set(OpenMP_omp_LIBRARY ${HOMEBREW_LIBOMP_PREFIX}/lib/libomp.dylib)
endif()
find_package(OpenMP REQUIRED)
endif()
else()
find_package(OpenMP REQUIRED)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
if(USE_GPU)
set(BOOST_COMPUTE_HEADER_DIR ${PROJECT_SOURCE_DIR}/external_libs/compute/include)
include_directories(${BOOST_COMPUTE_HEADER_DIR})
find_package(OpenCL REQUIRED)
include_directories(${OpenCL_INCLUDE_DIRS})
message(STATUS "OpenCL include directory: " ${OpenCL_INCLUDE_DIRS})
if(WIN32)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(Boost 1.56.0 COMPONENTS filesystem system REQUIRED)
if(WIN32)
# disable autolinking in boost
add_definitions(-DBOOST_ALL_NO_LIB)
endif()
include_directories(${Boost_INCLUDE_DIRS})
add_definitions(-DUSE_GPU)
endif()
if(__INTEGRATE_OPENCL)
if(APPLE)
message(FATAL_ERROR "Integrated OpenCL build is not available on macOS")
else()
include(cmake/IntegratedOpenCL.cmake)
add_definitions(-DUSE_GPU)
endif()
endif()
if(BUILD_CPP_TEST AND MSVC)
# Use /MT flag to statically link the C runtime
#set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
if(USE_CUDA)
find_package(CUDAToolkit 11.0 REQUIRED)
include_directories(${CUDAToolkit_INCLUDE_DIRS})
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS} -Xcompiler=-fPIC -Xcompiler=-Wall")
# reference for mapping of CUDA toolkit component versions to supported architectures ("compute capabilities"):
# https://en.wikipedia.org/wiki/CUDA#GPUs_supported
set(CUDA_ARCHS "60" "61" "62" "70" "75")
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL "11.0")
list(APPEND CUDA_ARCHS "80")
endif()
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL "11.1")
list(APPEND CUDA_ARCHS "86")
endif()
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL "11.5")
list(APPEND CUDA_ARCHS "87")
endif()
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL "11.8")
list(APPEND CUDA_ARCHS "89")
list(APPEND CUDA_ARCHS "90")
endif()
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL "12.8")
list(APPEND CUDA_ARCHS "100")
list(APPEND CUDA_ARCHS "120")
endif()
# Generate PTX for the most recent architecture for forwards compatibility
list(POP_BACK CUDA_ARCHS CUDA_LAST_SUPPORTED_ARCH)
list(TRANSFORM CUDA_ARCHS APPEND "-real")
list(APPEND CUDA_ARCHS "${CUDA_LAST_SUPPORTED_ARCH}-real" "${CUDA_LAST_SUPPORTED_ARCH}-virtual")
message(STATUS "CUDA_ARCHITECTURES: ${CUDA_ARCHS}")
if(USE_DEBUG)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -g")
else()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -O3 -lineinfo")
endif()
message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")
add_definitions(-DUSE_CUDA)
if(NOT DEFINED CMAKE_CUDA_STANDARD)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()
endif()
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <xmmintrin.h>
int main() {
int a = 0;
_mm_prefetch(&a, _MM_HINT_NTA);
return 0;
}
" MM_PREFETCH)
if(${MM_PREFETCH})
message(STATUS "Using _mm_prefetch")
add_definitions(-DMM_PREFETCH)
endif()
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <mm_malloc.h>
int main() {
char *a = (char*)_mm_malloc(8, 16);
_mm_free(a);
return 0;
}
" MM_MALLOC)
if(${MM_MALLOC})
message(STATUS "Using _mm_malloc")
add_definitions(-DMM_MALLOC)
endif()
if(UNIX OR MINGW OR CYGWIN)
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -pthread -Wextra -Wall -Wno-ignored-attributes -Wno-unknown-pragmas -Wno-return-type"
)
if(MINGW)
# ignore this warning: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95353
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wno-stringop-overflow"
)
endif()
if(USE_DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
if(USE_SWIG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
endif()
if(NOT USE_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas -Wno-unused-private-field")
endif()
if(__BUILD_FOR_R AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-cast-function-type")
endif()
endif()
if(WIN32 AND MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
endif()
# Check if inet_pton is already available, to avoid conflicts with the implementation in LightGBM.
# As of 2022, MinGW started including a definition of inet_pton.
if(WIN32)
include(CheckSymbolExists)
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
check_symbol_exists(inet_pton "ws2tcpip.h" WIN_INET_PTON_FOUND)
if(WIN_INET_PTON_FOUND)
add_definitions(-DWIN_HAS_INET_PTON)
endif()
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "ws2_32")
endif()
if(MSVC)
# compiling 'fmt' on MSVC: "Unicode support requires compiling with /utf-8"
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /MP /utf-8")
# 确保使用动态运行时库
if(BUILD_SHARED_LIBS)
if(USE_DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MDd")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MD")
endif()
endif()
if(__BUILD_FOR_R)
# MSVC does not like this commit:
# https://github.com/wch/r-source/commit/fb52ac1a610571fcb8ac92d886b9fefcffaa7d48
#
# and raises "error C3646: 'private_data_c': unknown override specifier"
add_definitions(-DR_LEGACY_RCOMPLEX)
endif()
if(USE_DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Od")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Ob2 /Oi /Ot /Oy")
endif()
else()
if(BUILD_SHARED_LIBS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if(NOT USE_DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funroll-loops")
endif()
endif()
set(LightGBM_HEADER_DIR ${PROJECT_SOURCE_DIR}/include)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
include_directories(${LightGBM_HEADER_DIR})
if(USE_MPI)
include_directories(${MPI_CXX_INCLUDE_PATH})
endif()
set(
LGBM_SOURCES
src/boosting/boosting.cpp
src/boosting/gbdt_model_text.cpp
src/boosting/gbdt_prediction.cpp
src/boosting/gbdt.cpp
src/boosting/prediction_early_stop.cpp
src/boosting/sample_strategy.cpp
src/io/bin.cpp
src/io/config_auto.cpp
src/io/config.cpp
src/io/dataset_loader.cpp
src/io/dataset.cpp
src/io/file_io.cpp
src/io/json11.cpp
src/io/metadata.cpp
src/io/parser.cpp
src/io/train_share_states.cpp
src/io/tree.cpp
src/metric/dcg_calculator.cpp
src/metric/metric.cpp
src/network/linker_topo.cpp
src/network/linkers_mpi.cpp
src/network/linkers_socket.cpp
src/network/network.cpp
src/objective/objective_function.cpp
src/treelearner/data_parallel_tree_learner.cpp
src/treelearner/feature_histogram.cpp
src/treelearner/feature_parallel_tree_learner.cpp
src/treelearner/gpu_tree_learner.cpp
src/treelearner/gradient_discretizer.cpp
src/treelearner/linear_tree_learner.cpp
src/treelearner/serial_tree_learner.cpp
src/treelearner/tree_learner.cpp
src/treelearner/voting_parallel_tree_learner.cpp
src/utils/openmp_wrapper.cpp
)
set(
LGBM_CUDA_SOURCES
src/boosting/cuda/cuda_score_updater.cpp
src/boosting/cuda/cuda_score_updater.cu
src/metric/cuda/cuda_binary_metric.cpp
src/metric/cuda/cuda_pointwise_metric.cpp
src/metric/cuda/cuda_regression_metric.cpp
src/metric/cuda/cuda_pointwise_metric.cu
src/objective/cuda/cuda_binary_objective.cpp
src/objective/cuda/cuda_multiclass_objective.cpp
src/objective/cuda/cuda_rank_objective.cpp
src/objective/cuda/cuda_regression_objective.cpp
src/objective/cuda/cuda_binary_objective.cu
src/objective/cuda/cuda_multiclass_objective.cu
src/objective/cuda/cuda_rank_objective.cu
src/objective/cuda/cuda_regression_objective.cu
src/treelearner/cuda/cuda_best_split_finder.cpp
src/treelearner/cuda/cuda_data_partition.cpp
src/treelearner/cuda/cuda_histogram_constructor.cpp
src/treelearner/cuda/cuda_leaf_splits.cpp
src/treelearner/cuda/cuda_single_gpu_tree_learner.cpp
src/treelearner/cuda/cuda_best_split_finder.cu
src/treelearner/cuda/cuda_data_partition.cu
src/treelearner/cuda/cuda_gradient_discretizer.cu
src/treelearner/cuda/cuda_histogram_constructor.cu
src/treelearner/cuda/cuda_leaf_splits.cu
src/treelearner/cuda/cuda_single_gpu_tree_learner.cu
src/io/cuda/cuda_column_data.cu
src/io/cuda/cuda_tree.cu
src/io/cuda/cuda_column_data.cpp
src/io/cuda/cuda_metadata.cpp
src/io/cuda/cuda_row_data.cpp
src/io/cuda/cuda_tree.cpp
src/cuda/cuda_utils.cpp
src/cuda/cuda_algorithms.cu
)
if(USE_CUDA)
list(APPEND LGBM_SOURCES ${LGBM_CUDA_SOURCES})
endif()
add_library(lightgbm_objs OBJECT ${LGBM_SOURCES})
if(BUILD_CLI)
add_executable(lightgbm src/main.cpp src/application/application.cpp)
target_link_libraries(lightgbm PRIVATE lightgbm_objs)
endif()
set(API_SOURCES "src/c_api.cpp")
# Only build the R part of the library if building for
# use with the R-package
if(__BUILD_FOR_R)
list(APPEND API_SOURCES "src/lightgbm_R.cpp")
endif()
add_library(lightgbm_capi_objs OBJECT ${API_SOURCES})
# 创建库
if(BUILD_SHARED_LIBS)
# 构建共享库
add_library(_lightgbm SHARED)
message(STATUS "构建动态链接库 (DLL)")
# Windows特定设置
if(WIN32)
# 确保生成导入库
set_target_properties(_lightgbm PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS ON
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
)
endif()
else()
# 构建静态库
add_library(_lightgbm STATIC)
message(STATUS "构建静态链接库 (LIB)")
endif()
# R expects libraries of the form <project>.{dll,dylib,so}, not lib_<project>.{dll,dylib,so}
if(__BUILD_FOR_R)
set_target_properties(
_lightgbm
PROPERTIES
PREFIX ""
OUTPUT_NAME "lightgbm"
)
endif()
# LightGBM headers include openmp, cuda, R etc. headers,
# thus PUBLIC is required for building _lightgbm_swig target.
target_link_libraries(_lightgbm PUBLIC lightgbm_capi_objs lightgbm_objs)
if(MSVC AND NOT __BUILD_FOR_R)
set_target_properties(_lightgbm PROPERTIES OUTPUT_NAME "lib_lightgbm")
endif()
if(USE_SWIG)
set_property(SOURCE swig/lightgbmlib.i PROPERTY CPLUSPLUS ON)
list(APPEND swig_options -package com.microsoft.ml.lightgbm)
set_property(SOURCE swig/lightgbmlib.i PROPERTY SWIG_FLAGS "${swig_options}")
swig_add_library(_lightgbm_swig LANGUAGE java SOURCES swig/lightgbmlib.i)
swig_link_libraries(_lightgbm_swig _lightgbm)
set_target_properties(
_lightgbm_swig
PROPERTIES
# needed to ensure Linux build does not have lib prefix specified twice, e.g. liblib_lightgbm_swig
PREFIX ""
# needed in some versions of CMake for VS and MinGW builds to ensure output dll has lib prefix
OUTPUT_NAME "lib_lightgbm_swig"
)
if(WIN32)
set(LGBM_SWIG_LIB_DESTINATION_PATH "${LGBM_SWIG_DESTINATION_DIR}/lib_lightgbm_swig.dll")
if(MINGW OR CYGWIN)
set(LGBM_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm.dll")
set(LGBM_SWIG_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm_swig.dll")
else()
set(LGBM_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/Release/lib_lightgbm.dll")
set(LGBM_SWIG_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/Release/lib_lightgbm_swig.dll")
endif()
elseif(APPLE)
set(LGBM_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm.dylib")
set(LGBM_SWIG_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm_swig.jnilib")
set(LGBM_SWIG_LIB_DESTINATION_PATH "${LGBM_SWIG_DESTINATION_DIR}/lib_lightgbm_swig.dylib")
else()
set(LGBM_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm.so")
set(LGBM_SWIG_LIB_SOURCE_PATH "${PROJECT_SOURCE_DIR}/lib_lightgbm_swig.so")
set(LGBM_SWIG_LIB_DESTINATION_PATH "${LGBM_SWIG_DESTINATION_DIR}/lib_lightgbm_swig.so")
endif()
add_custom_command(
TARGET _lightgbm_swig
POST_BUILD
COMMAND "${Java_JAVAC_EXECUTABLE}" -d . java/*.java
COMMAND
"${CMAKE_COMMAND}"
-E
copy_if_different
"${LGBM_LIB_SOURCE_PATH}"
"${LGBM_SWIG_DESTINATION_DIR}"
COMMAND
"${CMAKE_COMMAND}"
-E
copy_if_different
"${LGBM_SWIG_LIB_SOURCE_PATH}"
"${LGBM_SWIG_LIB_DESTINATION_PATH}"
COMMAND "${Java_JAR_EXECUTABLE}" -cf lightgbmlib.jar com
)
endif()
if(USE_MPI)
target_link_libraries(lightgbm_objs PUBLIC ${MPI_CXX_LIBRARIES})
endif()
if(USE_OPENMP)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_link_libraries(lightgbm_objs PUBLIC OpenMP::OpenMP_CXX)
# c_api headers also includes OpenMP headers, thus compiling
# lightgbm_capi_objs needs include directory for OpenMP.
# Specifying OpenMP in target_link_libraries will get include directory
# requirements for compilation.
# This uses CMake's Transitive Usage Requirements. Refer to CMake doc:
# https://cmake.org/cmake/help/v3.16/manual/cmake-buildsystem.7.html#transitive-usage-requirements
target_link_libraries(lightgbm_capi_objs PUBLIC OpenMP::OpenMP_CXX)
endif()
endif()
if(USE_GPU)
target_link_libraries(lightgbm_objs PUBLIC ${OpenCL_LIBRARY} ${Boost_LIBRARIES})
endif()
if(__INTEGRATE_OPENCL)
# targets OpenCL and Boost are added in IntegratedOpenCL.cmake
add_dependencies(lightgbm_objs OpenCL Boost)
# variables INTEGRATED_OPENCL_* are set in IntegratedOpenCL.cmake
target_include_directories(lightgbm_objs PRIVATE ${INTEGRATED_OPENCL_INCLUDES})
target_compile_definitions(lightgbm_objs PRIVATE ${INTEGRATED_OPENCL_DEFINITIONS})
target_link_libraries(lightgbm_objs PUBLIC ${INTEGRATED_OPENCL_LIBRARIES} ${CMAKE_DL_LIBS})
endif()
if(USE_CUDA)
set_target_properties(
lightgbm_objs
PROPERTIES
CUDA_ARCHITECTURES "${CUDA_ARCHS}"
CUDA_SEPARABLE_COMPILATION ON
)
set_target_properties(
_lightgbm
PROPERTIES
CUDA_ARCHITECTURES "${CUDA_ARCHS}"
CUDA_RESOLVE_DEVICE_SYMBOLS ON
)
if(BUILD_CLI)
set_target_properties(
lightgbm
PROPERTIES
CUDA_ARCHITECTURES "${CUDA_ARCHS}"
CUDA_RESOLVE_DEVICE_SYMBOLS ON
)
endif()
endif()
if(WIN32)
if(MINGW OR CYGWIN)
target_link_libraries(lightgbm_objs PUBLIC ws2_32 iphlpapi)
endif()
endif()
if(__BUILD_FOR_R)
# utils/log.h and capi uses R headers, thus both object libraries need to link
# with R lib.
if(MSVC)
set(R_LIB ${LIBR_MSVC_CORE_LIBRARY})
else()
set(R_LIB ${LIBR_CORE_LIBRARY})
endif()
target_link_libraries(lightgbm_objs PUBLIC ${R_LIB})
target_link_libraries(lightgbm_capi_objs PUBLIC ${R_LIB})
endif()
#-- Google C++ tests
if(BUILD_CPP_TEST)
find_package(GTest CONFIG)
if(NOT GTEST_FOUND)
message(STATUS "Did not find Google Test in the system root. Fetching Google Test now...")
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
add_library(GTest::GTest ALIAS gtest)
endif()
set(LightGBM_TEST_HEADER_DIR ${PROJECT_SOURCE_DIR}/tests/cpp_tests)
include_directories(${LightGBM_TEST_HEADER_DIR})
set(
CPP_TEST_SOURCES
tests/cpp_tests/test_array_args.cpp
tests/cpp_tests/test_arrow.cpp
tests/cpp_tests/test_byte_buffer.cpp
tests/cpp_tests/test_chunked_array.cpp
tests/cpp_tests/test_common.cpp
tests/cpp_tests/test_main.cpp
tests/cpp_tests/test_serialize.cpp
tests/cpp_tests/test_single_row.cpp
tests/cpp_tests/test_stream.cpp
tests/cpp_tests/testutils.cpp
)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-")
endif()
add_executable(testlightgbm ${CPP_TEST_SOURCES})
target_link_libraries(testlightgbm PRIVATE lightgbm_objs lightgbm_capi_objs GTest::GTest)
endif()
# 在 include_directories 设置之后添加:
# 关键修复:为Windows DLL创建符号导出定义
if(WIN32 AND BUILD_SHARED_LIBS)
# 创建导出头文件
file(WRITE "${CMAKE_BINARY_DIR}/lightgbm_export.h"
"#ifndef LIGHTGBM_EXPORT_H
#define LIGHTGBM_EXPORT_H
#ifdef _WIN32
#ifdef LIGHTGBM_EXPORTS
#define LIGHTGBM_API __declspec(dllexport)
#else
#define LIGHTGBM_API __declspec(dllimport)
#endif
#else
#define LIGHTGBM_API
#endif
#endif // LIGHTGBM_EXPORT_H
")
# 添加导出定义到所有源文件
add_definitions(-DLIGHTGBM_EXPORTS)
include_directories("${CMAKE_BINARY_DIR}")
endif()
# 设置输出目录
# 设置输出目录
set_target_properties(_lightgbm PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/lib/Release"
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/lib/Debug"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/lib/Release"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/lib/Debug"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/Release"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/Debug"
OUTPUT_NAME "lib_lightgbm"
)
if(BUILD_CLI)
install(
TARGETS lightgbm
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
)
endif()
if(__BUILD_FOR_PYTHON)
set(CMAKE_INSTALL_PREFIX "lightgbm")
endif()
# The macOS linker puts an absolute path to linked libraries in lib_lightgbm.dylib.
# This block overrides that information for LightGBM's OpenMP dependency, to allow
# finding that library in more places.
#
# This reduces the risk of runtime issues resulting from multiple {libgomp,libiomp,libomp}.dylib being loaded.
#
if(APPLE AND USE_OPENMP AND BUILD_SHARED_LIBS)
# store path to {libgomp,libiomp,libomp}.dylib found at build time in a variable
get_target_property(
OpenMP_LIBRARY_LOCATION
OpenMP::OpenMP_CXX
INTERFACE_LINK_LIBRARIES
)
# get just the filename of that path
# (to deal with the possibility that it might be 'libomp.dylib' or 'libgomp.dylib' or 'libiomp.dylib')
get_filename_component(
OpenMP_LIBRARY_NAME
${OpenMP_LIBRARY_LOCATION}
NAME
)
# get directory of that path
get_filename_component(
OpenMP_LIBRARY_DIR
${OpenMP_LIBRARY_LOCATION}
DIRECTORY
)
# get exact name of the library in a variable
get_target_property(
__LIB_LIGHTGBM_OUTPUT_NAME
_lightgbm
OUTPUT_NAME
)
if(NOT __LIB_LIGHTGBM_OUTPUT_NAME)
set(__LIB_LIGHTGBM_OUTPUT_NAME "lib_lightgbm")
endif()
if(CMAKE_SHARED_LIBRARY_SUFFIX_CXX)
set(
__LIB_LIGHTGBM_FILENAME "${__LIB_LIGHTGBM_OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX_CXX}"
CACHE INTERNAL "lightgbm shared library filename"
)
else()
set(
__LIB_LIGHTGBM_FILENAME "${__LIB_LIGHTGBM_OUTPUT_NAME}.dylib"
CACHE INTERNAL "lightgbm shared library filename"
)
endif()
# Override the absolute path to OpenMP with a relative one using @rpath.
#
# This also ensures that if a {libgomp,libiomp,libomp}.dylib has already been loaded, it'll just use that.
add_custom_command(
TARGET _lightgbm
POST_BUILD
COMMAND
install_name_tool
-change
${OpenMP_LIBRARY_LOCATION}
"@rpath/${OpenMP_LIBRARY_NAME}"
"${__LIB_LIGHTGBM_FILENAME}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Replacing hard-coded OpenMP install_name with '@rpath/${OpenMP_LIBRARY_NAME}'..."
)
# add RPATH entries to ensure the loader looks in the following, in the following order:
#
# - (R-only) ${LIBR_LIBS_DIR} (wherever R for macOS stores vendored third-party libraries)
# - ${OpenMP_LIBRARY_DIR} (wherever find_package(OpenMP) found OpenMP at build time)
# - /opt/homebrew/opt/libomp/lib (where 'brew install' / 'brew link' puts libomp.dylib)
# - /opt/local/lib/libomp (where 'port install' puts libomp.dylib)
#
# with some compilers, OpenMP ships with the compiler (e.g. libgomp with gcc)
list(APPEND __omp_install_rpaths "${OpenMP_LIBRARY_DIR}")
# with clang, libomp doesn't ship with the compiler and might be supplied separately
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(
APPEND __omp_install_rpaths
"/opt/homebrew/opt/libomp/lib"
"/opt/local/lib/libomp"
)
# It appears that CRAN's macOS binaries compiled with -fopenmp have install names
# of the form:
#
# /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libomp.dylib
#
# That corresponds to the libomp.dylib that ships with the R framework for macOS, available
# from https://cran.r-project.org/bin/macosx/.
#
# That absolute-path install name leads to that library being loaded unconditionally.
#
# That can result in e.g. 'library(data.table)' loading R's libomp.dylib and 'library(lightgbm)' loading
# Homebrew's. Having 2 loaded in the same process can lead to segfaults and unpredictable behavior.
#
# This can't be easily avoided by forcing R-package builds in LightGBM to use R's libomp.dylib
# at build time... LightGBM's CMake uses find_package(OpenMP), and R for macOS only provides the
# library, not CMake config files for it.
#
# Best we can do, to allow CMake-based builds of the R-package here to continue to work
# alongside CRAN-prepared binaries of other packages with OpenMP dependencies, is to
# ensure that R's library directory is the first place the loader searches for
# libomp.dylib when clang is used.
#
# ref: https://github.com/microsoft/LightGBM/issues/6628
#
if(__BUILD_FOR_R)
list(PREPEND __omp_install_rpaths "${LIBR_LIBS_DIR}")
endif()
endif()
set_target_properties(
_lightgbm
PROPERTIES
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_RPATH "${__omp_install_rpaths}"
INSTALL_RPATH_USE_LINK_PATH FALSE
)
endif()
install(
TARGETS _lightgbm
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)
if(INSTALL_HEADERS)
install(
DIRECTORY ${LightGBM_HEADER_DIR}/LightGBM
DESTINATION ${CMAKE_INSTALL_PREFIX}/include
)
install(
FILES ${FAST_DOUBLE_PARSER_INCLUDE_DIR}/fast_double_parser.h
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/LightGBM/utils
)
install(
DIRECTORY ${FMT_INCLUDE_DIR}/
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/LightGBM/utils
FILES_MATCHING PATTERN "*.h"
)
# 如果是Windows DLL,也安装导出头文件
if(WIN32 AND BUILD_SHARED_LIBS)
install(FILES "${CMAKE_BINARY_DIR}/lightgbm_export.h"
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/LightGBM
)
endif()
endif()
然后下载下面两个文件(eigen要先配置好)
fast_double_parser: 从https://github.com/lemire/fast_double_parser 下载,将include中的头文件放到external_libs/fast_double_parser/include下。
fmt: 从https://github.com/fmtlib/fmt 下载,将include中的头文件放到external_libs/fmt/include下。
接下来使用命令行进行动态运行时库编译:
打开VS2022开发者命令提示符 Developer Command Prompt for VS
确保MSVC工具链在PATH中
先定位到上面那个解压后的目录下面(使用cd +绝对路径)
然后依次操作下面命令
mkdir build
cd build
# 配置
cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install ..
# 编译
cmake --build . --config Release --parallel
# 安装
cmake --build . --config Release --target INSTALL
编译好在G:/ 目录看到3个文件夹bin、include、lib。当然你可以建一个文件夹用了存放他们(我们要的就是这个3个文件夹里的文件)。
接下来就可以在clion里进行代码测试了。
CMakeLists设置如下:
set(LightGBM_INCLUDE_DIR "G:/include")
set(LightGBM_LIB_DIR "G:/lib")
# 包含头文件
include_directories(${LightGBM_INCLUDE_DIR})
# 添加可执行文件
add_executable(LightGBMtest ../LightGBM/test.cpp)
target_link_libraries(LightGBMtest "${LightGBM_LIB_DIR}/lib_lightgbm.lib" )
if(WIN32)
# 将 DLL 复制到输出目录
add_custom_command(TARGET LightGBMtest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"G:/bin/lib_lightgbm.dll"
$<TARGET_FILE_DIR:LightGBMtest>
)
endif()
测试代码:
#include <iostream>
#include <vector>
#include <random>
#include <LightGBM/c_api.h>
int main() {
std::cout << "LightGBM C++ API Test Started..." << std::endl;
// 设置随机数生成器
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
// 1. 创建训练数据
const int num_train = 1000;
const int num_features = 10;
std::vector<float> train_data(num_train * num_features);
std::vector<float> train_labels(num_train);
// 生成随机训练数据
for (int i = 0; i < num_train; ++i) {
for (int j = 0; j < num_features; ++j) {
train_data[i * num_features + j] = dist(gen);
}
// 简单的二分类问题:如果第一个特征 > 0.5,则标签为1,否则为0
train_labels[i] = (train_data[i * num_features] > 0.5f) ? 1.0f : 0.0f;
}
// 2. 创建测试数据
const int num_test = 100;
std::vector<float> test_data(num_test * num_features);
std::vector<float> test_labels(num_test);
for (int i = 0; i < num_test; ++i) {
for (int j = 0; j < num_features; ++j) {
test_data[i * num_features + j] = dist(gen);
}
test_labels[i] = (test_data[i * num_features] > 0.5f) ? 1.0f : 0.0f;
}
// 3. 创建数据集
DatasetHandle train_dataset = nullptr;
const char* parameters = "max_bin=255";
int result = LGBM_DatasetCreateFromMat(
train_data.data(),
C_API_DTYPE_FLOAT32,
num_train,
num_features,
1, // row major
parameters,
nullptr, // no reference
&train_dataset
);
if (result != 0) {
std::cerr << "Failed to create training dataset: " << LGBM_GetLastError() << std::endl;
return -1;
}
// 4. 设置标签
result = LGBM_DatasetSetField(
train_dataset,
"label",
train_labels.data(),
num_train,
C_API_DTYPE_FLOAT32
);
if (result != 0) {
std::cerr << "Failed to set labels: " << LGBM_GetLastError() << std::endl;
LGBM_DatasetFree(train_dataset);
return -1;
}
// 5. 创建Booster
BoosterHandle booster = nullptr;
const char* booster_params =
"objective=binary "
"metric=auc "
"num_leaves=31 "
"learning_rate=0.1 "
"feature_fraction=0.8 "
"bagging_fraction=0.8 "
"bagging_freq=5 "
"verbose=0";
result = LGBM_BoosterCreate(train_dataset, booster_params, &booster);
if (result != 0) {
std::cerr << "Failed to create booster: " << LGBM_GetLastError() << std::endl;
LGBM_DatasetFree(train_dataset);
return -1;
}
std::cout << "Training started..." << std::endl;
// 6. 训练模型
const int num_rounds = 100;
for (int i = 0; i < num_rounds; ++i) {
int is_finished = 0;
result = LGBM_BoosterUpdateOneIter(booster, &is_finished);
if (result != 0) {
std::cerr << "Failed to update iteration " << i << ": " << LGBM_GetLastError() << std::endl;
break;
}
// 每10轮打印一次训练损失
if (i % 10 == 0) {
int eval_count = 0;
LGBM_BoosterGetEvalCounts(booster, &eval_count);
if (eval_count > 0) {
std::vector<double> eval_results(eval_count);
LGBM_BoosterGetEval(booster, 0, &eval_count, eval_results.data());
std::cout << "Iteration " << i << ", Train AUC: " << eval_results[0] << std::endl;
}
}
if (is_finished) {
std::cout << "Early stopping at iteration " << i << std::endl;
break;
}
}
std::cout << "Training completed!" << std::endl;
// 7. 保存模型
result = LGBM_BoosterSaveModel(
booster,
0, // start_iteration
0, // num_iteration (0 means all)
C_API_FEATURE_IMPORTANCE_GAIN,
"lightgbm_model.txt"
);
if (result != 0) {
std::cerr << "Failed to save model: " << LGBM_GetLastError() << std::endl;
} else {
std::cout << "Model saved to lightgbm_model.txt" << std::endl;
}
// 8. 进行预测
std::vector<double> predictions(num_test);
int64_t out_len = 0;
result = LGBM_BoosterPredictForMat(
booster,
test_data.data(),
C_API_DTYPE_FLOAT32,
num_test,
num_features,
1, // row major
C_API_PREDICT_NORMAL,
0, // start_iteration
0, // num_iteration (0 means all)
"",
&out_len,
predictions.data()
);
if (result != 0) {
std::cerr << "Failed to make predictions: " << LGBM_GetLastError() << std::endl;
} else {
std::cout << "Predictions completed!" << std::endl;
// 计算准确率
int correct = 0;
for (int i = 0; i < num_test; ++i) {
int predicted = (predictions[i] > 0.5) ? 1 : 0;
if (predicted == static_cast<int>(test_labels[i])) {
correct++;
}
}
double accuracy = static_cast<double>(correct) / num_test;
std::cout << "Test Accuracy: " << accuracy * 100 << "%" << std::endl;
}
// 9. 获取特征重要性
int num_features_booster = 0;
LGBM_BoosterGetNumFeature(booster, &num_features_booster);
std::vector<double> feature_importance(num_features_booster);
result = LGBM_BoosterFeatureImportance(
booster,
0, // num_iteration (0 means all)
C_API_FEATURE_IMPORTANCE_GAIN,
feature_importance.data()
);
if (result == 0) {
std::cout << "Feature Importance (Gain):" << std::endl;
for (int i = 0; i < num_features_booster; ++i) {
std::cout << "Feature " << i << ": " << feature_importance[i] << std::endl;
}
}
// 10. 清理资源
LGBM_BoosterFree(booster);
LGBM_DatasetFree(train_dataset);
std::cout << "LightGBM C++ API Test Completed Successfully!" << std::endl;
return 0;
}
运行结果如下:
LightGBM C++ API Test Started...
Training started...
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 0, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 10, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 20, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 30, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 40, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 50, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 60, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 70, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 80, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Iteration 90, Train AUC: 1
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Training completed!
Model saved to lightgbm_model.txt
Predictions completed!
Test Accuracy: 99%
Feature Importance (Gain):
Feature 0: 5664.57
Feature 1: 20.7003
Feature 2: 21.0868
Feature 3: 27.7902
Feature 4: 22.9087
Feature 5: 15.1964
Feature 6: 24.2659
Feature 7: 24.8022
Feature 8: 23.8073
Feature 9: 10.4155
LightGBM C++ API Test Completed Successfully!
Process finished with exit code 0
更多推荐
所有评论(0)