最小二乘法的曲线拟合

最小二乘法解决的问题:Ax=C 无解下的最优解
例子1:
一条过原点的直线OA,C是直线外一点,求C在OA上的投影点P

例子1

 

例子2:
已知三个不在一条直线上的点A,B,C,求一条直线,使A,B,C到直线的距离和最小

例子2

 

例子3:
已知三个不在一条直线上的点A,B,C,求一点,到A,B,C的距离和最小

例子3

其实这3个例子的本质都是一样的。都是求未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。
以第一个例子为例:

                             Ax=C  无解要求||Ax-C||^2最小A.TAx'=A.TCx'=(A.TA)^(-1)A.TCP=Ax'

公式推导

 

同理,例子2,3中都需要写成Ax=C 的形式,求最优解。
只是例子2中的最优解是直线y=ax+b中的a,b。例子3中的最优解是P的坐标P(xp,yp)。
使用程序求例子1:A(3,1),C(1,3)
CODE

import numpy as np 
from matplotlib import pyplot as pltA = np.array([[3],[1]])
C = np.array([[1],[3]])#x'=(A.TA)^(-1)A.TC
B = A.T.dot(C)
AA = np.linalg.inv(A.T.dot(A))#求A.T.dot(A)的逆
l=AA.dot(B)
#P=Ax'
P=A.dot(l)x=np.linspace(-2,2,10)#x.shape=(10,)
x.shape=(1,10)
#画出直线y=ax
xx=A.dot(x)
fig = plt.figure() #figsize=(10,6)
ax= fig.add_subplot(111)
ax.plot(xx[0,:],xx[1,:])
#画出A点
ax.plot(A[0],A[1],'ko')
#画出C点,P点
ax.plot([C[0],P[0]],[C[1],P[1]],'r-o')
#画出OC线
ax.plot([0,C[0]],[0,C[1]],'m-o')#画出坐标轴x=0,y=0
ax.axvline(x=0,color='black')
ax.axhline(y=0,color='black')#标写每个点的字母
margin=0.1
ax.text(A[0]+margin, A[1]+margin, r"A",fontsize=20)
ax.text(C[0]+margin, C[1]+margin, r"C",fontsize=20)
ax.text(P[0]+margin, P[1]+margin, r"P",fontsize=20)
ax.text(0+margin,0+margin,r"O",fontsize=20)
ax.text(0+margin,4+margin, r"y",fontsize=20)
ax.text(4+margin,0+margin, r"x",fontsize=20)
plt.xticks(np.arange(-2,3))
plt.yticks(np.arange(-2,3))ax.axis('equal')
plt.show()

结果:

 

最小二乘法 拟合曲线

1.直线拟合

 

直线拟合


已知图中拟合数据的坐标,对图中的拟合数据进行直线拟合。
依旧使用最小二乘法求解
Ax=b——————1
无解下的最优解。已知点的个数为n,所求直线的方程为y1=ax1+b,A由方程右边的a,b的系数构成构成(nx2)的矩阵,每行为(x1,1),b由已知点的y1坐标构成矩阵(nx1)。方程1中的x为要求的列向量[a,b]。
A.TAx'=A.Tb
x'=(A.TA)^(-1)A.TC
求得x‘后,画出拟合曲线的yy=Ax'

 

import numpy as np  
import matplotlib.pyplot as plt  #x的个数决定了样本量
x = np.arange(-1,1,0.02) 
#y为理想函数 
y = 2*np.sin(x*2.3)+0.5*x**3
#y1为离散的拟合数据
y1 = y+0.5*(np.random.rand(len(x))-0.5)##################################
#主要程序
one=np.ones((len(x),1))#len(x)得到数据量
x=x.reshape(x.shape[0],1)
A=np.hstack((x,one))#两个100x1列向量合并成100x2,(100, 1) (100,1 ) (100, 2)
C=y1.reshape(y1.shape[0],1)
#等同于C=y1.reshape(100,1)
#虽然知道y1的个数为100但是程序中不应该出现人工读取的数据def optimal(A,b):B = A.T.dot(b)AA = np.linalg.inv(A.T.dot(A))#求A.T.dot(A)的逆P=AA.dot(B)print Preturn A.dot(P)#求得的[a,b]=P=[[  2.88778507e+00] [ -1.40062271e-04]]
yy = optimal(A,b)
#yy=P[0]*x+P[1]
##################################
plt.plot(x,y,color='g',linestyle='-',marker='',label=u'理想曲线') 
plt.plot(x,y1,color='m',linestyle='',marker='o',label=u'拟合数据')
plt.plot(x,yy,color='b',linestyle='-',marker='.',label=u"拟合曲线") 
# 把拟合的曲线在这里画出来
plt.legend(loc='upper left')
plt.show()

