
引言
在 C++ 中实现线性拟合(Linear Fit),可以通过最小二乘法(Least Squares Method)来计算最佳拟合直线的斜率和截距。以下是一个完整的线性拟合函数实现,包括输入数据点、计算斜率和截距,并输出拟合结果。
过程
线性拟合公式
给定一组数据点 (xi, yi),线性拟合的目标是找到一条直线 (y = mx + b),使得误差平方和最小。斜率和截距的计算公式如下:
其中:
- (N) 是数据点的数量。
- (m) 是斜率。
- (b) 是截距。
实现代码
#include <iostream>
#include <vector>
#include <tuple>
// 线性拟合函数
std::tuple<double, double> linearFit(const std::vector<double>& x, const std::vector<double>& y) {
if (x.size() != y.size() || x.empty())
throw std::invalid_argument("Input vectors must be of the same non-zero size.");
}
size_t N = x.size();
double sumX = 0.0, sumY = 0.0, sumXY = 0.0, sumX2 = 0.0;
// 计算各项和
for (size_t i = 0; i < N; ++i) {
sumX += x[i];
sumY += y[i];
sumXY += x[i] * y[i];
sumX2 += x[i] * x[i];
}
// 计算斜率 (m) 和截距 (b)
double m = (N * sumXY - sumX * sumY) / (N * sumX2 - sumX * sumX + 1e-5);
double b = (sumY - m * sumX) / N;
return std::make_tuple(m, b);
}
int main() {
// 示例数据点
std::vector<double> x = {1, 2, 3, 4, 5};
std::vector<double> y = {2, 4, 5, 4, 5};
try {
// 进行线性拟合
auto [m, b] = linearFit(x, y);
// 输出结果
std::cout << "拟合直线方程: y = " << m << " * x + " << b << std::endl;
// 预测新值
double newX = 6;
double predictedY = m * newX + b;
std::cout << "当 x = " << newX << " 时,预测 y = " << predictedY << std::endl;
} catch (const std::exception& e) {
std::cerr << "错误: " << e.what() << std::endl;
}
return 0;
}
代码说明
1. 输入数据
- x 和 y 是两个 std::vector,分别存储数据点的 (x) 和 (y) 坐标。
- 如果 x 和 y 的大小不一致或为空,会抛出异常。
2. 计算各项和
- sumX:(x_i) 的总和。
- sumY:(y_i) 的总和。
- sumXY:(x_i y_i) 的总和。
- sumX2:(x_i^2) 的总和。
3. 计算斜率和截距
- 使用最小二乘法公式计算斜率 (m) 和截距 (b)。
4. 返回结果
- 使用 std::tuple<double, double> 返回斜率和截距。
5. 预测新值
- 使用拟合的直线方程 (y = mx + b) 预测新的 (y) 值。
小结
通过最小二乘法实现线性拟合,可以计算出最佳拟合直线的斜率和截距。