Numpy 泊松直方图拟合

Numpy 泊松直方图拟合,numpy,matplotlib,plot,scipy,Numpy,Matplotlib,Plot,Scipy,我试图在泊松分布的柱状图上拟合一条曲线,就像这样 我修改了拟合函数,使其类似于泊松分布,以参数t作为变量。但是曲线拟合函数无法绘制,我不知道为什么 def histo(bsize): N = bsize #binwidth bw = (dt.max()-dt.min())/(N-1.) bin1 = dt.min()+ bw*np.arange(N) #define the array to hold the occurrence count b

我试图在泊松分布的柱状图上拟合一条曲线,就像这样

我修改了拟合函数,使其类似于泊松分布,以参数t作为变量。但是曲线拟合函数无法绘制,我不知道为什么

def histo(bsize):
    N = bsize
    #binwidth
    bw = (dt.max()-dt.min())/(N-1.)
    bin1 = dt.min()+ bw*np.arange(N)
    #define the array to hold the occurrence count
    bincount= np.array([])
    for bin in bin1:
        count = np.where((dt>=bin)&(dt<bin+bw))[0].size
        bincount = np.append(bincount,count)
    #bin center
    binc = bin1+0.5*bw
    plt.figure()
    plt.plot(binc,bincount,drawstyle= 'steps-mid')
    plt.xlabel("Interval[ticks]")
    plt.ylabel("Frequency")
histo(30)
plt.xlim(0,.5e8)
plt.ylim(0,25000)
import numpy as np
from scipy.optimize import curve_fit
delta_t = 1.42e7
def func(x, t):
    return t * np.exp(- delta_t/t) 
popt, pcov = curve_fit(func, np.arange(0,.5e8),histo(30))
plt.plot(popt)
def histo(bsize):
N=b尺寸
#箱宽
bw=(dt.max()-dt.min())/(N-1.)
bin1=dt.min()+bw*np.arange(N)
#定义用于保存发生计数的数组
bincount=np.array([])
对于bin1中的bin:

count=np。其中((dt>=bin)和(dt代码的问题在于,您不知道
曲线拟合的返回值是什么。这是拟合函数的参数及其协方差矩阵-您无法直接绘制

分块最小二乘拟合 一般来说,您可以更轻松地获取所有信息:

将numpy导入为np
将matplotlib.pyplot作为plt导入
从scipy.optimize导入曲线\u拟合
来自scipy.special import factorial
从scipy.stats导入泊松
#得到泊松偏差随机数
数据=np.随机泊松(2100)
#箱子的宽度应为整数,因为泊松分布为整数分布
料仓=np.arange(11)-0.5
条目,bin_边,patches=plt.hist(数据,bin=bin,density=True,label='data')
#计算垃圾箱中心
bin_middles=0.5*(bin_边[1::+bin_边[:-1])
def fit_功能(k,lamb):
''泊松函数,参数lamb是拟合参数''
返回poisson.pmf(k,lamb)
#曲线拟合
参数,cov_矩阵=曲线拟合(拟合函数、bin_中间、条目)
#用拟合参数绘制泊松偏差图
x_图=np.arange(0,15)
plt.plot(
x_图,
拟合函数(x_图,*参数),
标记='o',线条样式='',
label='Fit result',
)
plt.legend()
plt.show()
结果是:

无约束最大似然拟合 更好的可能性是根本不使用直方图 而是进行最大似然拟合

但通过仔细检查,这甚至是不必要的,因为 泊松分布参数的最大似然估计是算术平均值

但是,如果您有其他更复杂的PDF,可以使用以下示例:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.special import factorial
from scipy import stats


def poisson(k, lamb):
    """poisson pdf, parameter lamb is the fit parameter"""
    return (lamb**k/factorial(k)) * np.exp(-lamb)


def negative_log_likelihood(params, data):
    """
    The negative log-Likelihood-Function
    """

    lnl = - np.sum(np.log(poisson(data, params[0])))
    return lnl

def negative_log_likelihood(params, data):
    ''' better alternative using scipy '''
    return -stats.poisson.logpmf(data, params[0]).sum()


# get poisson deviated random numbers
data = np.random.poisson(2, 1000)

# minimize the negative log-Likelihood

result = minimize(negative_log_likelihood,  # function to minimize
                  x0=np.ones(1),            # start value
                  args=(data,),             # additional arguments for function
                  method='Powell',          # minimization method, see docs
                  )
# result is a scipy optimize result object, the fit parameters 
# are stored in result.x
print(result)

# plot poisson-distribution with fitted parameter
x_plot = np.arange(0, 15)

plt.plot(
    x_plot,
    stats.poisson.pmf(x_plot, *parameters),
    marker='o', linestyle='',
    label='Fit result',
)
plt.legend()
plt.show()

谢谢你的精彩讨论

您可能需要考虑以下内容:

1) 计算“对数泊松”以获得更好的数值行为,而不是计算“泊松”

2) 不要使用“lamb”,而是使用对数(我称之为“log_mu”),以避免拟合“漂移”到负值“mu”。 所以

其中“loggamma”是
scipy.special.loggamma
函数

实际上,在上述拟合中,“loggamma”项只会为最小化的函数添加一个常量偏移量,因此可以只执行以下操作:

log_poisson_(k, log_mu): return k*log_mu - math.exp(log_mu)

注:
log\u poisson()
log\u poisson()
不同,但以上述方式用于最小化时,将给出相同的拟合最小值(相同的mu值,直至数值问题)。被最小化的函数的值将被抵消,但人们通常并不关心这一点。

您能提供追溯吗?我强烈怀疑您不了解什么是
curve\u fit
。请看两件事:1)您不需要编写自己的直方图函数,只需使用;2)如果您有实际数据,请不要将曲线拟合到直方图,使用3)您实现的
func
不是泊松函数这非常适合将曲线拟合到数据点,这是对所问问题的正确答案,在编程的意义上。然而,如果你要拟合泊松数据,科学/统计上你最好拟合样本本身,而不是直方图!当然,我会将此添加到我的答案中。我添加了一个未绑定的似然系数。如何确保我的箱子宽度是整数值?可以使用类似
bins=np的东西为箱子关键字提供一个箱子边数组。arange(0,N,1)-0.5
将为您提供具有整宽度和整中心的'N-2'箱子
log_poisson_(k, log_mu): return k*log_mu - math.exp(log_mu)