用C語言實現最小二乘法算法


本文博客鏈接:http://blog.csdn.net/jdh99,作者:jdh,轉載請注明.

公式參考:https://www.cnblogs.com/paiandlu/p/7843236.html

 

 

 

 

基本思想

求出這樣一些未知參數使得樣本點和擬合線的總誤差(距離)最小

最直觀的感受如下圖(圖引用自知乎某作者)

而這個誤差(距離)可以直接相減,但是直接相減會有正有負,相互抵消了,所以就用差的平方

推導過程

1 寫出擬合方程
𝑦=𝑎+𝑏𝑥y=a+bx

(3287.82)/(20391.6)

= 0.16123403754487141764

截距

擬合方程

y=0.161234x-8.6394

#include <stdio.h>

/*********************************************************************
*                           宏定義
**********************************************************************/

/*********************************************************************
*                           數據fifo長度
**********************************************************************/

#define LEN     100

/*********************************************************************
*                           數據結構
**********************************************************************/

/*********************************************************************
*                           數據單元
**********************************************************************/

struct _Data_Unit
{
    float x;
    float y;
};

/*********************************************************************
*                           數據fifo
**********************************************************************/

struct _Data
{
    struct _Data_Unit data[LEN];
    int len;
};

/*********************************************************************
*                           全局變量
**********************************************************************/

/*********************************************************************
*                           數據fifo
**********************************************************************/

struct _Data Data =
{
    .len = 0
};

/*********************************************************************
*                           函數
**********************************************************************/

/*********************************************************************
*                           壓入數據
*參數:x:測量數據x
*     y:測量數據y
**********************************************************************/

void push(float x, float y)
{
    int i = 0;

    if (Data.len < LEN)
    {
        Data.data[Data.len].x = x;
        Data.data[Data.len++].y = y;
        return;
    }

    //數據移動,去掉最后一個數據
    for (i = 0; i < LEN - 1; i++)
    {
        Data.data[i].x = Data.data[i + 1].x;
        Data.data[i].y = Data.data[i + 1].y;
    }
    Data.data[LEN].x = x;
    Data.data[LEN].y = y;
    Data.len = LEN;
}

/*********************************************************************
*                           計算估值
*擬合曲線y = a * x + b
*參數:x:需要估值的數的x值
*返回:估值y
**********************************************************************/

float calc(float x)
{
    int i = 0;
    float mean_x = 0;
    float mean_y = 0;
    float num1 = 0;
    float num2 = 0;
    float a = 0;
    float b = 0;

    //求t,y的均值
    for (i = 0; i < Data.len; i++)
    {
        mean_x += Data.data[i].x;
        mean_y += Data.data[i].y;
    }
    mean_x /= Data.len;
    mean_y /= Data.len;

    printf("mean_x = %f,mean_y = %f\n", mean_x, mean_y);

    for (i = 0; i < Data.len; i++)
    {
        num1 += (Data.data[i].x - mean_x) * (Data.data[i].y - mean_y);
        num2 += (Data.data[i].x - mean_x) * (Data.data[i].x - mean_x);
    }

    b = num1 / num2;
    a = mean_y - b * mean_x;

    printf("a = %f,b = %f\n", a, b);

    return (a + b * x);
}


int main()
{
    float length[10] = {208, 152, 113, 227, 137, 238, 178, 104, 191, 130};
    float width[10] = {21.6, 15.5, 10.4, 31.0, 13.0, 32.4, 19.0, 10.4, 19.0, 11.8};
    int i = 0;

    for (i = 0; i < 10; i++)
    {
        push(length[i], width[i]);
    }
    printf("300m長度的戰艦預測寬度為為%f米\n", calc(300));

    //getchar();
    return 0;
}

mean_x = 167.800003,mean_y = 18.410000
a = -8.645075,b = 0.161234

 計算器計算:

0.161234*300-8.6394

= 39.7308

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM