配置条件: 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_BUILD
            COMMAND ${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.2

2. Armadillo 矩阵测试:
矩阵 A:
   0.7868   0.9467   0.2513
   0.2505   0.0193   0.0227
   0.7107   0.4049   0.5206

矩阵 B:
   0.3447   0.1400   0.8571
   0.2742   0.5439   0.4998
   0.5610   0.5219   0.4194

矩阵 C = A * B:
   0.6718   0.7562   1.2529
   0.1044   0.0574   0.2338
   0.6481   0.5915   1.0298


3. 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
标签向量大小: 1x10

2. 数据操作测试:
数据保存成功
数据加载成功,大小: 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;

        // 计算RMSE
        if (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.0000
   1.0000   2.0000   3.0000   4.0000   5.0000
   2.0000   3.0000   5.0000   1.0000   5.0000


2. 数据分割完成
训练集大小: 3x16
测试集大小: 3x4

3. 训练协同过滤模型...
模型训练成功

4. 预测完成
预测值示例:    2.6290   3.1484   0.8088   4.2313

实际值示例:    3.0000   2.0000   2.0000   1.0000

RMSE: 1.82458

5. 生成推荐...
为用户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, 样本数=100
    mat 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;   // 类别数

    // 创建并训练SVM
    LinearSVM<> 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
标签数量: 100

2. 分割数据集...
训练集: 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_HPP
        arma::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;
#else
        return false;
#endif
    } catch (const std::exception& e) {
        cout << "K-means错误: " << e.what() << endl;
        return false;
    } catch (...) {
        return false;
    }
}

运行结果

=== MLPACK 模块可用性综合测试 ===
MLPACK 版本: 4.6.2

1. 测试核心功能...
? 核心功能测试通过

2. 测试数据IO功能...
? 数据IO功能测试通过

3. 测试K-means功能...
? K-means功能测试失败

=== 测试完成 ===

Process finished with exit code 0

更多推荐