直线拟合结果

 

从结果中可以看出,直线拟合并不能对拟合数据达到很好的效果,下面我们介绍一下曲线拟合。

2.曲线拟合

 

曲线拟合


图中的拟合数据如果用直线进行拟合效果会更差,曲线能更好的表达数据的特征。这里我们使用多项式函数进行拟合。
拟合函数:
y=axn+bx(n-1)+cx^(n-2)+...+d
假设拟合数据共有100个
Ax=b
A=[x1^n x1^(n-1) x1^(n-2) ...... 1]
[x2^n x2^(n-1) x2^(n-2) ...... 1]
......
[x100^n x100^(n-1) x100^(n-2) . 1]

 

b=[y1]
[y2]
......
[y100]

解得拟合函数的系数[a,b,c.....d]
CODE:

import numpy as np  
import matplotlib.pyplot as plt  x = np.arange(-1,1,0.02)  
y = ((x*x-1)**3+1)*(np.cos(x*2)+0.6*np.sin(x*1.3))y1 = y+(np.random.rand(len(x))-0.5)##################################
### 核心程序
#使用函数y=ax^3+bx^2+cx+d对离散点进行拟合,最高次方需要便于修改,所以不能全部列举,需要使用循环
#A矩阵
m=[]
for i in xrange(7):#这里选的最高次为x^7的多项式a=x**(i)m.append(a)
A=np.array(m).T
b=y1.reshape(y1.shape[0],1)##################################def projection(A,b):AA = A.T.dot(A)#A乘以A转置w=np.linalg.inv(AA).dot(A.T).dot(b)print w#w=[[-0.03027851][ 0.1995869 ] [ 2.43887827] [ 1.28426472][-5.60888682] [-0.98754851][ 2.78427031]]return A.dot(w)yw = projection(A,b)
yw.shape = (yw.shape[0],)plt.plot(x,y,color='g',linestyle='-',marker='',label=u"理想曲线") 
plt.plot(x,y1,color='m',linestyle='',marker='o',label=u"已知数据点")
plt.plot(x,yw,color='r',linestyle='',marker='.',label=u"拟合曲线")
plt.legend(loc='upper left')
plt.show()

结果

 

根据结果可以看到拟合的效果不错。
我们可以通过改变

  • 拟合函数类型
  • 样本数(此处为x的个数)

来调整拟合效果。
如果此处我们把拟合函数改为最高次为x^20的多项式

m=[]
for i in xrange(20):a=x**(i)m.append(a)

所得结果如下:

 

x^20 样本数100


这种现象称为过拟合现象

 

  • 可以通过增加样本数数,
  • 降低拟合函数的次数

矫正过拟合现象
在保持拟合函数改为最高次为x^20的多项式的条件下,增大样本数:

x = np.arange(-1,1,0.005) #原来是x = np.arange(-1,1,0.02)  

x^20 样本数400

通过结果可以看出,过拟合现象得到了改善。

 

 

概念

最小二乘法多项式曲线拟合,根据给定的m个点,并不要求这条曲线精确地经过这些点,而是曲线y=f(x)的近似曲线y= φ(x)。

 

原理

[原理部分由个人根据互联网上的资料进行总结,希望对大家能有用]

     给定数据点pi(xi,yi),其中i=1,2,…,m。求近似曲线y= φ(x)。并且使得近似曲线与y=f(x)的偏差最小。近似曲线在点pi处的偏差δi= φ(xi)-y,i=1,2,...,m。 

