1原理
最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。(来自百度)
2.模型
2.1线性模型
假设(x,y)的一组数(x1,y1),(x2,y2)……(xn,yn)之间的相互关系是近似一条直线,此时令此直线方程为y=ax+b,也就是说此时需要找合适的a,b使得 (①式)都相等。实际上,这是不可能的,那么根据二乘法的原理就找合适的a,b使得实际值和计算值之差的平方和最小,即累计和最小。
代入①式,得
(②式)
欲求此值最小,那么就是分别对a,b求偏导数,令偏导数为0,即得:
整理上式得:
因为a,b都是常数,所以:
求得a,b是
2.2 k次多项式模型
3 代码实现
3.1 线性模型实现
// LeastSquareMethod.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
void LinearFit(double *X,double *Y,int length)
{
double a = 0.0,b = 0.0;
double lTotalX = 0.0; //保存∑Xi
double lTotalY = 0.0; //保存∑Yi
double lTotalXX = 0.0; //保存xi平方的累加和
double lTotalXY = 0.0; //保存∑Xi*∑Yi
for (int i=0;i<length;i++)
{
lTotalX += X[i];
lTotalY += Y[i];
lTotalXX += X[i]*X[i];
lTotalXY += X[i]*Y[i];
}
a = (length * lTotalXY - lTotalX*lTotalY)/(length*lTotalXX - lTotalX*lTotalX);
b = (lTotalY*lTotalXX - lTotalXY*lTotalX)/(length*lTotalXX - lTotalX*lTotalX);
cout<<"a = "<<a<<", b = "<<b<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
double X[] = {2,4,6,8,10,12};
double Y[] = {8.9,10.1,11.2,12.0,13.1,13.9};
int length = sizeof(X)/sizeof(X[0]);
LinearFit(X,Y,length);
system("pause");
return 0;
}
运行结果为:
java版
public class LeastSquareMethod {
static void LinearFit(double []X, double []Y, int length){
double a = 0.0;
double b = 0.0;
double totalX = 0.0;
double totalY = 0.0;
double totalXY = 0.0;
double totalXX = 0.0;
for(int i =0; i< length;i++){
totalX += X[i];
totalY += Y[i];
totalXY += X[i]*Y[i];
totalXX += X[i]*X[i];
}
a = (length * totalXY - totalX * totalY)/(length * totalXX - totalX*totalX);
b = (totalY * totalXX - totalXY * totalX)/(length * totalXX - totalX*totalX);
System.out.printf("a = %f , b = %f .", a,b);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
double X[] = {2,4,6,8,10,12};
double Y[] = {8.9,10.1,11.2,12.0,13.1,13.9};
int length = X.length;
LinearFit(X,Y,length);
}
}
运行结果为: