最近在工作中需要使用到最小二乘法对数据进行拟合,虽然以前听说过最小二乘法的大名但一直没有进行过详细的了解,借着这个机会正好研究下。
- 最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和来查找数据的最佳函数匹配。利用最小二乘法可以简便的求得未知的数据,并使得这些求得的数据和实际数据之间的误差的平方和最小。最小二乘法还可以用来进行曲线的拟合。更多关于最小二乘法的介绍可以参考这篇博文 https://www.matongxue.com/madocs/818/
我需要的正是利用最小二乘法找到使得误差平方和最小的一元线性回归方程ax+b=y
。通过对最小二乘法的计算可得出如下公式:
- 使用c++代码实现一阶最小二乘法求解
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
int LeastSquare(vector<double> &x, vector<double> &y, double input_x){
if(x.size()==0 || y.size()==0 || x.size()!=y.size())
return 0;
int n=x.size();
double a = 0;
double b = 0;
double xi2 = 0;
double yi2 = 0;
double xiyi = 0;
double sumxi = 0;
double sumyi = 0;
for(int i=0; i<x.size(); i++){
xi2 += pow(x[i],2);
yi2 += pow(y[i],2);
sumxi += x[i];
sumyi += y[i];
xiyi +=x[i]*y[i];
}
a = (n*xiyi-sumxi*sumyi)/(n*xi2 - pow(sumxi, 2));
b = (xi2*sumyi - sumxi*xiyi)/(n*xi2 - pow(sumxi, 2));
return a*input_x + b;
}
int _tmain(int argc, _TCHAR* argv[])
{
double x[5] = {25.0,27.0,31.0,33.0,35.0};
double y[5] = {110.0,115.0,155.0,160.0,180.0};
std::vector<double> xlist(x,x+5);
std::vector<double> ylist(y, y+5);
double result = LeastSquare(xlist, ylist,20);
cout<<result<<endl;
system("pause");
return 0;
}
上述计算一元方程拟合公式的方法是在手动算出拟合公式的情况下进行计算的,有很强的局限性。不能有效地针对多元方程进行计算。可以自由设定拟合项数的最小二乘法计算函数可以参考该博客进行实现 https://blog.csdn.net/weixin_44344462/article/details/88850409 。数学知识对于一个程序员来说真的还是蛮重要的,以后有时间还是要多补补高等数学和线性代数方面的知识。