如何通过高阶参数固定函数约束两参数相等 适配scipy分布拟合场景
解法
简化模拟场景
你目前提供的fix函数仅支持将参数固定为静态常量,本身没有内置动态参数绑定相等的能力,你可以通过额外加一层自定义包装函数实现需求,示例代码如下:
def bind_a_equal_b(func): def wrapped(a, c): # 调用原函数时自动将b参数赋值为a的值 return func(a, a, c) return wrapped # 生成目标函数 target_func = bind_a_equal_b(f) # 测试:target_func(2, 3) 等价于 f(2, 2, 3),返回结果为7
如果必须基于现有fix函数实现,也可以调整包装逻辑配合fix使用,上述方式是最轻量化的实现方案。
实际scipy分布拟合场景
针对scipy.stats.rv_continuous.fit的参数相等约束需求,有两种常用实现方案:
方案1:自定义约束分布(推荐)
继承你需要拟合的原分布类,改写pdf/cdf计算逻辑,将两个需要相等的参数合并为一个,即可直接复用内置的fit方法逻辑,示例代码如下:
from scipy.stats import rv_continuous # 替换为你实际要拟合的原分布,比如gamma、beta等 from scipy.stats import your_original_dist class ConstrainedDist(rv_continuous): def _pdf(self, x, a, *args): # 原分布的b参数直接传入a的值,实现a=b的约束 return your_original_dist._pdf(x, a, a, *args) # 初始化自定义分布,参数a要和原分布的取值范围一致,比如原分布支持x>0则设a=0 constrained_dist = ConstrainedDist(a=0, name='constrained_a_eq_b') # 直接调用fit方法拟合样本,输出参数的第一个值就是a=b的取值 fit_params = constrained_dist.fit(your_sample_data)
方案2:自定义损失函数优化
如果需要更灵活的约束逻辑,可以自己实现负对数似然损失,调用scipy.optimize.minimize直接求解:
import numpy as np from scipy.optimize import minimize from scipy.stats import your_original_dist # 你的待拟合样本 samples = 你的样本数据 def neg_log_likelihood(params): a, loc, scale = params # 约束b=a,传入原分布的对数概率密度函数 return -np.sum(your_original_dist.logpdf(samples, a, a, loc=loc, scale=scale)) # 设置初始猜测值,可以参考原分布无约束拟合的结果 init_guess = [1, 0, 1] # 求解最优参数 res = minimize(neg_log_likelihood, x0=init_guess, method='L-BFGS-B') # 最优参数存储在res.x中,第一个值即为a=b的取值 optimal_a, optimal_loc, optimal_scale = res.x
内容的提问来源于stack exchange,提问作者plop
相关产品推荐
相关产品推荐

