使用 curve_fit 拟合从列表中的函数总和定义的符号函数

问题描述 投票:0回答:0

我是 python 的新手,想尝试将直方图拟合为“指数类”和“正态类”分布的总和。原则上,我想在已知的发行版上尝试这个,所有发行版都是用 scipi.stats 内置的。该过程将迭代

pdfs_start
中的每对函数和
pdfs_bulk
中的函数。

由于 scipi stat 中的 pdf 似乎不具有带有参数列表的属性(除了 *args),我检查了文档以构建函数,其功能如下

import inspect
from scipy.stats import norm, lognorm, expon, gamma, beta, pareto
from scipy.stats import kstest, chisquare
from scipy.optimize import curve_fit

def expon_func(x, exp1, exp2):
    return expon.pdf(x, exp1, exp2)
expon_func.name = expon.name

def beta_func(x, beta1, beta2, beta3, beta4):
    return beta.pdf(x, beta1, beta2, beta3, beta4)
beta_func.name = beta.name

def pareto_func(x, pareto1, pareto2, pareto3):
    return pareto.pdf(x, beta1, beta2, beta3)
pareto_func.name = pareto.name

def norm_func(x, norm1, norm2):
    return norm.pdf(x, norm1, norm2)
norm_func.name = norm.name

def lognorm_func(x, lognorm1, lognorm2, lognorm3):
    return lognorm.pdf(x, lognorm1, lognorm2, lognorm3)
lognorm_func.name = lognorm.name

def gamma_func(x, gamma1, gamma2, gamma3):
    return gamma.pdf(x, gamma1, gamma2, gamma3)
gamma_func.name = gamma.name

pdfs_start = [expon_func, beta_func, pareto_func]
pdfs_bulk = [norm_func, lognorm_func, gamma_func, beta_func]

我尝试了以下函数来执行传递一个新函数,该函数返回其两个参数函数的总和:

def create_func(f1, f2):
    f1_params = list(inspect.signature(f1).parameters.keys())[1:]
    f2_params = list(inspect.signature(f2).parameters.keys())[1:]
    params = list(set(f1_params) | set(f2_params))
    def func(x, *params):
        return f1(x, *f1_params) + f2(x, *f2_params)
    return {'Function': func, 'Name': f"{f1.name} + {f2.name}", 'p0': [1 for i in range(len(params))] }

请注意,两个列表的每个函数共享的唯一参数是自变量

x
。除了这个,每个函数都有不同数量的参数,我不想为每个组合手动指定。

字典中的“p0”条目将作为初始猜测提供给 curve_fit,否则它将无法确定拟合参数的数量。

调用 curve_fit 的一个例子是,然后(在实际情况下,它会在 for 循环中,但这里就足够了)

popt,_ = curve_fit(create_func(pdfs_start[2],pdfs_bulk[3])['Function'], bins[:-1] + (bins[1] - bins[0])/2, hist, p0 = create_func(pdfs_start[2],pdfs_bulk[3])['p0'])

这确实运行了,但是得到的曲线非常糟糕(很抱歉,我无法提供直方图)。我想这是一个数值问题,curve_fit 根本无法收敛这么多参数和给定的初始猜测,但我不确定。

我的打算能实现吗?除此之外,您有任何改进我的代码的技巧吗?我很感激任何见解!

scipy curve-fitting scipy-optimize scipy.stats
© www.soinside.com 2019 - 2024. All rights reserved.