多元最小二乘回归 C++有截距和预测的带类实现 及案例
时间: 2024-02-20 16:56:41 浏览: 22
以下是一个多元最小二乘回归的C++类实现及其使用案例。
```
#include <iostream>
#include <vector>
#include <cmath>
class MultipleLinearRegression {
private:
int n; // 自变量个数
int m; // 样本个数
std::vector<double> y; // 因变量
std::vector<std::vector<double>> x; // 自变量矩阵
std::vector<double> beta; // 模型系数
double SSR; // 回归平方和
double SSE; // 残差平方和
double SST; // 总平方和
double R2; // 决定系数
public:
MultipleLinearRegression(int _n, int _m) : n(_n), m(_m), beta(_n + 1) {
x.resize(m, std::vector<double>(n + 1));
}
void setY(const std::vector<double>& _y) {
y = _y;
}
void setX(const std::vector<std::vector<double>>& _x) {
for (int i = 0; i < m; i++) {
x[i][0] = 1.0;
for (int j = 0; j < n; j++) {
x[i][j + 1] = _x[i][j];
}
}
}
void fit() {
// 计算模型系数
std::vector<std::vector<double>> xtx(n + 1, std::vector<double>(n + 1));
std::vector<double> xty(n + 1);
for (int i = 0; i < m; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
xtx[j][k] += x[i][j] * x[i][k];
}
xty[j] += x[i][j] * y[i];
}
}
for (int i = 0; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
double r = xtx[j][i] / xtx[i][i];
for (int k = i + 1; k <= n; k++) {
xtx[j][k] -= r * xtx[i][k];
}
xty[j] -= r * xty[i];
}
}
for (int i = n; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
double r = xtx[j][i] / xtx[i][i];
for (int k = i; k >= j; k--) {
xtx[j][k] -= r * xtx[i][k];
}
xty[j] -= r * xty[i];
}
beta[i] = xty[i] / xtx[i][i];
}
// 计算回归平方和、残差平方和、总平方和和决定系数
double ymean = 0.0;
for (int i = 0; i < m; i++) {
ymean += y[i];
}
ymean /= m;
SSR = SSE = SST = 0.0;
for (int i = 0; i < m; i++) {
double yhat = predict(x[i]);
SSR += (yhat - ymean) * (yhat - ymean);
SSE += (yhat - y[i]) * (yhat - y[i]);
SST += (y[i] - ymean) * (y[i] - ymean);
}
R2 = SSR / SST;
}
double predict(const std::vector<double>& _x) {
double yhat = beta[0];
for (int i = 0; i < n; i++) {
yhat += beta[i + 1] * _x[i];
}
return yhat;
}
double getSSR() {
return SSR;
}
double getSSE() {
return SSE;
}
double getSST() {
return SST;
}
double getR2() {
return R2;
}
};
int main() {
// 构造样本数据
std::vector<std::vector<double>> x = {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}};
std::vector<double> y = {6, 7, 8};
// 构造回归模型并拟合数据
MultipleLinearRegression model(3, 3);
model.setX(x);
model.setY(y);
model.fit();
// 输出模型系数、回归平方和、残差平方和、总平方和和决定系数
std::cout << "beta: ";
for (int i = 0; i < 4; i++) {
std::cout << model.predict({i, i + 1, i + 2}) << " ";
}
std::cout << std::endl;
std::cout << "SSR: " << model.getSSR() << std::endl;
std::cout << "SSE: " << model.getSSE() << std::endl;
std::cout << "SST: " << model.getSST() << std::endl;
std::cout << "R2: " << model.getR2() << std::endl;
return 0;
}
```
在上面的代码中,我们定义了一个`MultipleLinearRegression`类来实现多元最小二乘回归,其中包含了以下几个成员变量:
- `n`:自变量个数
- `m`:样本个数
- `y`:因变量
- `x`:自变量矩阵
- `beta`:模型系数
- `SSR`:回归平方和
- `SSE`:残差平方和
- `SST`:总平方和
- `R2`:决定系数
我们还定义了以下几个成员函数:
- `setY`:设置因变量
- `setX`:设置自变量矩阵
- `fit`:拟合数据并计算模型系数、回归平方和、残差平方和、总平方和和决定系数
- `predict`:预测因变量值
- `getSSR`:获取回归平方和
- `getSSE`:获取残差平方和
- `getSST`:获取总平方和
- `getR2`:获取决定系数
在使用示例中,我们构造了一个包含3个自变量和3个样本的样本数据,然后构造回归模型并拟合数据,最后输出模型系数、回归平方和、残差平方和、总平方和和决定系数。