随机梯度下降回归 带截距和带参数的C++带类实现及案例
时间: 2024-03-05 15:48:47 浏览: 70
简单的梯度下降C++实现
5星 · 资源好评率100%
以下是一个简单的随机梯度下降回归模型的 C++ 类实现,包括带截距和带参数的情况:
```c++
#include <iostream>
#include <vector>
#include <random>
using namespace std;
class LinearRegression {
private:
vector<double> weights; // 权重
double bias; // 截距
double learning_rate; // 学习率
public:
// 构造函数
LinearRegression(double learning_rate) {
this->learning_rate = learning_rate;
}
// 训练函数(带截距)
void train(vector<vector<double>> X, vector<double> y) {
int m = X.size(); // 样本数
int n = X[0].size(); // 特征数
// 初始化权重和截距
weights.resize(n);
for (int i = 0; i < n; i++) {
weights[i] = 0.0;
}
bias = 0.0;
// 随机梯度下降
for (int epoch = 0; epoch < 100; epoch++) {
for (int i = 0; i < m; i++) {
double y_pred = predict(X[i]);
double error = y_pred - y[i];
// 更新权重和截距
for (int j = 0; j < n; j++) {
weights[j] -= learning_rate * error * X[i][j];
}
bias -= learning_rate * error;
}
}
}
// 训练函数(带参数)
void train(vector<vector<double>> X, vector<double> y, vector<double> init_weights, double init_bias) {
int m = X.size(); // 样本数
int n = X[0].size(); // 特征数
// 初始化权重和截距
weights = init_weights;
bias = init_bias;
// 随机梯度下降
for (int epoch = 0; epoch < 100; epoch++) {
for (int i = 0; i < m; i++) {
double y_pred = predict(X[i]);
double error = y_pred - y[i];
// 更新权重和截距
for (int j = 0; j < n; j++) {
weights[j] -= learning_rate * error * X[i][j];
}
bias -= learning_rate * error;
}
}
}
// 预测函数
double predict(vector<double> x) {
double y_pred = bias;
for (int i = 0; i < weights.size(); i++) {
y_pred += weights[i] * x[i];
}
return y_pred;
}
};
int main() {
// 构造训练数据
vector<vector<double>> X = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}};
vector<double> y = {6.0, 15.0, 24.0};
// 创建模型对象
LinearRegression lr(0.01);
// 训练模型(带截距)
lr.train(X, y);
// 输出权重和截距
cout << "Weights: ";
for (int i = 0; i < lr.weights.size(); i++) {
cout << lr.weights[i] << " ";
}
cout << endl;
cout << "Bias: " << lr.bias << endl;
// 训练模型(带参数)
vector<double> init_weights = {0.5, 0.5, 0.5};
double init_bias = 1.0;
lr.train(X, y, init_weights, init_bias);
// 输出权重和截距
cout << "Weights: ";
for (int i = 0; i < lr.weights.size(); i++) {
cout << lr.weights[i] << " ";
}
cout << endl;
cout << "Bias: " << lr.bias << endl;
return 0;
}
```
在上述代码中,我们使用了一个 `LinearRegression` 类来实现随机梯度下降回归模型。其中,构造函数接收一个学习率参数,用于调节模型的学习速度。`train` 函数用于训练模型,其中第一个版本针对带截距的情况,第二个版本针对带参数的情况。`predict` 函数用于预测输入样本的输出值。
在主函数中,我们首先构造了一个简单的训练数据集,包括三个样本和三个特征。然后,我们创建了一个 `LinearRegression` 对象,并使用 `train` 函数训练模型。最后,我们输出了模型的权重和截距。
值得注意的是,在第二次训练时,我们传入了一个初始权重和截距,用于加速模型的收敛。这种方法通常被称为“预热”(warm-up),可以帮助模型在训练初期快速逼近最优解。
阅读全文