常见的曲线拟合方法:

     1.使偏差绝对值之和最小

     

 

     2.使偏差绝对值最大的最小

     

 

     3.使偏差平方和最小

 

     

 

     按偏差平方和最小的原则选取拟合曲线,并且采取二项式方程为拟合曲线的方法,称为最小二乘法。

推导过程:

     1. 设拟合多项式为:

          

     2. 各点到这条曲线的距离之和,即偏差平方和如下:

          

     3. 为了求得符合条件的a值,对等式右边求ai偏导数,因而我们得到了: 

          

          

                         .......

          

 

     4. 将等式左边进行一下化简,然后应该可以得到下面的等式:

          

          

                     .......

          

 

     5. 把这些等式表示成矩阵的形式,就可以得到下面的矩阵:

          

     6. 将这个范德蒙得矩阵化简后可得到:

          

     7. 也就是说X*A=Y,那么A = (X'*X)-1*X'*Y,便得到了系数矩阵A,同时,我们也就得到了拟合曲线。

 

经验证 5,与 6 的 结果一致,所以 一般用 6的方式更简单。

 

 

验证代码:

# coding=utf-8'''
作者:Jairus Chan
程序:多项式曲线拟合算法
'''
import matplotlib.pyplot as plt
import math
import numpy
import randomfig = plt.figure()
ax = fig.add_subplot(111)# 阶数为9阶
order = 9# 生成曲线上的各个点
x = numpy.arange(-1, 1, 0.02)
y = [((a * a - 1) * (a * a - 1) * (a * a - 1) + 0.5) * numpy.sin(a * 2) for a in x]
# ax.plot(x,y,color='r',linestyle='-',marker='')
# ,label="(a*a-1)*(a*a-1)*(a*a-1)+0.5"# 生成的曲线上的各个点偏移一下,并放入到xa,ya中去
i = 0
xa = []
ya = []
for xx in x:yy = y[i]d = float(random.randint(60, 140)) / 100# ax.plot([xx*d],[yy*d],color='m',linestyle='',marker='.')i += 1xa.append(xx * d)ya.append(yy * d)'''for i in range(0,5):xx=float(random.randint(-100,100))/100yy=float(random.randint(-60,60))/100xa.append(xx)ya.append(yy)'''ax.plot(xa, ya, color='m', linestyle='', marker='.')# 进行曲线拟合  验证 5
matA = []
for i in range(0, order + 1):matA1 = []for j in range(0, order + 1):tx = 0.0for k in range(0, len(xa)):dx = 1.0for l in range(0, j + i):dx = dx * xa[k]tx += dxmatA1.append(tx)matA.append(matA1)print(len(matA))
print(len(matA[0]))
print(matA[0])
print(matA[1])
print(matA[2])# print(len(xa))
# print(matA[0][0])
matA = numpy.array(matA)matB = []
for i in range(0, order + 1):ty = 0.0for k in range(0, len(xa)):dy = 1.0for l in range(0, i):dy = dy * xa[k]ty += ya[k] * dymatB.append(ty)matB = numpy.array(matB)matAA = numpy.linalg.solve(matA, matB)print(matAA.shape)
# 画出拟合后的曲线
# print(matAA)
xxa = numpy.arange(-1, 1.06, 0.03)
yya = []
for i in range(0, len(xxa)):yy = 0.0for j in range(0, order + 1):dy = 1.0for k in range(0, j):dy *= xxa[i]dy *= matAA[j]yy += dyyya.append(yy)
ax.plot(xxa, yya, color='g', linestyle='', marker='.')# 多项式 拟合   验证 6
def projection(A, b):AA = A.T.dot(A)w = numpy.linalg.inv(AA).dot(A.T).dot(b)return warray_xa = numpy.array(xa)
array_ya = numpy.array(ya)m = []
for i in range(10):a = array_xa**(i)m.append(a)
A = numpy.array(m).T
b = array_ya.reshape(array_ya.shape[0], 1)w = projection(A, b)
print("w:", w.shape)
print("xxa", xxa.shape)
array_xxa = numpy.array(xxa)mm = []
for i in range(10):a = xxa**(i)mm.append(a)
AA = numpy.array(mm).T
print("AA:", AA.shape)new_y = AA.dot(w)
ax.plot(array_xxa, new_y, color='b', linestyle='-', marker='')# 5 曲线 与 6 曲线 重合。ax.legend()
plt.show()

运行效果:

 

 

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

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

相关文章

最小二乘法曲线拟合

最小二乘法曲线拟合以及Matlab实现 在实际工程中,我们常会遇到这种问题:已知一组点的横纵坐标,需要绘制出一条尽可能逼近这些点的曲线(或直线),以进行进一步进行加工或者分析两个变量之间的相互关系。而获…

chatgpt赋能python:Python中输出的完整指南

Python中输出的完整指南 在Python中进行编程,输出是至关重要的一部分。它可用于在命令行界面或Web应用程序中显示结果、数据操作等。Python具有各种输出方法,包括print语句,文件和日志记录。在本文中,我们将深入研究Python中输出…

机器视觉康耐视智能相机Insight-手眼标定详细步骤

(Q有答疑)康耐视VisionPro工具与脚本入门级系列教程2023 In-Sight 智能相机包含标定手眼的工具 CalibrateGrid,用手动的标定方式,即将康耐视标定片固定在运动平台上,然后手动输入电机位置坐标,要保证电机在 X 方向移动一次,Y 方向移动一次,旋转两次角度,切旋转角度差不能…

ChatGPT的4个不为人知却非常实用的小功能

今天重点介绍四个ChatGPT很实用的小功能。 一、停止生成 如果在ChatGPT输出内容的过程中,我们发现结果不是自己想要的,可以直接点击“Stop generating”按钮,这样它就会立即停止输出。 二、复制功能 在ChatGPT返回对话的右侧,有三…

SQL 插入带引号的字段

今天突然想了下给字段插入引号的SQL该怎样写,然后就百度了一下,结果看各位的结果真是云里雾里啊 ╮(╯▽╰)╭ 然后就自己本机测试了一下 O(∩_∩)O,三种数据库都可以 不知道我这样写有没有问题呢 ... 稍微介绍一下吧: 如果要向…

什么是IPSec?6000字带你详细剖析,很赞!

关注、星标公众号,精彩内容每日送达 来源:网络素材 1.IPSEC协议簇安全框架 a.IPSec简介 IPSec(Internet Protocol Security):是一组基于网络层的,应用密码学的安全通信协议族。IPSec不是具体指哪个协议&…

C++ set类成员函数介绍 (set和multiset)

目录 🤔set模板介绍: 🤔特点: 🤔set的成员函数: 😊set构造函数: 🔍代码实例: 🔍运行结果: 😊 set赋值函数&#xf…

MySQL之数据库基本查询语句

——————今天距2020年43天—————— 这是ITester软件测试小栈第80次推文 SELECT 基本查询语句 查询单个列 #查询Author表name列的值 select name from Author;查询多个列 #查询Author表id,name两列的值 select id,name from Author;查询所有列 #查询Author表所有列的信息…

泔水()

欢迎大家观看本人第一张博客 16340218 数据科学与计算机学院 目录 数学干货之不等式 均值不等式幂平均不等式柯西不等式琴生不等式证明不等式的小策略 函数法“暴力”积分法数学归纳法水货-大学感想 一、各类不等式 1.均值不等式 平方平均数 ≥ 算术平均数 ≥ 几何平均数…

【Mysql】mysql数据库的查询语句

单表查询 1、普通查询 &#xff08;1&#xff09;命令&#xff1a;select * from <表名>;//通匹 &#xff08;2&#xff09;命令&#xff1a;select <要查询的字段> from <表名>&#xff1b; 2、去重查询&#xff08;distinct&#xff09; 命令&#xff1a;…

Metasploit超详细安装及使用教程(图文版)

通过本篇文章&#xff0c;我们将会学习以下内容&#xff1a; 1、在Windows上安装Metasploit 2、在Linux和MacOS上安装Metasploit 3、在Kali Linux中使用 Metasploit 4、升级Kali Linux 5、使用虚拟化软件构建渗透测试实验环境 6、配置SSH连接 7、使用SSH连接Kali 8、配…

基于深度学习的高精度汽车自行车检测识别系统(PyTorch+Pyside6+模型)

摘要&#xff1a;基于深度学习的高精度汽车自行车检测识别系统可用于日常生活中检测与定位汽车自行车目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的汽车自行车目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目…

Kotlin笔记(零)简介

百度百科简介 2017年&#xff0c;google公司在官网上宣布Kotlin成为Android的开发语言&#xff0c;使编码效率大增。Kotlin 语言由 JetBrains 公司推出&#xff0c;这是一个面向JVM的新语言 参考资料 官网&#xff1a;https://kotlinlang.org/中文官网&#xff1a;https://w…

【测试基础02】

测试基础02 一、HTML基础二、Python导入三方模块三、安装webgrock驱动四、元素定位(1)、元素定位工具(2)、元素定位方式(3)、XPATH路径(3)、CSS选择器 五、Selenium WebDriver初步应用(1)、基本方法(2)、测试案例1(3)、测试案例2(3)、测试案例3 六、获取元素信息的方法七、fram…

黑马Redis视频教程实战篇(三)

目录 一、优惠券秒杀 1.1 全局唯一ID 1.2 Redis实现全局唯一ID 1.3 添加优惠卷 1.4 实现秒杀下单 1.5 库存超卖问题分析 1.6 代码实现乐观锁解决超卖问题 1.7 优惠券秒杀-一人一单 1.8 集群环境下的并发问题 二、分布式锁 2.1 基本原理和实现方式对比 2.2 Redis分布…

QQ截屏快速获取像素颜色

QQ截屏快速获取像素颜色 qq截屏的快捷键是 CTRL ALT A qq截屏除了截屏 还有个很不错的小功能 获取像素的颜色 是大家都容易忽略的 具体方法很简单 第一步 按下 Ctrl Alt A 快捷键 但是 不要点击鼠标 第二步 移动鼠标 到你想要像素点的颜色 如图所示 按C 即可复制 RGB十进…

计算机如何共享桌面,怎么共享电脑屏幕?

在平时的工作生活中&#xff0c;有的时候我们需要把自己的电脑屏幕共享到另一台电脑上&#xff0c;来方便给同事或者朋友演示一些操作。今天在这里给大家分享2个电脑屏幕共享的方法&#xff0c; 2种电脑屏幕共享的方法 幕享电脑投屏 幕享&#xff0c;英文名叫Letsview&#xff…

超简单友盟分享(微信、QQ)+ 原生微信分享

超简单友盟分享&#xff08;微信、QQ&#xff09; 原生微信分享 友盟分享&#xff08;微信、QQ&#xff09;原生微信分享QQ分享&#xff08;使用Android原生的api跳转QQ&#xff09; 友盟分享&#xff08;微信、QQ&#xff09; 之前写的项目好好的&#xff0c;后来打开就报这个…

手机端 html 怎么分享到朋友圈,【Web前端问题】移动web页面如何实现分享到微信、QQ等分享功能?...

移动web页面(浏览器打开的web应用&#xff0c;非App内置的Web页面)内有分享按钮&#xff0c;点击可分享到朋友圈&#xff0c;微信好友&#xff0c;QQ...... 据说是使用相关插件&#xff0c;求指导&#xff01; 回答&#xff1a; 如果不是app内置web页面,只能使用js的一键分享.具…

QQ空间说说批量删除

怎么批量删除QQ空间说说&#xff1f; 第一步&#xff1a;用电脑打开浏览器登录你的QQ空间 第二步&#xff1a;点击你的说说栏目 第三步&#xff1a;按下电脑的F12键或者点击右上角的菜单一栏&#xff0c;点击开发者工具 第四步&#xff1a;看到右半边屏幕&#xff0c;找到…