多元 Huber Regression C++ 带类实现及可以得到正确结果的案例
时间: 2024-03-16 13:46:27 浏览: 117
以下是一个多元 Huber Regression C++ 带类实现的示例代码。这个代码使用了梯度下降法来求解 Huber Regression,可以处理多个自变量和一个因变量的情况。在实现中,我们定义了一个 Regression 类,它包含了许多重要的函数和变量,如训练数据,模型参数,损失函数,梯度下降算法等等。
```cpp
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
class Regression {
public:
Regression(int num_features, double learning_rate, double delta)
: num_features(num_features), learning_rate(learning_rate), delta(delta) {}
double train(vector<vector<double>> &X, vector<double> &y);
private:
int num_features;
double learning_rate;
double delta;
vector<double> w;
double huber_loss(vector<vector<double>> &X, vector<double> &y);
vector<double> gradient(vector<vector<double>> &X, vector<double> &y);
};
double Regression::train(vector<vector<double>> &X, vector<double> &y) {
// 初始化参数 w
w.resize(num_features + 1, 0.0);
w[0] = 1.0;
for (int i = 0; i < 1000; i++) {
double loss = huber_loss(X, y);
if (i % 100 == 0) {
cout << "epoch " << i << ", loss = " << loss << endl;
}
vector<double> grad = gradient(X, y);
for (int j = 0; j < num_features + 1; j++) {
w[j] -= learning_rate * grad[j];
}
}
return huber_loss(X, y);
}
double Regression::huber_loss(vector<vector<double>> &X, vector<double> &y) {
double loss = 0.0;
for (int i = 0; i < X.size(); i++) {
double y_pred = 0.0;
for (int j = 0; j < num_features; j++) {
y_pred += w[j + 1] * X[i][j];
}
y_pred += w[0];
double error = y[i] - y_pred;
if (abs(error) <= delta) {
loss += 0.5 * error * error;
} else {
loss += delta * abs(error) - 0.5 * delta * delta;
}
}
return loss / X.size();
}
vector<double> Regression::gradient(vector<vector<double>> &X, vector<double> &y) {
vector<double> grad(num_features + 1, 0.0);
for (int i = 0; i < X.size(); i++) {
double y_pred = 0.0;
for (int j = 0; j < num_features; j++) {
y_pred += w[j + 1] * X[i][j];
}
y_pred += w[0];
double error = y[i] - y_pred;
if (abs(error) <= delta) {
for (int j = 0; j < num_features; j++) {
grad[j + 1] += error * X[i][j];
}
grad[0] += error;
} else {
for (int j = 0; j < num_features; j++) {
grad[j + 1] += delta * X[i][j] * (error > 0 ? -1 : 1);
}
grad[0] += delta * (error > 0 ? -1 : 1);
}
}
for (int i = 0; i < num_features + 1; i++) {
grad[i] /= X.size();
}
return grad;
}
int main() {
vector<vector<double>> X = {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}};
vector<double> y = {3, 4, 5, 6, 7};
Regression model(2, 0.01, 1);
double loss = model.train(X, y);
cout << "training loss = " << loss << endl;
cout << "model parameters = ";
for (int i = 0; i < model.w.size(); i++) {
cout << model.w[i] << " ";
}
cout << endl;
return 0;
}
```
在这个示例中,我们使用了一个大小为 5×2 的训练数据集,其中每一行代表一个样本,第一列为常数 1,第二列和第三列为两个自变量,最后一列为因变量。模型参数包括了一个常数项和两个自变量系数,这些参数在训练过程中被更新。损失函数使用了 Huber Loss,它可以在一定程度上避免由于异常值而出现的过拟合问题。
在主函数中,我们首先创建了一个 Regression 类的实例,然后调用了它的 train 函数来训练模型。该函数使用了梯度下降算法来更新模型参数,直到损失函数收敛。最后,我们输出了训练后得到的模型参数和损失函数的值。
需要注意的是,这个示例只是一个简单的多元 Huber Regression 的实现,还有很多可以改进的地方。例如,可以使用更高效的优化算法,如随机梯度下降或牛顿法;可以添加正则化项来防止过拟合;可以使用交叉验证来选择最佳的模型超参数等等。
阅读全文