线性回归,最小二乘法 C语言实现

1.  前言

最近断断续续重温了一些数学书,有高等数学,也有初等数学。有时候,觉得数学才是世界上最美的东西,但有时候又觉得数学很高冷,不接地气。

不过,前段时间工作中用到了最小二乘法,下面记录一些用法。


2. 最小二乘法


根据维基百科的说明:
最小二乘法 (又称 最小平方法 )是一种 数学 优化 技术。
它通过最小化 误差 的平方和寻找数据的最佳 函数 匹配。
利用 最小二乘法 可以简便地求得未知的数据,
并使得这些求得的数据与实际数据之间误差的平方和为最小。

看了之后一头雾水对不对,是的,任何人看着一段不知道在说啥。下面举个例子,就很好懂了。

针对线性最小二乘法即直线拟合,如下图(来自维基百科)所示:


透过这张图,我想大家一定能理解,我们用最小二乘法来做什么事情,即: 

根据已有的数据(图中的点),来做出一条最贴近数据发展趋势的直线。

通过这条直线,我们可以对未来的数据进行预测,因为基本会落在这条直线附近。

当然了,最小二乘法不只是直线,还可以是曲线,本文不讨论。

3. 求解直线方程
我们现在要做的,就是求解直线方程。

假设已知有N个点,设这条直线方程为:  y = a·x + b

其中,a和b的计算公式如下:

简化后:

本文对于推导过程不在赘述,网上都有。

4. 算法代码和效果演示

#include <stdio.h>
#include <stdlib.h>

#define     COUNT     18.0
int main()
{
    //float x[6]={0.0,1.0,2.0,3.0,4.0,5.0};
    //float y[6]={1.1,1.9,3.1,3.9,4.4,4.9};
    /*float x[6]={0.0,1.0,2.0,3.0,4.0,5.0};
    float y[6]={0.0,1.0,2.0,3.0,4.0,5.0};*/
    float x[18]={0};
    float y[18]={560,560,560,560,558,560,556,547,545,548,545,547,547,547,547,547,555,558};


    float a,b,mxy,xx,yy,x2,x22;
    int i;

    a=b=mxy=xx=yy=x2=x22=0.0;

    for(i=0;i<COUNT;i++)
    {
        x[i] = i;
        mxy=COUNT*x[i]*y[i]+mxy;
        xx=1.0*x[i]+xx;
        yy=1.0*y[i]+yy;
        x2=1.0*x[i]*x[i]*COUNT+x2;
        x22=1.0*x[i]+x22;
    }

    b=1.0*(mxy-xx*yy)/(x2-x22*x22);
    a=1.0*yy/COUNT-b*xx/COUNT;

    printf("Y=%0.2fx+%0.2f\n",b,a);
    
    system("pause");
    return 0;
}

结果:

Y=-0.68x+558.39

sh: 1: pause: not found

一元线性最小二乘法是一种常用的回归分析方法,用于拟合一条直线来描述两个变量之间的关系。下面是一个简单的C语言程序示例,用于实现一元线性最小二乘法: ```c #include <stdio.h> // 定义结构体存储数据点 typedef struct { double x; double y; } DataPoint; // 计算一元线性最小二乘法拟合直线的斜率和截距 void linearRegression(DataPoint data[], int n, double *slope, double *intercept) { double sumX = 0, sumY = 0, sumXY = 0, sumXX = 0; // 计算各项累加和 for (int i = 0; i < n; i++) { sumX += data[i].x; sumY += data[i].y; sumXY += data[i].x * data[i].y; sumXX += data[i].x * data[i].x; } // 计算斜率和截距 *slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX); *intercept = (sumY - *slope * sumX) / n; } int main() { // 定义数据点数组 DataPoint data[] = {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}}; int n = sizeof(data) / sizeof(data); // 计算拟合直线的斜率和截距 double slope, intercept; linearRegression(data, n, &slope, &intercept); // 输出结果 printf("拟合直线方程为:y = %.2fx + %.2f\n", slope, intercept); return 0; } ``` 这个程序通过定义一个结构体`DataPoint`来存储数据点的x和y值。`linearRegression`函数用于计算一元线性最小二乘法的斜率和截距,通过传入数据点数组和数据点个数,计算得到拟合直线的斜率和截距。最后在`main`函数中调用`linearRegression`函数,并输出拟合直线的方程。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值