【问题标题】:Unpacking parameters for a simulation解包模拟参数
【发布时间】:2013-04-24 03:33:26
【问题描述】:

我做了很多 ODE 模拟,并使用了一些 Python 参数优化工具(例如 scipy.optimize.minimize、emcee),这些工具需要将参数作为列表传入。这使得它们非常麻烦,因为我必须将参数称为params[0]params[1] 等,而不是更直观的名称来实际描述它们在模拟中的作用。到目前为止,我对此的解决方案是这样的:

k1 = 1.0 
k2 = 0.5
N = 0.01

params = [k1,k2,N]

def sim(params,timerange):
    k1 = params[0]
    k2 = params[1]
    N = params[2]

    # run the simulation

这真的很笨拙,并且由于多种原因而令人不满意。每当我需要向模拟添加新参数时,我都必须修改参数列表并更改我在模拟函数中手动解包列表的方式;浪费一些时间在每一轮模拟等中建立新的参考。

我想知道是否有一个理智的、非笨拙的解决方案来定义带有名称的参数,将它们作为列表传递给函数,然后通过列表中的相同名称引用它们。

【问题讨论】:

  • 您能否进一步解释一下您在sim 函数中所做的工作?具体来说,我希望看到您在哪里调用 scipy 或 emcee 函数,以便我们更好地了解需要传递的内容。我的直觉告诉我,使用 *args**kwargs 会带你去你想去的地方,但如果没有更多信息,我无法确定。
  • 公平。这些函数实际上并不是从 sim 内部调用的。 sim 所做的只是返回 ODE 系统的瞬时值,scipy odeint 函数使用这些值来确定我感兴趣的系统的演变。这反过来又从计算误差的函数中调用在模拟和一些数据之间,由emcee或optimize.minimize调用。最后两个的工作是最小化误差函数;我需要进行列表解包的原因是因为它们需要将要调整的参数传递到列表中。
  • *args 不起作用,因为每个参数都作为单独的参数传递,我需要将它们全部作为单个列表的元素传递。

标签: python parameters scipy emcee


【解决方案1】:
def sim(params,timerange):
    k1,k2,N = params

我认为是你想要的 ..,.. 如果你添加了一个额外的参数,你只需在 N 之后添加它......但它不是可选参数

或许更好

def sim(*params,**kwargs):
    timerange = kwargs.get('timerange',default_timerange)
    K1,K2,N = params #assuming you know you have exactly 3

#then call it like so
sim(k1,k2,N,timerange=(-100,100))

【讨论】:

  • 我认为您的第一个应该会有所帮助,谢谢!第二个不会,因为我遇到的问题是我使用的优化器需要sim 函数,以将参数值列表作为输入调用(而不是每个参数作为单独的输入)。
  • @JoranBeasley:我想你的意思是k1,k2,N = params。使用 * 会导致语法错误。
  • 是的......对不起,当我添加这个时我正在自动驾驶:P
【解决方案2】:

我通常按照 Joran 在他的回答中建议的去做:

def sim(params, timerange):
    k1, k2, N = params
    ...

但你也可以这样做:

def sim((k1, k2, N), timerange):
    ...

(至少,这在 Python 2.7 中有效。我还没有在其他 Python 版本中尝试过。)我用scipy.integrate.odeintscipy.integrate.odescipy.optimize.minimize 测试了这个想法,它运行良好。例如,在以下代码中,您可以使用costcost2 作为minimize 的第一个参数:

from scipy.optimize import minimize

def cost(z, a, b):
    x, y = z
    c = (x - a)**2 + (y - b)**2
    return c

def cost2((x, y), a, b):
    c = (x - a)**2 + (y - b)**2
    return c

if __name__ == "__main__":
    a = 5.0
    b = 1.5
    x0 = 4.2
    y0 = 1.5
    sol = minimize(cost2, (x0, y0), args=(a,b))
    print sol['x']

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 2017-02-01
    • 2022-01-08
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 2015-10-21
    相关资源
    最近更新 更多