最小二乘法拟合直线、曲线

news2024/12/22 19:08:25

参考文章:马同学马同学提供线性代数,微积分,概率论与数理统计,机器学习等知识讲解https://www.matongxue.com/madocs/818/

C++最小二乘法拟合-(线性拟合和多项式拟合)_尘中远的博客-CSDN博客_namespace gsl

最小二乘法—多项式拟合非线性函数 - 简书

最小二乘法,即:最小化误差的平方和\epsilon

\epsilon =\sum_{i=1}^{m}\left ( y-y_{i} \right )^{2}             

 其中,m为样本点的数量,y为预测值,y_{i}为当前值。

  • 直线拟合:线性拟合(一元函数)

如果想要根据输入数据拟合一条直线,那么y可以表示为:

y=ax+b

\epsilon为:

\epsilon =\sum_{i=1}^{m}\left ( ax_{i}+b-y_{i} \right )^{2}

当a、b偏导数为0时,\epsilon最小:

\frac{\partial \epsilon }{\partial a}=2\sum_{i=1}^{m}\left ( ax_{i}+b-y_{i} \right )x_{i}=0

\frac{\partial \epsilon }{\partial b}=2\sum_{i=1}^{m}\left ( ax_{i}+b-y_{i} \right )=0

展开累加符号得:

a\sum_{i=1}^{m}x^{2}_{i}+b\sum_{i=1}^{m}x_{i}=\sum_{i=1}^{m}x_{i}y_{i}

a\sum_{i=1}^{m}x_{i}+bm=\sum_{i=1}^{m}y_{i}

根据克拉默(克莱姆)法则求解线性方程组(省略累加符号的上下限):

D=\begin{vmatrix} \sum x^{2}_{i} & \sum x_{i}\\ \sum x_{i}& m \end{vmatrix} , D_{1}=\begin{vmatrix} \sum x_{i}y_{i} & \sum x_{i}\\ \sum y_{i}& m \end{vmatrix} , D_{2}=\begin{vmatrix} \sum x_{i}^{2} & \sum x_{i}y_{i}\\ \sum x_{i}& \sum y_{i} \end{vmatrix}

a=\frac{D_{1}}{D}=\frac{m\sum x_{i}y_{i}-\sum x_{i}y_{i}}{m\sum x_{i}^{2}-\sum x_{i}\sum x_{i}}

b=\frac{D_{2}}{D}=\frac{\sum x_{i}^{2}\sum y_{i}-\sum x_{i}y_{i}\sum x_{i}}{m\sum x_{i}^{2}-\sum x_{i}\sum x_{i}}

C++代码

template<typename T>
bool linearFit(const T* x, const T* y,size_t length)
{
	factor.resize(2,0);
	typename T t1=0, t2=0, t3=0, t4=0;
	for(int i=0; i<length; ++i)
	{
		t1 += x[i]*x[i];
		t2 += x[i];
		t3 += x[i]*y[i];
		t4 += y[i];
	}
factor[1] = (t3*length - t2*t4) / (t1*length - t2*t2);
factor[0] = (t1*t4 - t2*t3) / (t1*length - t2*t2);
return true;
}
  • 曲线拟合:多项式拟合(多元函数)

如果想要根据输入数据拟合一条曲线,那么y可以表示为:

y=a_{0}+a_{1}x+a_{2}x^{2}+...+a_{n}x^{n}

\epsilon为:

\epsilon =\sum_{i=1}^{m}\left [ (a_{0}+a_{1}x_{i}+a_{2}x_{i}^{2}+...+a_{n}x_{i}^{n})-y_{i} \right ]^{2}

a_{0}a_{1}a_{2}、...a_{n}偏导数为0时,\epsilon最小:

