You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求无依赖第三方库的C++机器学习实现方法及简单示例

手动用C++实现机器学习:线性回归示例

核心流程拆解

不管什么机器学习模型,通用流程都逃不过这几步:

  • 数据预处理:对原始数据做归一化/标准化,消除量纲影响
  • 模型定义:用数学表达式描述模型(比如线性回归的y = wx + b)
  • 损失函数:衡量预测值和真实值的差异
  • 优化算法:通过迭代调整模型参数,最小化损失
  • 训练与评估:用训练数据更新参数,用测试数据验证效果

C++完整实现代码

下面是一个预测房屋价格的简化场景(假设房屋面积x对应价格y),全程仅依赖C++标准库:

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

// 数据归一化:把数值缩放到[0,1]区间
void normalize(std::vector<double>& data) {
    double min_val = *std::min_element(data.begin(), data.end());
    double max_val = *std::max_element(data.begin(), data.end());
    for (auto& val : data) {
        val = (val - min_val) / (max_val - min_val);
    }
}

// 线性回归预测:y = w*x + b
double predict(double x, double w, double b) {
    return w * x + b;
}

// 计算均方误差(MSE)损失
double calculate_loss(const std::vector<double>& x, const std::vector<double>& y, double w, double b) {
    double total_loss = 0.0;
    for (size_t i = 0; i < x.size(); ++i) {
        double pred = predict(x[i], w, b);
        total_loss += std::pow(pred - y[i], 2);
    }
    return total_loss / x.size();
}

// 计算梯度:损失对w和b的偏导数
void calculate_gradient(const std::vector<double>& x, const std::vector<double>& y, double w, double b, double& dw, double& db) {
    dw = 0.0;
    db = 0.0;
    for (size_t i = 0; i < x.size(); ++i) {
        double pred = predict(x[i], w, b);
        dw += (pred - y[i]) * x[i];
        db += (pred - y[i]);
    }
    dw /= x.size();
    db /= x.size();
}

// 训练模型:批量梯度下降
void train_model(const std::vector<double>& x, const std::vector<double>& y, double& w, double& b, double learning_rate, int epochs) {
    for (int epoch = 0; epoch < epochs; ++epoch) {
        double dw, db;
        calculate_gradient(x, y, w, b, dw, db);
        // 更新参数
        w -= learning_rate * dw;
        b -= learning_rate * db;
        // 每100轮打印一次损失
        if (epoch % 100 == 0) {
            double loss = calculate_loss(x, y, w, b);
            std::cout << "Epoch " << epoch << ", Loss: " << loss << std::endl;
        }
    }
}

int main() {
    // 模拟训练数据:房屋面积(平方米) -> 价格(万元)
    std::vector<double> x_train = {50, 60, 70, 80, 90, 100};
    std::vector<double> y_train = {15, 18, 21, 24, 27, 30};

    // 数据归一化
    normalize(x_train);
    normalize(y_train);

    // 初始化模型参数:w和b初始为0
    double w = 0.0;
    double b = 0.0;

    // 训练参数
    double learning_rate = 0.1;
    int epochs = 1000;

    // 训练模型
    train_model(x_train, y_train, w, b, learning_rate, epochs);

    // 测试:输入归一化后的面积(对应原始85平米)
    double x_test = (85 - 50) / (100 - 50); // 原始85平米归一化后的值
    double y_pred = predict(x_test, w, b);
    // 反归一化得到真实价格
    double y_pred_real = y_pred * (30 - 15) + 15;
    std::cout << "\n预测85平米房屋价格:" << y_pred_real << "万元" << std::endl;

    return 0;
}

代码关键部分解释

  1. 数据归一化:避免不同特征的数值范围差异过大(比如面积是几十,价格是几万),导致梯度下降收敛慢。这里用最小-最大归一化,把数据缩到0-1区间。
  2. 模型预测:完全遵循线性回归的数学公式y = wx + b,没有任何黑箱逻辑。
  3. 损失函数:用均方误差衡量预测偏差,这是回归任务最常用的损失计算方式。
  4. 梯度计算:手动推导损失对w和b的偏导数,这是梯度下降的核心——明确参数往哪个方向调整能减少损失。
  5. 训练循环:迭代更新w和b,每次用全部训练数据计算梯度(批量梯度下降),直到损失趋于稳定。

进阶建议

  • 这个示例是单特征线性回归,你可以扩展到多特征(比如加入房间数、楼层等),只需要把w改成向量,计算梯度时对应每个特征的偏导即可。
  • 可以尝试实现逻辑回归(分类任务),只需要把预测函数换成sigmoid,损失函数换成交叉熵。
  • 手动实现时重点要理解每一步的数学原理,而不是照搬代码——比如为什么用MSE?梯度下降的数学推导是什么?

内容的提问来源于stack exchange,提问作者Bryan Anthony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 14:03:14