当前位置: 首页 > article >正文

2023-12-03 C语言最小二乘法备忘


点击 <C 语言编程核心突破> 快速C语言入门


C语言最小二乘法备忘

  • 前言
  • 一、数学公式
  • 二、代码
  • 总结


前言

要解决问题: 最小二乘法实现线性回归的C语言实现, 这个数学公式转为C语言.


一、数学公式

设有 n n n 组数据

( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x n , y n ) \huge (x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n) (x1,y1),(x2,y2),,(xn,yn)

要求解线性方程

y = a x + b \huge y=ax+b y=ax+b

使得所有数据到直线的距离之和最小。

首先,计算数据的均值
x ˉ = 1 n ∑ i = 1 n x i \huge \bar{x}=\frac{1}{n}\sum_{i=1}^nx_i xˉ=n1i=1nxi

y ˉ = 1 n ∑ i = 1 n y i \huge \bar{y}=\frac{1}{n}\sum_{i=1}^ny_i yˉ=n1i=1nyi

然后,计算 x x x y y y 的协方差

s x y = 1 n ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) \huge s_{xy}=\frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})(y_i-\bar{y}) sxy=n1i=1n(xixˉ)(yiyˉ)

x x x 的方差

s x 2 = 1 n ∑ i = 1 n ( x i − x ˉ ) 2 \huge s_{x}^2=\frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})^2 sx2=n1i=1n(xixˉ)2

最后,直线的斜率 a a a 和截距 b b b 分别为:

a = s x y s x 2 \huge a=\frac{s_{xy}}{s_{x}^2} a=sx2sxy

b = y ˉ − a x ˉ \huge b=\bar{y}-a\bar{x} b=yˉaxˉ

以上就是最小二乘法线性回归的数学公式,不使用矩阵。


二、代码

最小二乘法是一种数学优化技术,它通过最小化误差的平方和寻找数据的最佳函数匹配。

下面是一个使用C语言实现最小二乘法的例子:

#include <stdio.h>

// 最小二乘法
void leastSqaureMethod(double arrayX[], double arrayY[], const int num,
                       double *numA, double *numB)
{
    // 计算x和y的总和, 以计算平均值
    double sumX = 0.0;
    double sumY = 0.0;
    for (int i = 0; i != num; ++i)
    {
        sumX += arrayX[i];
        sumY += arrayY[i];
    }

    // 计算x和y的平均值
    double aveX = sumX / num;
    double aveY = sumY / num;

    // 计算n倍的x和y的协方差, 以及x的方差
    double nSXY = 0.0;
    double nS2X = 0.0;
    for (int i = 0; i != num; ++i)
    {
        nSXY += (arrayX[i] - aveX) * (arrayY[i] - aveY);
        nS2X += (arrayX[i] - aveX) * (arrayX[i] - aveX);
    }

    // 计算系数a和b
    *numA = nSXY / nS2X;
    *numB = aveY - (*numA) * aveX;
}

int main()
{
    double BOD5[] = {234, 251, 252, 285, 231, 202, 201, 238, 257,
                     211, 225, 220, 226, 268, 279, 300, 286, 254,
                     221, 232, 210, 219, 218, 222, 231};
    double CODCr[] = {532, 634, 559, 691, 484, 482, 474, 556, 512,
                      423, 541, 498, 551, 584, 621, 614, 547, 587,
                      529, 577, 485, 501, 500, 532, 561};

    double numA;
    double numB;

    leastSqaureMethod(BOD5, CODCr, 25, &numA, &numB);

    printf("f(x) = %lf * x + %lf\n", numA, numB);

    return 0;
}

此程序中的函数leastSquareMethod实现了最小二乘法,用于通过给定的一组数据点,求出最佳拟合直线的系数a和b的值。

其中,double arrayX[]double arrayY[]分别为输入数据点的横坐标和纵坐标数组,const int num为数据点的数量,double *numAdouble *numB为求得的系数ab的返回值。

在主函数中,定义了两个数组BOD5CODCr,分别存储了25组数据点。

然后,调用函数leastSquareMethod计算出系数a和b的值,并将结果输出到控制台上。


总结

根据数学公式翻译成C语言, 简单的公式还是不太难的, 需要注意的是精度, 以及是否可能产生溢出, 通常来讲, double足够了.


点击 <C 语言编程核心突破> 快速C语言入门



http://www.kler.cn/a/161671.html

相关文章:

  • 树莓派(Raspberry Pi)Pico 2 C_C++开发环境配置(Docker+SDK)
  • AUTOSAR_EXP_ARAComAPI的7章笔记(3)
  • 数据集标注txt文件读取小工具
  • 【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线
  • C#文字识别API场景解析、表格识别提取
  • mac终端使用pytest执行iOS UI自动化测试方法
  • 零基础自学C语言|深入理解指针 ④
  • 2002-2021年全国各地级市环境规制18个相关指标数据
  • vue项目中如何引入zip压缩包之解决方案
  • html和css写去哪儿导航条
  • CefSharp 获取POST(AJAX)、GET消息返回值(request)
  • “低代码开发:快餐大厨还是魔术棒?探寻软件开发的诙谐世界“
  • ZooKeeper学习一
  • Verilog学习 | 用initial语句写出固定的波形
  • 《使用ThinkPHP6开发项目》 - 安装ThinkPHP框架
  • Amazon CodeWhisperer 正式发布可免费供个人使用
  • 【Flink系列五】Checkpoint及Barrier原理
  • CCF刷题记录 -- 202305-2:矩阵运算 --python解法
  • 【每日一题】—— D. Divide and Equalize(Codeforces Round 903 (Div. 3))(数学、数论)
  • 12.07
  • Hadoop学习笔记(HDP)-Part.19 安装Kafka
  • Win10 安装.NET Framework 3.5 报错0x80240438
  • 利用 Python 进行数据分析实验(四)
  • log4j日志框架的使用
  • 【redis笔记】分布式锁
  • 在 CentOS 或 Red Hat 系统上安装 Citus 组件