请问如果用了optimize.curve_fit的‘lm’方法,但‘lm’和对参数设边界(>0)矛盾,只能用‘trf’,导致拟合结果很奇怪,有啥能够兼顾lm和边界的方法吗,或许不能用scipy?
“Devil组”引证GPT后的撰写:
要在优化过程中同时使用 Levenberg-Marquardt(LM)方法和参数边界,则可以考虑使用其他的优化库,例如 lmfit 或 cma-es。
lmfit 库是一个专门用于拟合的 Python 库,它提供了许多与参数拟合相关的函数和类。其中包括一个 Minimizer 类,它使用 LM 算法,并且允许您在拟合过程中设置参数边界。
下面是一个使用 lmfit 库拟合一个正弦函数的例子:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
# Define the model
def sine(x, amplitude, frequency, phase, offset):
return amplitude * np.sin(2 * np.pi * frequency * x + phase) + offset
# Generate some noisy data
x = np.linspace(0, 2 * np.pi, 50)
y = sine(x, 1, 1, 0, 0) + np.random.normal(0, 0.1, 50)
# Define the LM model
model = Model(sine)
# Set the parameter bounds
model.set_param_hint('amplitude', min=0)
model.set_param_hint('frequency', min=0)
model.set_param_hint('offset', min=0)
# Fit the model to the data
result = model.fit(y, x=x, amplitude=0.5, frequency=2, phase=0, offset=0)
# Plot the results
plt.scatter(x, y)
plt.plot(x, result.best_fit)
plt.show()
# Print the fitted parameters
print(result.params)
cma-es 库是另一个常用的全局优化库,它可以在不知道参数范围的情况下进行优化。该库使用进化策略算法来寻找全局最优解。下面是一个使用 cma-es 库拟合同样正弦函数的例子:
import numpy as np
import matplotlib.pyplot as plt
import cma
# Define the objective function
def objective_function(params):
amplitude, frequency, phase, offset = params
y_pred = amplitude * np.sin(2 * np.pi * frequency * x + phase) + offset
error = np.sum((y - y_pred) ** 2)
return error
# Generate some noisy data
x = np.linspace(0, 2 * np.pi, 50)
y = np.sin(x) + np.random.normal(0, 0.1, 50)
# Set the initial guess
initial_guess = [0.5, 2, 0, 0]
# Set the bounds
bounds = [[0, np.inf], [0, np.inf], [0, 2 * np.pi], [0, np.inf]]
# Run the optimizer
result = cma.fmin(objective_function, initial_guess, bounds=bounds)
# Plot the results
plt.scatter(x, y)
plt.plot(x, result[0] * np.sin(2 * np.pi * result[1] * x + result[2]) + result[3])
plt.show()
# Print the fitted parameters
print(result)