win11系统下配置c++机器学习库mlpack
配置条件: win11,clion c++,msvc 工具链, mlpack
mlpack下载地址 https://www.mlpack.org/
mlpack的依赖库 
ensmallen下载地址 https://ensmallen.org/
cereal下载地址 https://github.com/USCiLab/cereal/releases/tag/v1.3.2
Armadillo 见我之前写的文章https://blog.csdn.net/hyl20012/article/details/147638951?spm=1001.2014.3001.5502
cmakelists.txt设置如下
cmake_minimum_required(VERSION 4.0)
project(mlpacktest)set(CMAKE_CXX_STANDARD 20)# 设置各依赖库的路径
set(MLPACK_ROOT "H:/software/mlpack462/Sources")
set(ARMADILLO_ROOT "H:/software/armadillo14_4_2")
set(ENSMALLEN_ROOT "H:/software/ensmallen3100")
set(CEREAL_ROOT "H:/software/cereal132")# 包含所有头文件路径
include_directories(${MLPACK_ROOT}/include${ARMADILLO_ROOT}/include${ENSMALLEN_ROOT}/include${CEREAL_ROOT}/include
)# 链接库文件路径
link_directories(${MLPACK_ROOT}/lib${ARMADILLO_ROOT}/examples/lib_win64
)# 查找所有mlpack库文件
file(GLOB MLPACK_LIBRARIES"${MLPACK_ROOT}/lib/mlpack_*.lib""${MLPACK_ROOT}/lib/mipack_*.lib"
)# 添加可执行文件
add_executable(test main.cpp)# MSVC编译器特定设置
if(MSVC)target_compile_options(test PRIVATE/EHsc/wd4005 # 宏重定义/wd4804 # 不安全布尔操作/wd4819 # 字符编码问题)
endif()# 链接所有找到的mlpack库
target_link_libraries(test${MLPACK_LIBRARIES}libopenblas.dll
)# MSVC编译器特定设置
if(MSVC)target_compile_options(test PRIVATE /EHsc)
endif()# 复制所有必要的DLL文件 - 从MLPACK_ROOT目录复制
set(REQUIRED_DLLS"libopenblas.dll""libgcc_s_seh-1.dll""libgfortran-3.dll"
)foreach(DLL ${REQUIRED_DLLS})add_custom_command(TARGET test POST_BUILDCOMMAND ${CMAKE_COMMAND} -E copy_if_different"${MLPACK_ROOT}/${DLL}"$<TARGET_FILE_DIR:test>COMMENT "Copying ${DLL} to output directory")
endforeach()
测试代码1:基础测试 - 验证头文件和基础功能
//基础测试 - 验证头文件和基础功能
#include <iostream>
#include <mlpack/core.hpp>
#include <armadillo>using namespace std;
using namespace arma;
using namespace mlpack;int main()
{cout << "=== MLPACK 基础配置测试 ===" << endl;// 测试 1: 版本信息cout << "1. 版本信息测试:" << endl;cout << "MLPACK 版本: " << MLPACK_VERSION_MAJOR << "."<< MLPACK_VERSION_MINOR << "." << MLPACK_VERSION_PATCH << endl;// 测试 2: Armadillo 矩阵操作cout << "\n2. Armadillo 矩阵测试:" << endl;mat A = randu<mat>(3, 3);mat B = randu<mat>(3, 3);mat C = A * B;cout << "矩阵 A:\n" << A << endl;cout << "矩阵 B:\n" << B << endl;cout << "矩阵 C = A * B:\n" << C << endl;// 测试 3: 简单的 mlpack 功能cout << "\n3. MLPACK 核心功能测试:" << endl;vec v = randu<vec>(5);cout << "随机向量: " << v.t() << endl;cout << "向量均值: " << mean(v) << endl;cout << "\n? 基础配置测试通过!" << endl;return 0;
}
运行结果
=== MLPACK 基础配置测试 ===
1. 版本信息测试:
MLPACK 版本: 4.6.22. Armadillo 矩阵测试:
矩阵 A:0.7868 0.9467 0.25130.2505 0.0193 0.02270.7107 0.4049 0.5206矩阵 B:0.3447 0.1400 0.85710.2742 0.5439 0.49980.5610 0.5219 0.4194矩阵 C = A * B:0.6718 0.7562 1.25290.1044 0.0574 0.23380.6481 0.5915 1.02983. MLPACK 核心功能测试:
随机向量: 0.7443 0.2492 0.2393 0.3201 0.9105向量均值: 0.492658? 基础配置测试通过!Process finished with exit code 0
测试代码2:中级测试 - 包含数据加载和简单算法
// 中级测试 - 包含数据加载和简单算法
#include <iostream>
#include <mlpack/core.hpp>
#include <mlpack/core/data/load.hpp>
#include <mlpack/core/data/save.hpp>
#include <armadillo>using namespace std;
using namespace arma;
using namespace mlpack;
using namespace mlpack::data;int main()
{cout << "=== MLPACK 中级功能测试 ===" << endl;// 创建一些测试数据mat data = randu<mat>(5, 10); // 5个特征,10个样本rowvec labels = randu<rowvec>(10); // 10个标签cout << "1. 数据创建测试:" << endl;cout << "数据矩阵大小: " << size(data) << endl;cout << "标签向量大小: " << size(labels) << endl;// 测试数据保存和加载(如果需要文件操作)cout << "\n2. 数据操作测试:" << endl;try {// 保存数据到临时文件Save("test_data.csv", data, true);cout << "数据保存成功" << endl;// 加载数据mat loadedData;Load("test_data.csv", loadedData, true);cout << "数据加载成功,大小: " << size(loadedData) << endl;// 验证数据一致性if (approx_equal(data, loadedData, "absdiff", 1e-5)) {cout << "数据一致性验证通过" << endl;} else {cout << "警告: 加载的数据与原始数据有差异" << endl;}} catch (const exception& e) {cout << "文件操作测试跳过: " << e.what() << endl;}// 测试 3: 基础统计cout << "\n3. 统计功能测试:" << endl;cout << "数据均值: " << mean(mean(data)) << endl;cout << "数据标准差: " << stddev(vectorise(data)) << endl;cout << "\n? 中级功能测试通过!" << endl;return 0;
}
运行结果
=== MLPACK 中级功能测试 ===
1. 数据创建测试:
数据矩阵大小: 5x10
标签向量大小: 1x102. 数据操作测试:
数据保存成功
数据加载成功,大小: 5x10
数据一致性验证通过3. 统计功能测试:
数据均值: 0.458978
数据标准差: 0.286455? 中级功能测试通过!Process finished with exit code 0
测试代码3:协同过滤测试代码
//3 协同过滤测试代码
#include <iostream>
#include <mlpack/core.hpp>
#include <mlpack/methods/cf/cf.hpp>
#include <armadillo>using namespace std;
using namespace arma;
using namespace mlpack;
// 移除 using namespace mlpack::cf; 因为可能不存在int main()
{cout << "=== MLPACK 协同过滤测试 ===" << endl;// 创建模拟评分数据// 格式: [用户ID, 物品ID, 评分]mat ratings(3, 20); // 3行: 用户,物品,评分; 20列: 20个评分// 填充模拟数据for (size_t i = 0; i < 20; ++i) {ratings(0, i) = floor(i / 5) + 1; // 用户ID: 1,1,1,1,1,2,2,2,2,2,...ratings(1, i) = (i % 5) + 1; // 物品ID: 1,2,3,4,5,1,2,3,4,5,...ratings(2, i) = rand() % 5 + 1; // 评分: 1-5的随机数}cout << "1. 模拟评分数据创建成功" << endl;cout << "数据大小: " << size(ratings) << endl;cout << "前5个评分:\n" << ratings.submat(0, 0, 2, 4) << endl;// 分割训练集和测试集mat trainRatings, testRatings;data::Split(ratings, trainRatings, testRatings, 0.2); // 20% 作为测试集cout << "\n2. 数据分割完成" << endl;cout << "训练集大小: " << size(trainRatings) << endl;cout << "测试集大小: " << size(testRatings) << endl;try {// 创建协同过滤模型 - 不使用命名空间限定cout << "\n3. 训练协同过滤模型..." << endl;CFType<RegSVDPolicy> cfModel(trainRatings,RegSVDPolicy(),3, // 相似用户数2 // 分解秩);cout << "模型训练成功" << endl;// 准备测试组合Mat<size_t> combinations(2, testRatings.n_cols);for (size_t i = 0; i < testRatings.n_cols; ++i) {combinations(0, i) = size_t(testRatings(0, i)); // 用户combinations(1, i) = size_t(testRatings(1, i)); // 物品}// 预测评分vec predictions;cfModel.Predict(combinations, predictions);cout << "\n4. 预测完成" << endl;cout << "预测值示例: " << predictions.subvec(0, min((size_t)3, predictions.n_elem-1)).t() << endl;cout << "实际值示例: " << testRatings.row(2).subvec(0, min((size_t)3, testRatings.n_cols-1)) << endl;// 计算RMSEif (testRatings.n_cols > 0) {double rmse = norm(predictions - testRatings.row(2).t(), 2) /sqrt((double)testRatings.n_cols);cout << "RMSE: " << rmse << endl;}// 获取推荐cout << "\n5. 生成推荐..." << endl;Col<size_t> users = {1}; // 为用户1生成推荐Mat<size_t> recommendations;cfModel.GetRecommendations(3, recommendations, users); // 推荐3个物品cout << "为用户1推荐的物品ID: ";for (size_t i = 0; i < recommendations.n_elem; ++i) {cout << recommendations[i] << " ";}cout << endl;} catch (const exception& e) {cout << "? 协同过滤测试失败: " << e.what() << endl;return -1;}cout << "\n? 协同过滤测试通过!" << endl;return 0;
}
运行结果
=== MLPACK 协同过滤测试 ===
1. 模拟评分数据创建成功
数据大小: 3x20
前5个评分:1.0000 1.0000 1.0000 1.0000 1.00001.0000 2.0000 3.0000 4.0000 5.00002.0000 3.0000 5.0000 1.0000 5.00002. 数据分割完成
训练集大小: 3x16
测试集大小: 3x43. 训练协同过滤模型...
模型训练成功4. 预测完成
预测值示例: 2.6290 3.1484 0.8088 4.2313实际值示例: 3.0000 2.0000 2.0000 1.0000RMSE: 1.824585. 生成推荐...
为用户1推荐的物品ID: 4 1 0 ? 协同过滤测试通过!Process finished with exit code 0
测试代码4:SVM 支持向量机测试代码
//SVM 支持向量机测试代码
#include <mlpack/core.hpp>
#include <mlpack/methods/linear_svm/linear_svm.hpp>
#include <iostream>using namespace mlpack;
using namespace arma;
using namespace std;int main()
{cout << "=== MLPack Linear SVM 简单测试 ===" << endl;// 设置随机种子arma::arma_rng::set_seed(12345);// 1. 创建简单的二分类数据cout << "\n1. 生成测试数据..." << endl;// 特征数=2, 样本数=100mat data(2, 100);Row<size_t> labels(100);// 类别0: 中心在(1,1)for (size_t i = 0; i < 50; ++i){data(0, i) = 1.0 + 0.3 * randn();data(1, i) = 1.0 + 0.3 * randn();labels(i) = 0;}// 类别1: 中心在(4,4)for (size_t i = 50; i < 100; ++i){data(0, i) = 4.0 + 0.3 * randn();data(1, i) = 4.0 + 0.3 * randn();labels(i) = 1;}cout << "数据维度: " << data.n_rows << " x " << data.n_cols << endl;cout << "标签数量: " << labels.n_elem << endl;// 2. 分割训练集和测试集cout << "\n2. 分割数据集..." << endl;mat trainData, testData;Row<size_t> trainLabels, testLabels;data::Split(data, labels, trainData, testData, trainLabels, testLabels, 0.2);cout << "训练集: " << trainData.n_cols << " 个样本" << endl;cout << "测试集: " << testData.n_cols << " 个样本" << endl;// 3. 训练线性SVM模型cout << "\n3. 训练线性SVM模型..." << endl;double lambda = 0.0001; // 正则化参数size_t numClasses = 2; // 类别数// 创建并训练SVMLinearSVM<> svm(trainData, trainLabels, numClasses, lambda);cout << "模型训练完成!" << endl;// 4. 在测试集上预测cout << "\n4. 测试模型性能..." << endl;Row<size_t> predictions;svm.Classify(testData, predictions);// 5. 计算准确率size_t correct = 0;for (size_t i = 0; i < testLabels.n_elem; ++i){if (predictions(i) == testLabels(i))correct++;}double accuracy = (double)correct / testLabels.n_elem * 100.0;cout << "测试准确率: " << accuracy << "% (" << correct << "/" << testLabels.n_elem << ")" << endl;// 6. 显示模型参数信息cout << "\n5. 模型参数信息..." << endl;cout << "权重矩阵维度: " << svm.Parameters().n_rows << " x " << svm.Parameters().n_cols << endl;// 7. 保存模型(可选)// data::Save("linear_svm_model.xml", "linear_svm", svm, false);// cout << "模型已保存到 linear_svm_model.xml" << endl;cout << "\n=== 测试完成 ===" << endl;return 0;
}
运行结果
=== MLPack Linear SVM 简单测试 ===1. 生成测试数据...
数据维度: 2 x 100
标签数量: 1002. 分割数据集...
训练集: 80 个样本
测试集: 20 个样本3. 训练线性SVM模型...
模型训练完成!4. 测试模型性能...
测试准确率: 45% (9/20)5. 模型参数信息...
权重矩阵维度: 2 x 2=== 测试完成 ===Process finished with exit code 0
测试代码:MLPACK 模块可用性测试。为了全面了解您的 mlpack 版本中哪些模块可用,请运行这个综合测试:
//MLPACK 模块可用性测试
//为了全面了解您的 mlpack 版本中哪些模块可用,请运行这个综合测试:
#include <iostream>
#include <mlpack/core.hpp>
#include <armadillo>using namespace std;// 测试函数声明
bool testCore();
bool testDataIO();
bool testCF();
bool testKMeans();
bool testLinearRegression();int main()
{cout << "=== MLPACK 模块可用性综合测试 ===" << endl;cout << "MLPACK 版本: " << MLPACK_VERSION_MAJOR << "."<< MLPACK_VERSION_MINOR << "." << MLPACK_VERSION_PATCH << endl;cout << "\n1. 测试核心功能..." << endl;if (testCore()) {cout << "? 核心功能测试通过" << endl;} else {cout << "? 核心功能测试失败" << endl;}cout << "\n2. 测试数据IO功能..." << endl;if (testDataIO()) {cout << "? 数据IO功能测试通过" << endl;} else {cout << "? 数据IO功能测试失败" << endl;}cout << "\n3. 测试K-means功能..." << endl;if (testKMeans()) {cout << "? K-means功能测试通过" << endl;} else {cout << "? K-means功能测试失败" << endl;}cout << "\n=== 测试完成 ===" << endl;return 0;
}bool testCore()
{try {arma::mat A = arma::randu<arma::mat>(2, 2);arma::mat B = arma::randu<arma::mat>(2, 2);arma::mat C = A * B;return true;} catch (...) {return false;}
}bool testDataIO()
{try {arma::mat data = arma::randu<arma::mat>(3, 5);// 测试数据分割功能arma::mat train, test;mlpack::data::Split(data, train, test, 0.3);return true;} catch (...) {return false;}
}bool testKMeans()
{try {
#ifdef MLPACK_METHODS_KMEANS_KMEANS_HPParma::mat data = arma::randu<arma::mat>(2, 10);arma::mat centroids;arma::Row<size_t> assignments;// 尝试不同的命名空间组合mlpack::kmeans::KMeans<> kmeans;kmeans.Cluster(data, 2, assignments, centroids);return true;
#elsereturn false;
#endif} catch (const std::exception& e) {cout << "K-means错误: " << e.what() << endl;return false;} catch (...) {return false;}
}
运行结果
=== MLPACK 模块可用性综合测试 ===
MLPACK 版本: 4.6.21. 测试核心功能...
? 核心功能测试通过2. 测试数据IO功能...
? 数据IO功能测试通过3. 测试K-means功能...
? K-means功能测试失败=== 测试完成 ===Process finished with exit code 0
