0

我在一月份问了一个类似的问题,@Miłosz Wieczór 很友好地回答了这个问题。现在,我面临着类似但不同的挑战,因为我需要在两个数据集(和)上同时拟合两个参数(和fc)。我基本上需要找到最适合数据和的和的值。alphae_expiq_expfcalphae_expiq_exp

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, 11.55])
iq_exp = np.array([0.010, 0.009, 0.011, 0.011, 0.010, 0.012, 0.019, 0.027, 0.038, 0.044, 0.052, 0.005])

ezero  = np.min(e_exp)
einf   = np.max(e_exp)

ig_fc     = 500
ig_alpha  = 0.35

def CCRI(f_exp, fc, alpha):
    x   = np.log(f_exp/fc)
    R  = ezero + 1/2 * (einf - ezero) * (1 + np.sinh((1 - alpha) * x) / (np.cosh((1 - alpha) * x) + np.sin(1/2 * alpha * math.pi)))
    I  = 1/2 * (einf - ezero) * np.cos(alpha * math.pi / 2) / (np.cosh((1 - alpha) * x) + np.sin(alpha * math.pi / 2))
    RI = np.sqrt(R ** 2 + I ** 2)
    return RI

def CCiQ(f_exp, fc, alpha):
    x   = np.log(f_exp/fc)
    R  = ezero + 1/2 * (einf - ezero) * (1 + np.sinh((1 - alpha) * x) / (np.cosh((1 - alpha) * x) + np.sin(1/2 * alpha * math.pi)))
    I  = 1/2 * (einf - ezero) * np.cos(alpha * math.pi / 2) / (np.cosh((1 - alpha) * x) + np.sin(alpha * math.pi / 2))
    iQ = I / R
    return iQ

poptRI, pcovRI = curve_fit(CCRI, f_exp, e_exp, p0=(ig_fc, ig_alpha))

poptiQ, pcoviQ = curve_fit(CCiQ, f_exp, iq_exp, p0=(ig_fc, ig_alpha))

einf,ezerof_exp都是常数加上我需要优化的变量是ig_fcand ig_alpha,其中ig代表初始猜测。在上面的代码中,我得到了两个不同的fcalpha值,因为我独立解决了它们。fc但是,我需要同时解决它们,以便alpha通用。

  • 有没有办法解决两个不同的函数来为fc和提供通用解决方案alpha
4

1 回答 1

1

文档说明了curve_fit的第二个返回值:

pcov

popt 的估计协方差。对角线提供参数估计的方差。要计算参数的一个标准偏差误差,请使用perr = np.sqrt(np.diag(pcov)).

因此,如果您想最小化整体误差,则需要将两者的误差结合起来。

def objective(what, ever):

    poptRI, pcovRI = curve_fit(CCRI, f_exp, e_exp, p0=(ig_fc, ig_alpha))

    poptiQ, pcoviQ = curve_fit(CCiQ, f_exp, iq_exp, p0=(ig_fc, ig_alpha))

    # not sure if this the correct equation, but you can start with it
    err_total = np.sum(np.sqrt(np.diag(pcovRI))) + np.sum(np.sqrt(np.diag(pcoviQ)))

    return err_total

关于二维高斯函数的总误差:

https://www.visiondummy.com/2014/04/draw-error-ellipse-representing-covariance-matrix/

更新:既然你想poptRIpoptiQ一样,你需要尽量减少他们的距离。

这可以像

from numpy import linalg

def objective(what, ever):

    poptRI, pcovRI = curve_fit(CCRI, f_exp, e_exp, p0=(ig_fc, ig_alpha))

    poptiQ, pcoviQ = curve_fit(CCiQ, f_exp, iq_exp, p0=(ig_fc, ig_alpha))

    delta = linalg.norm(poptiQ - poptRI)
    return delta

最小化此函数将(应该)导致 和 的值poptRI相似poptiQ。您将参数作为向量,并尝试最小化它们的 delta 向量的长度。

但是,这种方法假设poptRIpoptiQ(及其系数)大约在同一范围内,因为您在它们上使用了一些度量。如果说一个在 2000 范围内,另一个在 2 范围内。那么优化器将倾向于调整第一个。但也许这很好。

如果您想以某种方式对待它们,则需要将它们标准化。一种方法(假设所有系数都相似)可能是

linalg.norm((poptiQ / linalg.norm(poptiQ)) - (poptRI / linalg.norm(poptRI))))

您将结果标准化为单位向量,然后减去它们,然后创建范数。

函数的输入也是如此,但在那里可能并不那么重要。请参阅下面的链接。

但这在很大程度上取决于您要解决的问题。没有通用的解决方案。

与此相关的一些链接:

规范化在优化中有用/必要吗?

为什么我们必须对人工神经网络的输入进行归一化?

另一个目标函数:

这是你想要做的吗?你想找到最好的fcalpha所以两个函数的拟合结果尽可能接近?

def objective(fc, alpha):

    poptRI, pcovRI = curve_fit(CCRI, f_exp, e_exp, p0=(fc, alpha))

    poptiQ, pcoviQ = curve_fit(CCiQ, f_exp, iq_exp, p0=(fc, alpha))

    delta = linalg.norm(poptiQ - poptRI)
    return delta
于 2020-04-15T17:22:17.020 回答