如何在Python中用含8个独立参数的curve_fit拟合正态分布?
问题修正与简洁实现方案
代码核心错误
- 函数参数定义错误:
curve_fit要求模型函数第一个参数是自变量,后续为待拟合参数。你的待拟合参数是a,b,c,d,e,f,g,h,mu、sigma、oc1、oc2、oc3不应作为函数参数——oc1/oc2/oc3是自变量组成部分,mu/sigma是由自变量和待拟合参数计算的中间变量。 - 幂运算符号错误:Python中
^是按位异或,幂运算需用**。 - 依赖模块缺失:代码使用
math模块函数但未导入。 - 数据格式错误:
curve_fit的ydata需为一维数组;若实验数据是每组(oc1,oc2,oc3)对应的均值和标准差,需调整拟合逻辑合并数据维度。
修正后的代码实现
场景:拟合每组(oc1,oc2,oc3)对应的均值与标准差
假设你有N组(oc1,oc2,oc3),对应N个均值和N个标准差,目标是拟合a-h让计算出的μ和σ与实验值匹配:
from scipy.optimize import curve_fit import numpy as np def combined_model(x, a, b, c, d, e, f, g, h): # 拆分自变量 oc1, oc2, oc3 = x[:, 0], x[:, 1], x[:, 2] # 计算mu和sigma mu = a * (b ** oc1) * (c ** oc2) * (d ** oc3) sigma = e * (f ** oc1) * (g ** oc2) * (h ** oc3) # 合并结果为一维数组,匹配ydata格式 return np.concatenate([mu, sigma]) # 准备数据:替换为你的实际数组 oc1_array = np.array([...]) oc2_array = np.array([...]) oc3_array = np.array([...]) mean_array = np.array([...]) std_array = np.array([...]) xdata = np.column_stack((oc1_array, oc2_array, oc3_array)) ydata = np.concatenate([mean_array, std_array]) # 初始参数猜测(必须合理,否则拟合易不收敛) initial_guess = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # 执行拟合,可添加参数约束(如sigma必须为正) popt, pcov = curve_fit(combined_model, xdata, ydata, p0=initial_guess, bounds=([0]*8, [np.inf]*8)) # popt即为拟合得到的[a,b,c,d,e,f,g,h] a_fit, b_fit, c_fit, d_fit, e_fit, f_fit, g_fit, h_fit = popt
更简洁的实现方式
利用numpy向量化特性+scipy内置正态分布工具简化代码:
from scipy.optimize import curve_fit import numpy as np from scipy.stats import norm def simplified_model(x, a, b, c, d, e, f, g, h): # 转置后直接拆分自变量,更简洁 oc1, oc2, oc3 = x.T mu = a * (b ** oc1) * (c ** oc2) * (d ** oc3) sigma = e * (f ** oc1) * (g ** oc2) * (h ** oc3) # 若拟合观测值的概率密度,可直接返回norm.pdf(x_obs, mu, sigma) return np.concatenate([mu, sigma]) # 数据准备同前 xdata = np.column_stack((oc1_array, oc2_array, oc3_array)) ydata = np.concatenate([mean_array, std_array]) initial_guess = [1.0]*8 popt, pcov = curve_fit(simplified_model, xdata, ydata, p0=initial_guess, bounds=([0]*8, [np.inf]*8))
关键注意事项
- 初始参数:
curve_fit对初始值敏感,需根据实验数据给出合理初值(如mu随oc1增大时,b的初值设为大于1的数)。 - 参数约束:通过
bounds设置参数范围(如所有参数非负),避免出现无意义的拟合结果。 - 维度匹配:确保
xdata为(n_samples, 3)的二维数组,ydata与模型返回值维度一致(联合拟合时为(2*n_samples,))。
内容的提问来源于stack exchange,提问作者newtopy
相关产品推荐
相关产品推荐

