最小二乘法线性拟合及其代码实现(C语言)


前言

最小二乘法是最常用的数据拟合方法。本文从最小二乘法概念入手,介绍了其线性拟合的机理;之后通过C语言进行了算法实现;最后阐述了最小二乘法线性拟合的缺点与不足


一、最小二乘法

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

以最简单的 y y y关于 x x x的线性方程: y = β 0 + β 1 x y=β_0+β_1x y=β0+β1x为例。 假设给出的若干点的坐标为:( x 1 , y 1 x_1 , y_1 x1,y1 ) , ( x 2 , y 2 x_2 , y_2 x2,y2) ⋯( x j , y j x_j , y_j xj,yj) ⋯( x n , y n x_n , y_n xn,yn); 定义纵坐标 y y y的残差 R e s i d u a l Residual Residual为估计值与观测值之差,公式如下:
R e s i d u a l = y i − ( β 0 + β 1 x ) Residual = y_i - (β_0+β_1x) Residual=yi(β0+β1x);
在这里插入图片描述

β 0 = n Σ y i ‾ − n β 1 Σ x i ‾ β_0 = ^{\underline{Σ{y_i}}}_{n}- ^{\underline{β_1Σ{x_i}}}_{n} β0=nΣyinβ1Σxi

β 1 = n Σ x i 2 − ( Σ x i ) 2 n Σ x i y i − Σ x i Σ y i ‾ β_1 = ^{\underline{nΣ{x_iy_i}-Σ{x_i}Σ{y_i}}}_{nΣ{x_i}^2-(Σ{x_i})^2} β1=nΣxi2(Σxi)2nΣxiyiΣxiΣyi
一般最小二乘法的目的是使拟合误差(残差和)最小,即最小二乘法就是找到一组直线的参数,使得目标函数最小。

二、代码实现(C语言)

代码如下:

/**************************************************************/
// 最小二乘法线性拟合(y = β0 + β1x)
// 注:本程序仅考虑因变量y存在误差的情况,自变量给定为X_sample
/**************************************************************/
float β1;
float β0;
const int16_t X_sample[100] =
	{
    
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
	21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
	41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
	61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
	81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100};

//	平方和
float Square_sum(int16_t* data, uint16_t len)
{
    
    
	uint16_t i;
	float z = 0;
	for (i = 0; i < len; i++)
	{
    
    
		z = z + (*data)*(*data);
		data++;
	}
	return z;
}

//	向量积
float X_By_Y(int16_t* X, int16_t* Y, uint16_t len)
{
    
    
	uint16_t i;
	float z = 0;
	for (i = 0; i < len; i++)
	{
    
    
		z = z + X[i] * Y[i];
	}
	return z;
}

//	最小二乘法线性拟合
float Line_fit(int16_t *data, uint16_t len)
{
    
    
	float X_square     = Square_sum((int16_t*)X_sample, len);
	float X_multiply_Y = X_By_Y((int16_t*)X_sample, data, len);

	float X_sum = SFLeaSum16s((int16_t*)X_sample, len);
	float Y_sum = SFLeaSum16s(data, len);

	β0= (X_square*Y_sum - X_sum*X_multiply_Y)/(len*X_square - X_sum*X_sum);
	β1= (len*X_multiply_Y - Y_sum*X_sum)/(len*X_square - X_sum*X_sum);

	return β1;
}

float Line_return(int16_t X)
{
    
    
	return β0 + β1*X;
}

三、缺陷与不足

1. 对异常值很敏感

观察其代数解法的结果,最小二乘法仅使用了点的均值和方差信息,因此仅适用于存在普通噪声的情况,当存在异常值时,一般最小二乘法对异常值很敏感,可能会改变最后的结果,需采用其他方法解决。

2. 没有考虑自变量的误差

只有当自变量不存在偏差,或者自变量的偏差在一定范围内可以忽略不计时,最小二乘法才比较适用。因为一般最小二乘法仅考虑了因变量 y y y存在误差的情况,没有考虑自变量 x x x的误差,所以其应用条件有一定的限制。

3. 存在不可求解的情况

当要拟合的直线是垂直或接近垂直于 x x x轴时,斜率无穷大,最小二乘法不适用。

总结

1)最小二乘法是最常用的数据拟合方法,通过最小化误差的平方和寻找数据的最佳函数匹配;
2)最小二乘法仅使用了点的均值和方差信息,对异常值很敏感;
3)最小二乘法仅考虑了因变量 y y y存在误差的情况,但当点的横纵坐标都存在误差,而且都不能忽略时,一般最小二乘法不适用;
4)最小二乘法存在不可求解的情况(拟合的直线是垂直或接近垂直于 x x x轴)。

以上便是本文的全部内容,希望本文能对大家理解和运用最小二乘法进行线性拟合有所帮助。
当然,本文内容如有错误或不严谨之处,也恳请大家及时指出,谢谢!

参考

线性回归——最小二乘法拟合 - David Xu 2014 - 博客园
线性拟合1-最小二乘法_ningzian的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/m0_64770246/article/details/125691073