如何向Scipy Optimize传递常量与变量?模型拟合问题咨询
解决模型数据拟合的参数传递与优化方法选择问题
我来帮你梳理下代码里的参数传递问题,以及不同优化工具的适用场景:
一、修正参数传递,让代码正常运行
你的核心问题是没区分好常量和待优化变量,导致函数参数传递混乱。我们一步步调整:
1. 重构CCER函数
让它只接收需要优化的fc和alpha,固定的einf、ezero、f_exp直接在函数内引用(也可以作为默认参数传入,更严谨),同时用numpy数组操作替代列表推导,效率更高:
import numpy as np import math from scipy.optimize import curve_fit, least_squares, minimize # 实验数据与常量定义 f_exp = np.array([1, 1.6, 2.7, 4.4, 7.3, 12, 20, 32, 56, 88, 144, 250000]) e_exp = np.array([7.15, 7.30, 7.20, 7.25, 7.26, 7.28, 7.32, 7.25, 7.35, 7.34, 7.37, 13.55]) ezero = np.min(e_exp) einf = np.max(e_exp) # 初始猜测值 ig_fc = 500 ig_alpha = 0.35 def CCER(fc, alpha): x = np.log(f_exp / fc) sinh_term = np.sinh((1 - alpha) * x) cosh_sin_term = np.cosh((1 - alpha) * x) + np.sin(0.5 * alpha * math.pi) eR = ezero + 0.5 * (einf - ezero) * (1 + sinh_term / cosh_sin_term) return eR
2. 适配不同优化工具的写法
针对minimize的目标函数
minimize需要接收待优化参数,返回残差平方和:
def func(params): fc, alpha = params eR_pred = CCER(fc, alpha) return np.sum((eR_pred - e_exp) ** 2) # 执行优化 res = minimize(func, [ig_fc, ig_alpha], method='SLSQP') print("minimize优化结果:\n", res)
更推荐的curve_fit写法
curve_fit是专门为曲线拟合设计的工具,使用更简洁,还能输出参数的协方差矩阵:
# 适配curve_fit的函数格式:第一个参数是自变量f_exp,后面是待优化参数 def CCER_curvefit(f, fc, alpha): x = np.log(f / fc) sinh_term = np.sinh((1 - alpha) * x) cosh_sin_term = np.cosh((1 - alpha) * x) + np.sin(0.5 * alpha * math.pi) eR = ezero + 0.5 * (einf - ezero) * (1 + sinh_term / cosh_sin_term) return eR # 执行拟合,p0是初始猜测值 popt, pcov = curve_fit(CCER_curvefit, f_exp, e_exp, p0=[ig_fc, ig_alpha]) print("curve_fit优化后的参数:fc={:.2f}, alpha={:.4f}".format(popt[0], popt[1]))
灵活的least_squares写法
如果需要自定义残差计算或添加参数约束,least_squares是更好的选择:
def residuals(params): fc, alpha = params eR_pred = CCER(fc, alpha) return eR_pred - e_exp # 返回残差数组,而非平方和 res_ls = least_squares(residuals, [ig_fc, ig_alpha]) print("least_squares优化结果:\n", res_ls)
二、优化算法选择建议
三种工具的适用场景各有不同:
- curve_fit:最适合你的场景,封装程度高,使用简单,专门针对“给定x-y数据拟合模型参数”的需求,还能直接给出参数的不确定性(协方差矩阵),优先选用。
- least_squares:比
curve_fit更灵活,支持参数约束、权重设置,适合处理大型残差问题或需要自定义残差逻辑的场景。 - minimize:是通用优化器,适合复杂的非最小二乘目标函数,对于你的拟合需求,它的效率和精度不如前两个专门工具,不优先推荐。
内容的提问来源于stack exchange,提问作者naughty_waves
相关产品推荐
相关产品推荐

