[数值计算-15]:函数近似值的线性与非线性拟合的原理与Python代码示例

作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119973082


目录

第1章 什么是函数逼近?

1.1 抛出问题1:函数插值

1.2  抛出问题2:函数拟合

1.3  什么是回归

第2章 函数拟合

2.1 插值有时候插值并不是最好的选择

2.2 什么函数拟合

 2.2 函数拟合的基本步骤

第3章 最小二乘法

3.1 什么是最小二乘法

3.2 线性拟合函数的最小二乘法的几何意义

3.3 最小二乘算法实现

第4章 线性(直线)拟合的Python代码示例

4.0 前置条件:

4.1 步骤1:构建样本数据集

4.2 步骤2:构建拟合函数

4.3 步骤3:构建最小二乘的残差函数,并计算最佳参数(最关键步骤)

4.4 步骤4:利用拟合函数进行数据预测

4.5 步骤5:图形展示

第5章 非线性(二次抛物线)拟合的Python代码示例

 5.0 前置条件:

5.1 步骤1:构建样本数据集

5.2 步骤2:构建拟合函数

5.3 步骤3:构建最小二乘的残差函数,并计算最佳参数(最关键步骤)

5.4 步骤4:利用拟合函数进行数据预测

5.5 步骤5:图形展示

待续:最小二乘算法的实现



第1章 什么是函数逼近?

1.1 抛出问题1:函数插值

利用有限的样本数据,发现其内在的规律,并用这个规律预测未来新的数据。

(1)单个数据点

  • 0次函数通过样本点:唯一确定一个点 y = f(x) = a0
  • 1次直线函数通过样本点:可以有无数 y = f(x) = a1x + a0
  • 2次抛物线函数通过样本点:可以有无数 y = f(x) = a1x^2 + a1x + a0

(2)2个数据点

  • 0次函数通过样本点:无
  • 1次直线函数通过样本点:唯一直线 y = f(x) = a1x + a0
  • 2次抛物线函数通过样本点:可以有无数 y = f(x) = a1x^2 + a1x + a0

(3)3个数据点

  • 0次函数通过样本点:无
  • 1次直线函数通过样本点:无
  • 2次抛物线函数通过样本点:唯一抛物线y = f(x) = a1x^2 + a1x + a0

问题:

如果有(xn+1,yn+1), (xn,yn)........(x1,y1), (x0,y0)样本点,那么如何选择一个最低次的多项式函数,可以穿过上述样本点?

推测:

对应n+1个点,可以唯一的确定一个一元n次的多项式函数,该多项式函数可以穿越所有n+1个点。

1.2  抛出问题2:函数拟合

如果有n个点,不要求选出的函数穿越所有的点,而是根据这些点构建的轮廓,选择一个更低维度(次数)的函数尽可能的靠近这些样本点呢?

 当函数的次数远远小于样本点的次数是,该如何选择低次的函数?

1.3  什么是回归

回归与拟合是基本相同的概念。线性拟合通常称为线性回归。

第2章 函数拟合

2.1 插值有时候插值并不是最好的选择

(1)简单直线拟合好于多项式拟合

在上图图有,有几十个样本点,如果用多项式插值来进行函数逼近,虽然插值函数在样本点的误差为0,但很显然,需要高次多项式来进行逼近。

如果样本点有几百个,那么多项式的次数高达几百次。

从图中可以大致看出,要逼近上述样本点,只需要一个简单的线性函数即可:y=ax+b,这种函数逼近称为拟合。

(2)抛物线逼近

同理,对上述样本点的逼近,也不需要几十次的多项式进行插值,值需要一个简单的抛物线就可以进行逼近:y =ax^2 + bx + c,,这种函数逼近称为拟合。

(3)三角函数拟合

2.2 什么函数拟合

 

 2.2 函数拟合的基本步骤

步骤1:构建样本

(1)读取已有样本数据,并图形展示样本数据。或者

(2)构建自行测试样本数据

(3)图形化展示样布数据(散点图)

步骤2:选择函数模型

根据散点图,选择函数类,函数类可以从初等函数中进行选取,如线性函数、二次或多次多项式函数、三角函数等。

步骤3: 构建最小二乘的残差函数,并计算最佳参数(最关键步骤)

(1)选择最佳拟合的范数(这里选择最小二乘法)

选取了函数类型后,每个函数都有自己的待定参数,不同的参数,其拟合效果是不同的,如何选择函数的参数,使得拟合效果最好呢?常有的有最小二乘法。

最小二乘法是函数拟合最重要的环节之一。

