使用scipy从pdf样本坐标创建最佳拟合概率分布

时间:2017-09-04 12:05:35

标签: python scipy

问题:我有数据点表示从概率分布中采样的坐标(在这种情况下,我们将假设一个离散的概率分布函数)我们基本上形成了一个pdf&的最佳拟合#39;来自这里的pdf数据。

鉴于: pdf的样本坐标以及适合它的pdf类型(例如lognorm)

返回:理想情况下,pdf参数,或者最佳拟合分布的坐标。

我没有在stackoverflow上找到这个问题/答案的问题,我知道这可能是不好的做法。似乎scipy明确地喜欢原始数据来构建pdf参数,而不是pdf中的样本坐标。

我有矢量:

x = list(range(40))

y = 
[0.032935611986072325,
 0.15399668951796566,
 0.19217568076280733,
 0.16189644686218774,
 0.11504756998080325,
 0.09474568682103104,
 0.08971162676825704,
 0.06198299715985481,
 0.04408241680044377,
 0.026817519111333753,
 0.013562814925870696,
 0.007007365243147507,
 0.003909173588759217,
 0.0015053452905258473,
 0.00037481359597322736,
 0.0001378624720821066,
 5.734365756863486e-05,
 2.9711739672867803e-05,
 8.022169711674307e-06,
 5.942347934573561e-06,
 2.228380475465085e-06,
 3.7139674591084754e-06,
 8.913521901860341e-07,
 8.913521901860341e-07,
 5.94234793457356e-07,
 2.97117396728678e-07,
 2.97117396728678e-07,
 2.97117396728678e-07,
 1.48558698364339e-07,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 0.0]

2 个答案:

答案 0 :(得分:1)

致电您的PDF f(x)

如果您的数据真的代表{x, f(x)},那么您可以尝试使用例如f优化{x}的参数。 https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html#scipy.optimize.leastsq

如果您的数据是来自概率分布的样本,即您的数据看起来像x,但每个f(x)的概率f被选中,那么您应该尝试马尔可夫链蒙特卡洛估计string regexPattern = @"([0-9]+)"; Regex regex = new Regex(regexPattern); 。 Python有几种选择:

https://pystan.readthedocs.io/en/latest/

http://docs.pymc.io/notebooks/getting_started.html#Model-fitting

答案 1 :(得分:0)

我认为您的数据自sum(y) = 1起代表pdf {x,y = pdf(x)}。 当我们对数据进行轻微校正x = list(range(39))时,我们得到的曲线类似于对数正态(?)。

import matplotlib.pyplot as plt

x = list(range(39))
plt.plot(x, y)

enter image description here

避免使用优化算法的一个技巧是将数据转换为样本,因为每个y[i]x[i]的频率成正比。换句话说,如果您想要一个大小为N的“完美”样本S,则每个x[i]将出现N * y[i]次。

N = 20.000
n_times = [int(y[i] * N) for i in range(len(y))]
S = np.repeat(x, n_times)

剩下要做的就是使LogNormal发行版适合S。就我个人而言,我习惯于OpenTURNS库。您只需将S格式化为ot.Sample即可,方法是将其重塑为维度1的N个点

import openturns as ot

sample = ot.Sample([[p] for p in S])
fitdist = ot.LogNormalFactory().build(sample)

fitdist是一个“ ot.Distribution”,您可以打印以查看其参数

print(fitdist)
>>> LogNormal(muLog = 1.62208, sigmaLog = 0.45679, gamma = -1.79583)

或使用fitdist.computePDF内置方法(以ot.Sample格式作为参数绘制两条曲线

plt.plot(x, y)
plt.plot(x, fitdist.computePDF(ot.Sample([[p] for p in x])))

enter image description here