如何将参数传递给其他函数(通常和通过 scipy)? [英] How do I pass through arguments to other functions (generally and via scipy)?

查看:22
本文介绍了如何将参数传递给其他函数(通常和通过 scipy)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试 最小化一个输出chi-的函数通过 scipy 平方,找到最适合高斯叠加的 mu、sigma、normc.

from math import exp从数学导入 pi从 scipy.integrate 导入四边形从 scipy.optimize 导入最小化从 scipy.stats 导入卡方将 numpy 导入为 np# 猜测最小化卡方的初始值mu, sigma = np.mean(mydata), np.std(mydata) # mydata 是我的数据点normc = 1/(sigma * (2*pi)**(1/2))gauss = lambda x: normc * exp( (-1) * (x - mu)**2/( 2 * (sigma **2) ) ) # 高斯分布# 假设我有预定义的 bin-boundaries 作为一个名为 binbound 的列表def expvalperbin(binbound,mu,sigma,normc):# 计算每个 bin 的期望值答案 = []对于范围内的索引(len(binbound)):如果索引 != len(binbound)-1:ans.append(quad( 高斯,binbound[i​​ndex],binbound[i​​ndex+1])[0])返回答案expvalguess = expvalperbin(binbound,mu,sig,normc)obsval = countperbin(binbound,mydata)arglist = [mu,sig,norm]def chisquareopt(obslist,explist):返回卡方(obslist,explist)[0]chisquareguess = chisquareopt((obsval,expvalguess), expvalguess, args=arglist)结果 = 最小化( chisquareopt(obsval,expvalguess), chisquareguess)打印(结果)

运行此代码为我提供了此错误:

TypeError: chisquareopt() 得到了一个意外的关键字参数args"

我有几个问题:

1) 如何编写一个函数来允许将参数传递给我的函数 chisquareopt?

2) 如何判断 scipy 是否会优化给出最小卡方的参数 [mu, sigma, normc]?我如何从优化中找到这些参数?

3) 很难知道我是否在这里取得了进展.我在正确的轨道上吗?

如果相关,我有一个函数输入 [mu, sigma, normc] 并输出子列表列表,每个子列表包含 [mu, sigma, normc] 的可能组合(其中外部列表​​涵盖指定范围内所有可能的参数组合).

解决方案

我已经稍微简化了您的问题,让您对问题 2 有所了解.

首先,我将您的直方图 obslist 和数据点的数量 N 硬编码为全局变量(这稍微简化了函数签名).其次,我在 expvalperbin 中硬编码了 bin 边界,假设 9 个 bin 具有固定宽度 5 并且第一个 bin 从 30 开始(所以直方图范围从 30 到 75).

第三,我使用 optimize.fmin (Nelder-Mead) 而不是 optimize.minimize.使用 fmin 而不是 minimize 的原因是通过 args=(x,y) 传递附加参数似乎不起作用从这个意义上说,附加参数从第一次调用开始就保持固定值.这不是您想要的:您想同时优化 musigma.

鉴于这些简化,我们有以下(肯定非常非pythonic)脚本:

from math import exp从数学导入 pi从 scipy.integrate 导入四边形从 scipy.optimize 导入 fmin从 scipy.stats 导入卡方obslist = [12, 51, 144, 268, 264, 166, 75, 18, 2] # 直方图,1000 个观察值N = 1000 # 没有.数据点def gauss(x, mu, sigma):返回 1/(sigma * (2*pi)**(1/2)) * exp( (-1) * (x - mu)**2/( 2 * (sigma **2) ) )def expvalperbin(mu, sigma):e = []# 硬编码的 bin 边界对于范围内的 i (30, 75, 5):e.append(quad(gauss, i, i + 5, args=(mu, sigma))[0] * N)返回 edef chisquareopt(args):# args[0] = mu# args[1] = 西格玛返回卡方(obslist,expvalperbin(args[0],args[1]))[0]# 初步猜测initial_mu = 35.5初始西格玛 = 14结果 = fmin(chisquareopt, [initial_mu, initial_sigma])打印(结果)

<块引用>

优化成功终止.

当前函数值:2.010966

迭代次数:49

功能评估:95

[50.57590239 7.01857529]

顺便说一句,obslist 直方图是来自 N(50.5, 7.0) 正态分布的 1000 点随机样本.请记住,这些是我的第一行 Python 代码行,所以请不要以风格来评判我.我只是想让你了解一下问题的一般结构.

I am trying to minimize a function that outputs chi-square via scipy and find the mu,sigma,normc that provide the best fit for a Gaussian overlay.

from math import exp
from math import pi
from scipy.integrate import quad
from scipy.optimize import minimize
from scipy.stats import chisquare
import numpy as np

# guess intitial values for minimized chi-square
mu, sigma = np.mean(mydata), np.std(mydata) # mydata is my data points
normc = 1/(sigma * (2*pi)**(1/2)) 

gauss = lambda x: normc * exp( (-1) * (x - mu)**2 / ( 2 * (sigma **2) ) ) # Gaussian Distribution

# assume I have pre-defined bin-boundaries as a list called binbound

def expvalperbin(binbound,mu,sigma,normc):
    # calculates expectation value per bin
    ans = []
    for index in range(len(binbound)):
        if index != len(binbound)-1:
            ans.append( quad( gauss, binbound[index], binbound[index+1])[0] )
    return ans

expvalguess = expvalperbin(binbound,mu,sig,normc)
obsval = countperbin(binbound,mydata)
arglist = [mu,sig,norm]

def chisquareopt(obslist,explist):
    return chisquare(obslist,explist)[0]

chisquareguess = chisquareopt((obsval,expvalguess), expvalguess, args=arglist)

result = minimize( chisquareopt(obsval,expvalguess), chisquareguess   )
print(result)

Running this code provides me with this error:

TypeError: chisquareopt() got an unexpected keyword argument 'args'

I have a few questions:

1) How can I write a function to allow arguments to be passed through to my function chisquareopt?

2) How can I tell if scipy will optimize parameters [mu, sigma, normc] that give the minimum chi-square? How could I find these parameters from the optimization?

3) It is difficult to know if I'm making progress here or not. Am I on the right track?

EDIT: If it is relevant, I have a function that inputs [mu, sigma, normc] and outputs a list of sublists, each sublist containing a possible combination of [mu, sigma, normc] (where the outer list covers all possible combinations of parameters within specified ranges).

解决方案

I've simplified your problem somewhat to give you an idea on your question 2).

First, I've hard-coded your histogram obslist and the number of data points N as global variables (that simplifies the function signatures a little). Second I've hard-coded the bin boundaries in expvalperbin, assuming 9 bins with fixed width 5 and the first bin starts at 30 (so the histogram ranges from 30 to 75).

Third, I'm using optimize.fmin (Nelder-Mead) instead of optimize.minimize. The reason for using fmin instead of minimize is that the passing of additional parameters via args=(x,y) doesn't seem to work in the sense that the additional parameters are kept at the fixed values from the very first invocation. That's not what you want: you want to optimize over mu and sigma simultaneously.

Given these simplifications we have the following (surely very unpythonic) script:

from math import exp
from math import pi
from scipy.integrate import quad
from scipy.optimize import fmin
from scipy.stats import chisquare


obslist = [12, 51, 144, 268, 264, 166, 75, 18, 2] # histogram, 1000 observations
N = 1000 # no. of data points


def gauss(x, mu, sigma):
    return 1/(sigma * (2*pi)**(1/2)) * exp( (-1) * (x - mu)**2 / ( 2 * (sigma **2) ) )

def expvalperbin(mu, sigma):
    e = []
    # hard-coded bin boundaries
    for i in range(30, 75, 5):
        e.append(quad(gauss, i, i + 5, args=(mu, sigma))[0] * N)
    return e

def chisquareopt(args):
    # args[0] = mu
    # args[1] = sigma
    return chisquare(obslist, expvalperbin(args[0], args[1]))[0]

# initial guesses
initial_mu = 35.5
initial_sigma = 14

result = fmin(chisquareopt, [initial_mu, initial_sigma])

print(result)

Optimization terminated successfully.

Current function value: 2.010966

Iterations: 49

Function evaluations: 95

[ 50.57590239 7.01857529]

Btw., the obslist histogram is a 1000 point random sample from a N(50.5, 7.0) normal distribution. Remember that these are my very first Python code lines, so please don't judge me on the style. I just wanted to give you an idea about the general structure of the problem.

这篇关于如何将参数传递给其他函数(通常和通过 scipy)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