(2)计算最佳参数(这是最关键、最核心的步骤

最小二乘法得到的loss残差函数是一个多元二次多项式函数:

  • 残差函数的“元”的个数,就是拟合函数的参数
  • 残差函数的“元”的次数:2次
  • 拟合最好的依据:多元函数的最小值点处的各个变量值,就是拟合函数最好的参数。

求解多元二次多项式函数的方法有多种:

  • 法向量解线性方程组法
  • 梯度下降法

无论哪种方法,都是通过求残差函数的最小值,基于指定样本数据,获得了最佳参数的拟合函数。

步骤4:利用拟合函数进行数据预测

生成一组输入数据,利用第4步获得的拟合函数的参数以及对应的拟合函数,对数据进行函数运算(预测),得到新的输出数据。

步骤5:图形展示

把预测数据与采样数据、理论曲线一起进行图形展示。

第3章 最小二乘法

3.1 什么是最小二乘法

 

3.2 线性拟合函数的最小二乘法的几何意义

注意: 

最小二乘选择一个适当的直线参数,使得所有样本点处的yi - f(xi) = yi -(axi+b)的平方和的平均值最小,而不是所有样本点到拟合直线的距离的和的平均值最小。

这样选择,主要处于如下原因:

(1)计算简单:求点到拟合曲线的距离要比直接计算样本点处的Y值的差复杂很多。

(2)符合拟合函数原本的物理意义:拟合函数要在所有的样本点xi处,其f(xi)也尽可能的相等,或者说误差尽可能的小。

3.3 最小二乘算法实现

(1)最小二乘法求解1:“法向量”线性方程组求解法

(2)最小二乘法求解2:梯度下降法

可以直接利用scipy库提供的最小二乘的的算法,来根据样本数据计算拟合函数的参数。

from scipy import optimize      #最小二乘算法的算法库

optimize.curve_fit(f, x_data, y_data)

输出:

  • 拟合函数
  • x_data:样本数据的x值
  • y_data:样本数据的y值

输出:

  • 拟合的参数
  • 误差大小

第4章 线性(直线)拟合的Python代码示例

4.0 前置条件:

#导入库
from math import *
import time
import numpy as np
import matplotlib.pyplot as plt #画图工具
from pylab import mpl           #中文字体
from scipy import optimize      #最小二乘算法的算法库

4.1 步骤1:构建样本数据集

#步骤1:构建样本

#(1) 采用np, 直接手工生成样本的输入:一组等距离的分布在[-1,1]之间的100个点
sample_numbers = 50

x_data = np.linspace(0, 1, sample_numbers)

#(2) 为这些数据手工打上理论输出值(标签值):y = 2x + 1
y_data_pure =  2 * x_data + 1.0

#(3)为了模拟现实情况,通过随机数来模拟数据噪声
noise_range = 0.4
np.random.seed(10) #设置随机种子, 确保不同时候,执行结果是相同的
#randn(n)生成的0为均值,1为标准差的正态分布的n个随机数。
y_noise = np.random.randn(*x_data.shape) * noise_range  # *x_data.shape:输入样本的维度或个数

#(4)人工生成样本的输出:理论值 + 噪声
y_data_noise = y_data_pure + y_noise

#(5) 显示样本数据
# 样本的散点图
plt.scatter(x_data, y_data_noise, label="sample", color="black")

# 内在的、理论的曲线图
plt.plot(x_data, y_data_pure, label="f_pure(x)", color="blue", linewidth = 4)

#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("线性拟合")
plt.legend(loc="upper left")
plt.show()

 

4.2 步骤2:构建拟合函数

#步骤2:构建拟合函数:二元一次拟合函数, x变量,w是常量
def f_line_w(x, w):
    return (w*x + 1)

4.3 步骤3:构建最小二乘的残差函数,并计算最佳参数(最关键步骤)

#步骤3: 计算拟合参数
print("利用python库提供的最小二乘算法来计算拟合函数的参数")
print("无噪声数据:")
popt, pcov = optimize.curve_fit(f_line_w, x_data, y_data_pure)
print(popt)
print(pcov)
print("参数w=", popt[0])

print("\n有噪声数据:")
popt, pcov = optimize.curve_fit(f_line_w, x_data, y_data_noise)
print(popt)
print(pcov)
print("参数w=", popt[0])

w_scipy =  popt[0]
利用python库提供的最小二乘算法来计算拟合函数的参数
无噪声数据:
[2.]
[[0.]]
参数w= 2.0

有噪声数据:
[2.03981828]
[[0.00794081]]
参数w= 2.03981827977079

备注说明:

这里利用python库提供的最小二乘算法来计算拟合函数的参数。

因此没有展现用数值的方法求最小二乘最佳参数的过程。

4.4 步骤4:利用拟合函数进行数据预测

# 步骤4:利用获得的拟合函数进行数据预测

# scipy 算法的拟合数据
y_data_scipy = f_line_w(x_data, w_scipy)

4.5 步骤5:图形展示

#步骤5: 图形化展示
#(1) 显示样本数据曲线
plt.scatter(x_data, y_data_noise, label="sample", color="black")

#(2) 显示理论数据曲线
plt.plot(x_data, y_data_pure, label="intrinsic", color="blue", linewidth = 2)

#(3-1) 显示预测数据曲线 - scipy库实现
plt.plot(x_data, y_data_scipy,  label="predict",  color="red",  linewidth = 2)


#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("线性拟合")
plt.legend(loc="upper left")
plt.show()

 

第5章 非线性(二次抛物线)拟合的Python代码示例

 5.0 前置条件:

#导入库
from math import *
import time
import numpy as np
import matplotlib.pyplot as plt #画图工具
from pylab import mpl           #中文字体
from scipy import optimize      #最小二乘算法的算法库

5.1 步骤1:构建样本数据集

#步骤1:构建样本

#(1) 采用np, 直接手工生成样本的输入:一组等距离的分布在[-1,1]之间的100个点
sample_numbers = 30

x_data_new = np.linspace(-2, 4, sample_numbers)

#(2) 为这些数据手工打上理论输出值(标签值)
a_intrinsic = 1.0
b_intrinsic = -2.0
c_intrinsic = 1.0
y_data_pure_new =  a_intrinsic*x_data_new**2 + b_intrinsic*x_data_new + c_intrinsic

#(3)为了模拟现实情况,通过随机数来模拟数据噪声
noise_range = 0.4
np.random.seed(10) #设置随机种子, 确保不同时候,执行结果是相同的
#randn(n)生成的0为均值,1为标准差的正态分布的n个随机数。
y_noise_new = np.random.randn(*x_data_new.shape) * noise_range  # *x_data.shape:输入样本的维度或个数

#(4)人工生成样本的输出:理论值 + 噪声
y_data_noise_new = y_data_pure_new + y_noise_new

#(5) 显示样本数据
# 样本的散点图
plt.scatter(x_data_new, y_data_noise_new, label="sample", color="black")

# 内在的、理论的曲线图
plt.plot(x_data_new, y_data_pure_new, label="f_pure(x)", color="blue", linewidth = 4)

#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("线性拟合")
plt.legend(loc="upper left")
plt.show()

 

5.2 步骤2:构建拟合函数

#步骤2:构建拟合函数:二元一次拟合函数
def f_quadratic(x, a, b, c):
    return (a*x**2 + b*x + c)

5.3 步骤3:构建最小二乘的残差函数,并计算最佳参数(最关键步骤)

#步骤3:利用python库提供的最小二乘算法来计算拟合函数的参数
rst = optimize.curve_fit(f_quadratic, x_data_new, y_data_noise_new)
print(rst)

a, b,c = rst[0]
print("参数a=", a)
print("参数b=", b)
print("参数c=", c)
(array([ 1.02865517, -2.02758343,  0.98623065]), array([[ 0.00073372, -0.00146745, -0.00161925],
       [-0.00146745,  0.00481099,  0.0013624 ],
       [-0.00161925,  0.0013624 ,  0.01146607]]))
参数a= 1.0286551700726068
参数b= -2.027583425950391
参数c= 0.9862306473484475

备注说明:

这里利用python库提供的最小二乘算法来计算拟合函数的参数。

因此没有展现用数值的方法求最小二乘最佳参数的过程。

5.4 步骤4:利用拟合函数进行数据预测

# 步骤4:利用获得的拟合函数进行数据预测
y_data_fit_new = f_quadratic(x_data_new, a, b, c)

5.5 步骤5:图形展示

#步骤5: 图形化展示
#(1) 显示样本数据曲线
plt.scatter(x_data_new, y_data_noise_new, label="sample", color="black")

#(2) 显示理论数据曲线
plt.plot(x_data_new, y_data_pure_new, label="intrinsic", color="blue", linewidth = 2)

#(3) 显示预测数据曲线
plt.plot(x_data_new, y_data_fit_new,  label="predict",  color="red",  linewidth = 2)

#设置属性
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.title("非线性拟合")
plt.legend(loc="upper left")
plt.show()

 

待续:最小二乘算法的实现


作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119973082

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中进行非线性回归时,可以利用三角函数来建模数据。可以使用NumPy库中的sin()、cos()、tan()等函数来创建三角函数的特征。具体步骤如下: 1. 导入所需的库:首先,需要导入NumPy库来进行数值计算和创建三角函数特征。可以使用以下代码导入库: ``` import numpy as np ``` 2. 准备数据:准备包含自变量和因变量的数据集。 3. 创建三角函数特征:使用NumPy库的三角函数函数(如sin()、cos()、tan())来创建三角函数特征。可以根据需要选择适当的三角函数。 4. 构建模型:使用回归算法(如线性回归、多项式回归)来构建非线性回归模型。可以使用scikit-learn库中的线性回归模型或多项式回归模型来实现。 ``` from sklearn.linear_model import LinearRegression ``` 或 ``` from sklearn.preprocessing import PolynomialFeatures ``` 5. 训练模型:将数据集拟合到模型中,以获取最佳的参数。 6. 预测:使用训练好的模型来进行预测未知数据的类别。 请注意,以上只是非线性回归中使用三角函数的一种方法,具体的实现取决于数据集的特征和需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [机器学习笔记-线性回归与非线性回归](https://blog.csdn.net/m0_56615545/article/details/128054414)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [[数值计算-15]:函数近似值线性非线性拟合原理Python代码示例](https://blog.csdn.net/HiWangWenBing/article/details/119973082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文火冰糖的硅基工坊

你的鼓励是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值