\left\{\begin{matrix} \frac{\partial \epsilon }{\partial a_{0}}=2\sum_{i=1}^{m}\left [(a_{0}+a_{1}x_{i}+a_{2}x_{i}^{2}+...+a_{n}x_{i}^{n})-y_{i}\right]=0\\ \frac{\partial \epsilon }{\partial a_{1}}=2\sum_{i=1}^{m}\left [(a_{0}+a_{1}x_{i}+a_{2}x_{i}^{2}+...+a_{n}x_{i}^{n})-y_{i}\right]x_{i}=0\\ \frac{\partial \epsilon }{\partial a_{2}}=2\sum_{i=1}^{m}\left [(a_{0}+a_{1}x_{i}+a_{2}x_{i}^{2}+...+a_{n}x_{i}^{n})-y_{i}\right]x_{i}^{2}=0\\ ...\\ \frac{\partial \epsilon }{\partial a_{n}}=2\sum_{i=1}^{m}\left [(a_{0}+a_{1}x_{i}+a_{2}x_{i}^{2}+...+a_{n}x_{i}^{n})-y_{i}\right]x_{i}^{n}=0 \end{matrix}\right.

展开累加符号得(省略累加符号的上下限):

\left\{\begin{matrix} a_{0}n+a_{1}\sum x_{i}+a_{2}\sum x_{i}^{2}+...+a_{n}\sum x_{i}^{n}=\sum y_{i}\\ a_{0}\sum x_{i}+a_{1}\sum x_{i}^{2}+a_{2}\sum x_{i}^{3}+...+a_{n}\sum x_{i}^{n+1}=\sum x_{i}y_{i}\\ a_{0}\sum x_{i}^{2}+a_{1}\sum x_{i}^{3}+a_{2}\sum x_{i}^{4}+...+a_{n}\sum x_{i}^{n+2}=\sum x_{i}^{2}y_{i}\\ ...\\ a_{0}\sum x_{i}^{n}+a_{1}\sum x_{i}^{n+1}+a_{2}\sum x_{i}^{n+2}+...+a_{n}\sum x_{i}^{2n}=\sum x_{i}^{k}y_{i} \end{matrix}\right.

写成矩阵相乘的形式:

Ax=b

其中

A=\begin{bmatrix} n & \sum x_{i}& \sum x_{i}^{2} & ... & \sum x_{i}^{n} \\ \sum x_{i} & \sum x_{i}^{2}& \sum x_{i}^{3} & ... & \sum x_{i}^{n+1} \\ \sum x_{i}^{2} & \sum x_{i}^{3}& \sum x_{i}^{4} & ... & \sum x_{i}^{n+2} \\ ...& ...& ...& ...& ...\\ \sum x_{i}^{n} & \sum x_{i}^{n+1}& \sum x_{i}^{n+2} & ... & \sum x_{i}^{2n} \end{bmatrix}

x=\begin{bmatrix} a_{0}\\ a_{1}\\ a_{2}\\ ...\\ a_{n} \end{bmatrix}

b=\begin{bmatrix} \sum y_{i}\\ \sum x_{i}y_{i}\\ \sum x_{i}^{2}y_{i} \\ ...\\ \sum x_{i}^{k}y_{i} \end{bmatrix}

A、b可根据样本数据集计算得到,然后使用高斯列主元消元法解线性方程组,得到x

计算A、b的C++代码

void polyfit(const T* x,const T* y,size_t length,int poly_n)
		{
			//将最优化偏导数的方程组写为矩阵乘法形式:Ax=b,其中A、b可根据待拟合的点集坐标计算得到,x为最终待求的多项式系数矩阵
			//利用高斯列主元消元法来求解Ax=b
			//3阶多项式f(x)=ax^3 + bx^2 + cx^1 + dx^0,可见n阶多项式,具有n+1个待求系数,需要n+1个方程组才能解出
			std::vector<double> factor;
            factor.resize(poly_n+1,0);
			int i,j;
			//求x加和的相关项(系数矩阵中有重复项)
			std::vector<double> tempx(length, 1.0);
			std::vector<double> sumxx(poly_n * 2 + 1);
			for (i=0;i<2*poly_n+1;i++){
				for (sumxx[i]=0,j=0;j<length;j++)
				{
					sumxx[i]+=tempx[j];
					tempx[j]*=x[j];
				}
			}
			//根据重复项规律求matrix_A
			std::vector<double> matrix_A((poly_n + 1)*(poly_n + 1));
			for (i=0;i<poly_n+1;i++)
				for (j=0;j<poly_n+1;j++)
					matrix_A[i*(poly_n+1)+j]=sumxx[i+j];
			//求y加和的相关项matrix_b
			std::vector<double> tempy(y, y + length);//通过y中0到length-1个元素初始化向量
			std::vector<double> matrix_b(poly_n + 1);
			for (i = 0; i < poly_n + 1; i++) {
				for (matrix_b[i] = 0, j = 0; j < length; j++)
				{
					matrix_b[i] += tempy[j];
					tempy[j] *= x[j];
				}
			}
			//求多项式系数x,用变量factor代替
			gauss_solve(poly_n+1, matrix_A, factor, matrix_b);
		}

高斯列主元消元法计算x的c++代码

		template<typename T>
		void gauss_solve(int n
			, std::vector<typename T>& A
			, std::vector<typename T>& x
			, std::vector<typename T>& b)
		{
			GaussElimination(n, &A[0], &x[0], &b[0]);
		}
		template<typename T>
		void GaussElimination(int n, T* A, T* x, T* b)
		{
			int i, j, k;         //索引
			int r;               //主元所在行数
			double maxValue;     //当前列中绝对值最大的值,即列主元
			double factor;       //消元系数
			double temp;         //临时变量

			//逐列进行消元
			for (k = 0; k < n - 1; k++)
			{
				//获取列主元所在行数r
				r = k;
				maxValue = fabs(A[k*n + k]);
				for (i = k + 1; i < n; i++)
				{
					if (maxValue < fabs(A[i*n + k]))
					{
						maxValue = fabs(A[i*n + k]);
						r = i;
					}
				}

				//交换行元素,当r == k时,不需要交换
				if (r != k)
				{
					//交换等号左侧系数矩阵的行元素
					for (i = 0; i < n; i++)
					{
						temp = A[k*n + i];
						A[k*n + i] = A[r*n + i];
						A[r*n + i] = temp;
					}
					//交换等号右侧向量的行元素
					temp = b[k];
					b[k] = b[r];
					b[r] = temp;
				}
				//cout << "第" << k + 1 << "次选取主元并交换行的顺序" << endl;
				//DispalyMatrix(n, (double*)A, b);

				//按列消元过程
				for (i = k + 1; i < n; i++)
				{
					factor = A[i*n + k] / A[k*n + k];
					for (j = k+1; j < n; j++) //j = k时更便于观察结果,但是出现冗余计算
					{
						A[i*n + j] = A[i*n + j] - factor * A[k*n + j];
					}
					b[i] = b[i] - factor * b[k];
				}
				//cout << "第" << k + 1 << "次消元" << endl;
				//DispalyMatrix(n, (double*)A, b);
			}

			//判断系数矩阵的奇异性
			if (A[k*n + k] < 0.0001)
			{
				//cout << "系数矩阵是非奇异矩阵,方程无唯一解!" << "\n";
			}

			//回代法,将消元后的上三角矩阵变为单位矩阵,b即为系数
			for (i = n - 1; i >= 0; i--)
			{
				temp = 0;
				for (j = i + 1; j < n; j++)
				{
					temp = temp + A[i*n + j] * b[j];
				}
				b[i] = (b[i] - temp) / A[i*n + i];
				x[i] = b[i];
			}

			//cout << "回代计算后的矩阵:" << "\n";
			//for (i = 0; i < n; i++)
			//{
			//	for (j = 0; j < n; j++)
			//	{
			//		if (i == j)
			//			A[i*n + j] = 1;
			//		else
			//			A[i*n + j] = 0;
			//	}
			//}
			//DispalyMatrix(n, (double*)A, b);
			//cout << "最后得方程的根为:" << "\n";
			//for (i = 0; i < n; i++)
			//	cout << "x" << i + 1 << "=" << b[i] << "\n";
		}
		//void DispalyMatrix(int n, const double *A, const double *b)
		//{
		//	int i, j;
		//	for (i = 0; i < n; i++)
		//	{
		//		for (j = 0; j < n; j++)
		//			cout << setw(4) << setprecision(4) << *(A + i * n + j) << "   ";
		//		cout << b[i] << endl;
		//	}
		//	cout << endl;
		//}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/100746.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode_BFS_DFS_简单_1971.寻找图中是否存在路径

目录1.题目2.思路3.代码实现&#xff08;Java&#xff09;1.题目 有一个具有 n 个顶点的 双向 图&#xff0c;其中每个顶点标记从 0 到 n - 1&#xff08;包含 0 和 n - 1&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 u…

MR案例(2):学生排序(单字段排序、多字段排序)

文章目录一、任务目标1. 准备数据二、实行任务1. 创建Maven项目2. 添加相关依赖3. 创建日志属性文件4. 创建学生实体类5. 创建学生映射器类6. 创建学生归并器类7. 创建学生驱动类8. 启动学生驱动器类&#xff0c;查看结果一、任务目标 MR案例&#xff1a;学生排序&#xff08;…

【C++】继承与面向对象设计

目录 一、确保public继承塑模出is-a关系 二、避免隐藏继承而来的名称 三、区分接口继承和实现继承 四、考虑virtual函数以外的其他选择 五、不要重新定义继承而来的non-virtual函数 六、不要重新定义继承而来的缺省参数 七、尽量使用复合塑模出has-a 总结 一、确保publ…

【MySQL】Innodb存储引擎之物理存储结构(MySQL专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

云服务器安装jdk

第一步使用工具连接自己的服务器 连接成功后 在左侧选择需要上传的文件到opt目录 在云服务器的命令行操作界面输入指令 解压&#xff0c;输入jdk按table键自动补全 tar -zxvf 配置环境变量 vim /etc/profile 修改环境变量&#xff08;具体视安装 java 地址修改&#xff09; …

计算机毕设Python+Vue学生实验报告管理系统(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

jQuery 介绍

文章目录jQuery 介绍介绍下载安装jQuery 介绍 介绍 jQuery本身就是用JavaScript来写的&#xff0c;它只是把JavaScript中最常用的功能封装起来&#xff0c;以方便开发者快速开发。遥想当年&#xff0c;jQuery的创始人John Resig就是受够了JavaScript的各种缺点&#xff0c;所…

微服务框架 SpringCloud微服务架构 服务异步通讯 51 死信交换机 51.1 初识死信交换机

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯51 死信交换机51.1 初识死信交换机51.1.1 初识死信交换机51.1.2 总结51 死信交换机 51.1 初识…

java 多线程 上

目录 基本概念 线程的创建和使用 Thread类 API中创建线程的两种方式 Thread类的有关方法 线程的调度 线程的优先级 总结 基本概念 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码&#xff0c;静态对象。 进程(process)是程…

TapTap 算法平台的 Serverless 探索之路

作者&#xff1a;陈欣昊 Serverless 在构建应用上为 TapTap 节省了大量的运维与开发人力&#xff0c;在基本没投入基建人力的情况下&#xff0c;直接把我们非常原始的基建&#xff0c;或者说是资源管理水平拉到了业界相对前沿的标准。最直观的数据是&#xff0c;仅投入了个位数…

代码随想录Day55|392.判断子序列、115.不同的子序列

文章目录392.判断子序列115.不同的子序列392.判断子序列 文章讲解&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff1a;392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。…

koa 使用

&#xff08;贴个官网&#xff0c;koa 内容真不多&#xff0c;非常的小巧轻量&#xff09; 1. koa 是什么 一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用&#xff0c;通过组合不同的 generator&#xff0c;可以免除重复繁琐的回调函数嵌套&#xff0c;…

关于新正方教务系统(湖北工程学院)的one day越权漏洞的说明

关于正方教务系统漏洞的说明 此漏洞基于湖北工程学院教务管理系统进行演示&#xff0c;漏洞覆盖新正方教务系统8.0以下版本&#xff0c;为本人一年前提交的漏洞&#xff0c;所以并非0day漏洞 此漏洞影响范围巨大&#xff0c;几乎涉及国内一半高校的教务系统&#xff0c;包含武…

我国油气行业勘探开发投入提升 石油资源存在供需短缺矛盾 天然气需求高速发展

根据观研报告网发布的《2022年中国油气市场分析报告-市场竞争策略与发展动向前瞻》显示&#xff0c;油气是指石油和伴生的天然气&#xff0c;被誉为“能源之王”、“工业的血液”&#xff0c;是全世界各国的战略性产业。油气资源种类多样&#xff0c;根据开采难度可分为两大类&…

Python:三方库安装路径及路径变更

文章目录一、安装三方库的几种方式二、指定第三方库的镜像源三、查看安装默认路径四、修改安装默认路径五、查看安装的库六、导出库安装文件七、安装小结一、安装三方库的几种方式 1.直接pip install安装&#xff08;有网的环境下通用&#xff09; &#xff1a; 在python–>…

CSDN上讲得最好的——Linux权限

目录 一、shell原理精讲 二、Linux权限概念 三、权限管理 1、访问者分类 2、文件类型及访问权限 3、表示方法 4、设置方法 &#xff08;1&#xff09;chmod (2)chown (3)chgrp (4)umask 四、目录权限 五、粘滞位 一、超级管理员删除 二、该目录的所有者删除 三、…

GDAL之重投影(详细篇)

一、空间坐标系对应EPSG编号 二、通用横向墨卡托(UTM)投影坐标系和WGS84地理坐标系转换 一、目标地区的编号查看(中国东部地区属于UTM Zone 50N) 从180“W开始&#xff0c;有60个纵向投影区&#xff0c;编号为1到60。除了挪威和斯瓦尔巴群岛附近的一些例外&#xff0c;每个区…

【毕业设计_课程设计】基于 U-Net 网络的遥感图像语义分割(源码+论文)

文章目录0 项目说明1 研究目的2 研究方法3 研究结论4 论文目录5 项目工程0 项目说明 **基于 U-Net 网络的遥感图像语义分割 ** 提示&#xff1a;适合用于课程设计或毕业设计&#xff0c;工作量达标&#xff0c;源码开放 实验训练使用 Anaconda 版 Python 3.7 下的 TensorFlo…

OpenSSL BIO源码简析

文章目录1. BIO简介BIO chainBIO数据结构BIO_METHOD数据结构2. Base64示例分析初始化构造BIO链写数据free1. BIO简介 相关文档 /html/man7/bio.html /html/man3/BIO_*.htmlbio - Basic I/O abstraction&#xff0c;即IO抽象层。 BIO有两种: source/sink BIO&#xff0c;即数…

win7系统升级IE11,打补丁KB2729094失败解决办法

因银行这边很多都需要IE11版本&#xff0c;但win7系统大部分需要打一些补丁才能安装。其他补丁都打上了&#xff0c;唯独这个KB2729094一直失败&#xff0c;搞得很无语。还好找到可以直接用命令安装。就不需要打这个补丁了&#xff0c;直接安装使用即可。 1、下载IE11离线安装…