为什么我不能在惩罚函数中将元组解压缩为scipy quad?

时间:2018-08-12 18:42:05

标签: python syntax scipy

因此,这是一个带有一些混合分布的基本示例,其中2个高斯的参数数量已经是6。对于更多分布,我想对积分不是1的拟合进行惩罚。

scipy的

quad拒绝将所有参数都放在一个包中,相反,我不得不求助于p[0],p[1]...,这很快变得很麻烦。

为什么我似乎无法将元组直接解包到此处的函数中?

import numpy as np
from scipy import stats as st
from scipy.integrate import quad
from scipy.optimize import leastsq
import matplotlib.pylab as plt

def hist_to_xy(data, bins, normalized):
    counts, bin_edges = np.histogram(data, bins = bins, density = normalized)
    bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2

    x, y, = bin_centers, counts
    return x, y

# Random data
a = np.random.normal(0.3, 0.1, 1000)
b = np.random.normal(0.8, 0.1, 1000)
d = np.concatenate((a,b))
bins = np.arange(-0.5,1.5,0.01)
xvals = np.linspace(-0.2,1.2,100)
x, y, *_ = hist_to_xy(d, normalized = True, bins = bins)

def gauss(x, n1, m1, s1, n2, m2, s2):
    return n1*st.norm.pdf(x, m1,s1) + n2*st.norm.pdf(x, m2,s2)

### Works as you'd expect with p ####
p = (0.5, 0.5, 0.1, 0.5, 0.5, 0.1)
integral, *_ = quad(gauss, 0, 1, args = p)

def residuals(p,x,y):
    ### Only works if you index everything manually in p as p[0], p[1], p[2]... ###
    integral, *_ = quad(gauss, 0, 1, args = (p[0],p[1],p[2],p[3],p[4],p[5])) # eurghhh
    penalization = abs(1-integral)*10000
    return y - gauss(x, *p) - penalization

popt, pcov = leastsq(func=residuals, x0 = (0.5, 0.5, 0.1, 0.5, 0.5, 0.1), args=(x, y))
plt.plot(x,y, "o")
plt.plot(xvals, gauss(xvals, *popt), color = "firebrick")
plt.show()

1 个答案:

答案 0 :(得分:2)

找到了解决方法。只需在残差函数内添加<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.js"></script> <div class="content"> <div ><span data-link="notifications"></span> notifications</div> <div >this is <span data-link="something_else"></span> to show</div> <img data-link="src{:imgData.img1.src} title{:imgData.img1.desc}"/> <br/>Edit: <input data-link="something_else"/> </div>,quad就不会抱怨。