最小二乘法

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);
    }

}

运行结果为:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祝云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值