Numpy 如何为scipy.optimize.curve_fit添加约束

Numpy 如何为scipy.optimize.curve_fit添加约束

在数据分析和科学计算中,使用非线性回归分析来拟合数据是很常见的。在Python中,scipy.optimize.curve_fit是一个重要的库,用于优化拟合非线性函数的参数。然而,有时候我们需要添加一些约束条件,例如限制拟合参数的范围,或者是在模型中添加一些物理约束条件。在本文中,我们将学习如何使用Numpy为scipy.optimize.curve_fit添加约束。

阅读更多:Numpy 教程

添加参数范围约束

首先,让我们看一个例子。假设我们有以下这组数据:

import numpy as np
import matplotlib.pyplot as plt

x_data = np.linspace(-5, 5, num=50)
y_data = 3 * np.exp(-0.5 * (x_data - 1.5) ** 2) + 0.5 + np.random.normal(size=50)

这组数据可以很好地拟合高斯函数,我们可以使用curve_fit函数来拟合。假设我们希望限制拟合的参数a在[0, infinity),b在[-0.5, 0.5]之间。我们可以通过自定义函数和使用bound来添加这些范围限制。

def gaus(x, a, b, c):
    return a * np.exp(-0.5 * (x - b) ** 2) + c

from scipy.optimize import curve_fit

popt, pcov = curve_fit(gaus, x_data, y_data, bounds=((0, -0.5, -np.inf), (np.inf, 0.5, np.inf)))
print(popt)

plt.plot(x_data, y_data, 'bo', label='data')
plt.plot(x_data, gaus(x_data, *popt), 'r-', label='fit')
plt.legend()
plt.show()

这里我们传递了bounds参数,并指定了a在[0, infinity)之间,b在[-0.5, 0.5]之间,c任意。

添加物理约束条件

在某些情况下,我们可能需要在模型中添加一些物理约束条件。例如,假设我们有以下数据:

x_data = np.linspace(0, 1, num=50)
y_data = np.log(1 + 10 * x_data) + np.random.normal(size=50) / 10

这组数据很适合使用最小二乘法拟合,但是我们知道y必须大于等于x。我们可以通过定义一个带有物理约束条件的函数来拟合这些数据。请注意,这个函数中的第一个参数是待拟合参数,需要设置为变量x,而我们的参数是存储在第二个元组中的,我们需要将它展开到函数的参数列表中以进行拟合。

def log_model(x, *params):
    a, b = params
    if b < x:
        return np.nan + x
    return a * np.log(b * x + 1)

popt, pcov = curve_fit(log_model, x_data, y_data, p0=(1, 1))
print(popt)

plt.plot(x_data, y_data, 'bo', label='data')
plt.plot(x_data, log_model(x_data, *popt), 'r-', label='fit')
plt.legend()
plt.show()

这里我们根据要求限制了参数b必须大于等于x,如果b小于x,函数返回np.nan,这样就不会对拟合产生影响。

现在我们已经学会了如何使用Numpy为scipy.optimize.curve_fit添加约束。这将使我们更容易控制和管理我们的模型,使得我们的拟合工作更加精确和可靠。

总结

  • 可以使用bound参数来为拟合参数添加范围限制。
  • 可以定义带有物理约束条件的函数来拟合数据。
  • 这些约束条件可以帮助提高模型的可靠性和精确性。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程