高斯-牛顿法求解最小二乘问题-python

拟合曲线

其中 a, b, c 为曲线的参数,w 为高斯噪声,满足 w ∼ (0, σ2 )。

问题本质就是求解下面的最小二乘问题以估计曲线参数:

拟合结果

参数估计结果,与设置的a=1, b=2, c=1还是比较接近的

直接上代码:

import numpy as np
import matplotlib.pyplot as plt

# 定义真实参数值
ar, br, cr = 1.0, 2.0, 1.0

# 定义估计参数值
ae, be, ce = 2.0, -1.0, 5.0

# 数据点数量
N = 100

# 噪声标准差
w_sigma = 1.0

# 生成数据
rng = np.random.default_rng()
x_data = np.linspace(0, 1, N)
y_data = np.exp(ar * x_data**2 + br * x_data + cr) + rng.normal(0, w_sigma, N)

# 高斯牛顿法迭代
iterations = 100
inv_sigma = 1.0 / w_sigma

# 开始迭代
for _ in range(iterations):
    H = np.zeros((3, 3))
    b = np.zeros(3)
    cost = 0

    for i in range(N):
        xi, yi = x_data[i], y_data[i]
        error = yi - np.exp(ae * xi**2 + be * xi + ce)
        J = np.array([
            -xi**2 * np.exp(ae * xi**2 + be * xi + ce),
            -xi * np.exp(ae * xi**2 + be * xi + ce),
            -np.exp(ae * xi**2 + be * xi + ce)
        ])

        H += inv_sigma**2 * np.outer(J, J)
        b += -inv_sigma**2 * error * J

        cost += error**2

    # 求解线性方程 Hx=b
    dx = np.linalg.solve(H, b)

    # 更新参数
    ae += dx[0]
    be += dx[1]
    ce += dx[2]

    print(f"Total cost: {cost}, Update: {dx}, Estimated params: {ae}, {be}, {ce}")

# 绘制拟合曲线和原始数据
x_range = np.linspace(0, 1, 100)
y_fit = np.exp(ae * x_range**2 + be * x_range + ce)

plt.scatter(x_data, y_data, label='Original data')
plt.plot(x_range, y_fit, label='Fitted curve', color='red')
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.title('Nonlinear Least Squares Fit with Gauss-Newton')
plt.show()

运行结果

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高斯牛顿法(Gauss-Newton method)是一种非线性最小二乘问题(nonlinear least squares, NLS)的数值解法。Python中可以使用SciPy库中的optimize模块中的leastsq函数来实现高斯牛顿法。 具体实现步骤如下: 1. 定义目标函数,即非线性最小二乘问题的残差函数。 2. 定义Jacobi矩阵,即目标函数的一阶导数矩阵。 3. 使用leastsq函数求解非线性最小二乘问题,其中需要传入目标函数、初始参数值、Jacobi矩阵等参数。 下面是一个示例代码,演示如何使用高斯牛顿法求解非线性最小二乘问题: ```python import numpy as np from scipy.optimize import leastsq # 定义目标函数 def func(p, x): return p[0] * np.exp(p[1] * x) # 定义残差函数 def residuals(p, x, y): return func(p, x) - y # 生成数据 x_data = np.linspace(0, 1, 10) y_data = func([2, 3], x_data) + np.random.randn(len(x_data)) * 0.1 # 使用高斯牛顿法求解非线性最小二乘问题 p0 = [1, 1] # 初始参数值 params, cov_x, info, msg, success = leastsq(residuals, p0, args=(x_data, y_data), full_output=True) # 输出结果 print('Parameters:', params) print('Covariance matrix:', cov_x) print('Info:', info) print('Message:', msg) print('Success:', success) ``` 上述代码中,我们定义了目标函数`func`和残差函数`residuals`,并生成了一组带有噪声的数据。然后使用`leastsq`函数求解非线性最小二乘问题,其中传入了目标函数、初始参数值、数据以及残差函数等参数。最后输出了求解结果。 需要注意的是,高斯牛顿法只能求解局部最优解,解的质量很大程度上取决于初始参数值的选择。因此,在使用高斯牛顿法求解非线性最小二乘问题时,需要根据具体问题选择合适的初始参数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值